KiCad PCB EDA Suite
C3D_RENDER_RAYTRACING Class Reference

#include <c3d_render_raytracing.h>

Inheritance diagram for C3D_RENDER_RAYTRACING:
C3D_RENDER_BASE

Public Member Functions

 C3D_RENDER_RAYTRACING (BOARD_ADAPTER &aAdapter, CCAMERA &aCamera)
 
 ~C3D_RENDER_RAYTRACING ()
 
void SetCurWindowSize (const wxSize &aSize) override
 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. More...
 
bool Redraw (bool aIsMoving, REPORTER *aStatusReporter, REPORTER *aWarningReporter) override
 Redraw - Ask to redraw the view. More...
 
int GetWaitForEditingTimeOut () override
 GetWaitForEditingTimeOut - Give the interface the time (in ms) that it should wait for editing or movements before (this works for display preview mode) More...
 
void ReloadRequest ()
 ReloadRequest - !TODO: this must be reviewed to add flags to improve specific render. More...
 
bool IsReloadRequestPending () const
 IsReloadRequestPending - Query if there is a pending reload request. More...
 
void SetBusyIndicatorFactory (BUSY_INDICATOR::FACTORY aNewFactory)
 Set a new busy indicator factory. More...
 

Protected Member Functions

std::unique_ptr< BUSY_INDICATORCreateBusyIndicator () const
 Return a created busy indicator, if a factory has been set, else a null pointer. More...
 

Protected Attributes

BOARD_ADAPTERm_boardAdapter
 settings refrence in use for this render More...
 
CCAMERAm_camera
 
bool m_is_opengl_initialized
 flag if the opengl specific for this render was already initialized More...
 
bool m_reloadRequested
 !TODO: this must be reviewed in order to flag change types More...
 
wxSize m_windowSize
 The window size that this camera is working. More...
 

Static Protected Attributes

static const wxChar * m_logTrace = wxT( "KI_TRACE_3D_RENDER" )
 Trace mask used to enable or disable the trace output of this class. More...
 

Private Member Functions

bool initializeOpenGL ()
 
void initializeNewWindowSize ()
 
void opengl_init_pbo ()
 
void opengl_delete_pbo ()
 
void reload (REPORTER *aStatusReporter, REPORTER *aWarningReporter)
 
void restart_render_state ()
 
void rt_render_tracing (GLubyte *ptrPBO, REPORTER *aStatusReporter)
 
void rt_render_post_process_shade (GLubyte *ptrPBO, REPORTER *aStatusReporter)
 
void rt_render_post_process_blur_finish (GLubyte *ptrPBO, REPORTER *aStatusReporter)
 
void rt_render_trace_block (GLubyte *ptrPBO, signed int iBlock)
 
void rt_final_color (GLubyte *ptrPBO, const SFVEC3F &rgbColor, bool applyColorSpaceConversion)
 
void rt_shades_packet (const SFVEC3F *bgColorY, const RAY *aRayPkt, HITINFO_PACKET *aHitPacket, bool is_testShadow, SFVEC3F *aOutHitColor)
 
void rt_trace_AA_packet (const SFVEC3F *aBgColorY, const HITINFO_PACKET *aHitPck_X0Y0, const HITINFO_PACKET *aHitPck_AA_X1Y1, const RAY *aRayPck, SFVEC3F *aOutHitColor)
 
void setupMaterials ()
 
SFVEC3F shadeHit (const SFVEC3F &aBgColor, const RAY &aRay, HITINFO &aHitInfo, bool aIsInsideObject, unsigned int aRecursiveLevel, bool is_testShadow) const
 
void create_3d_object_from (CCONTAINER &aDstContainer, const COBJECT2D *aObject2D, float aZMin, float aZMax, const CMATERIAL *aMaterial, const SFVEC3F &aObjColor)
 Function create_3d_object_from. More...
 
void add_3D_vias_and_pads_to_container ()
 
void insert3DViaHole (const VIA *aVia)
 
void insert3DPadHole (const D_PAD *aPad)
 
void load_3D_models ()
 
void add_3D_models (const S3DMODEL *a3DModel, const glm::mat4 &aModelMatrix, float aModuleOpacity)
 
void initialize_block_positions ()
 
void render (GLubyte *ptrPBO, REPORTER *aStatusReporter)
 
void render_preview (GLubyte *ptrPBO)
 

Private Attributes

struct {
   CBLINN_PHONG_MATERIAL   m_Paste
 
   CBLINN_PHONG_MATERIAL   m_SilkS
 
   CBLINN_PHONG_MATERIAL   m_SolderMask
 
   CBLINN_PHONG_MATERIAL   m_EpoxyBoard
 
   CBLINN_PHONG_MATERIAL   m_Copper
 
   CBLINN_PHONG_MATERIAL   m_Floor
 
m_materials
 
CBOARDNORMAL m_board_normal_perturbator
 
CCOPPERNORMAL m_copper_normal_perturbator
 
CSOLDERMASKNORMAL m_solder_mask_normal_perturbator
 
CPLASTICNORMAL m_plastic_normal_perturbator
 
CPLASTICSHINENORMAL m_plastic_shine_normal_perturbator
 
CMETALBRUSHEDNORMAL m_brushed_metal_normal_perturbator
 
bool m_isPreview
 
RT_RENDER_STATE m_rt_render_state
 State used on quality render. More...
 
unsigned long int m_stats_start_rendering_time
 Time that the render starts. More...
 
size_t m_nrBlocksRenderProgress
 Save the number of blocks progress of the render. More...
 
CPOSTSHADER_SSAO m_postshader_ssao
 
CLIGHTCONTAINER m_lights
 
CDIRECTIONALLIGHTm_camera_light
 
bool m_opengl_support_vertex_buffer_object
 
GLuint m_pboId
 
GLuint m_pboDataSize
 
CCONTAINER m_object_container
 
CCONTAINER2D m_containerWithObjectsToDelete
 This will store the list of created objects special for RT, that will be clear in the end. More...
 
CCONTAINER2Dm_outlineBoard2dObjects
 
CGENERICACCELERATORm_accelerator
 
SFVEC3F m_BgColorTop_LinearRGB
 
SFVEC3F m_BgColorBot_LinearRGB
 
wxSize m_oldWindowsSize
 used to see if the windows size changed More...
 
std::vector< SFVEC2UIm_blockPositions
 this encodes the Morton code positions More...
 
std::vector< int > m_blockPositionsWasProcessed
 this flags if a position was already processed (cleared each new render) More...
 
std::vector< SFVEC2UIm_blockPositionsFast
 this encodes the Morton code positions (on fast preview mode) More...
 
SFVEC2UI m_realBufferSize
 
SFVEC2UI m_fastPreviewModeSize
 
HITINFO_PACKETm_firstHitinfo
 
SFVEC3Fm_shaderBuffer
 
unsigned int m_xoffset
 
unsigned int m_yoffset
 
unsigned int m_stats_converted_dummy_to_plane
 
unsigned int m_stats_converted_roundsegment2d_to_roundsegment
 
MAP_MODEL_MATERIALS m_model_materials
 Stores materials of the 3D models. More...
 

Detailed Description

Definition at line 59 of file c3d_render_raytracing.h.

Constructor & Destructor Documentation

◆ C3D_RENDER_RAYTRACING()

C3D_RENDER_RAYTRACING::C3D_RENDER_RAYTRACING ( BOARD_ADAPTER aAdapter,
CCAMERA aCamera 
)
explicit

Definition at line 49 of file c3d_render_raytracing.cpp.

49  :
50  C3D_RENDER_BASE( aAdapter, aCamera ),
51  m_postshader_ssao( aCamera )
52 {
53  wxLogTrace( m_logTrace, wxT( "C3D_RENDER_RAYTRACING::C3D_RENDER_RAYTRACING" ) );
54 
56  m_pboId = GL_NONE;
57  m_pboDataSize = 0;
61  m_oldWindowsSize.x = 0;
62  m_oldWindowsSize.y = 0;
67 
68  m_xoffset = 0;
69  m_yoffset = 0;
70 
71  m_isPreview = false;
72  m_rt_render_state = RT_RENDER_STATE_MAX; // Set to an initial invalid state
75 }
CPOSTSHADER_SSAO m_postshader_ssao
wxSize m_oldWindowsSize
used to see if the windows size changed
HITINFO_PACKET * m_firstHitinfo
unsigned int m_stats_converted_dummy_to_plane
CGENERICACCELERATOR * m_accelerator
size_t m_nrBlocksRenderProgress
Save the number of blocks progress of the render.
#define NULL
RT_RENDER_STATE m_rt_render_state
State used on quality render.
C3D_RENDER_BASE(BOARD_ADAPTER &aBoardAdapter, CCAMERA &aCamera)
unsigned int m_stats_converted_roundsegment2d_to_roundsegment
CDIRECTIONALLIGHT * m_camera_light
unsigned long int m_stats_start_rendering_time
Time that the render starts.
CCONTAINER2D * m_outlineBoard2dObjects
static const wxChar * m_logTrace
Trace mask used to enable or disable the trace output of this class.

References m_accelerator, m_camera_light, m_firstHitinfo, m_isPreview, C3D_RENDER_BASE::m_logTrace, m_nrBlocksRenderProgress, m_oldWindowsSize, m_opengl_support_vertex_buffer_object, m_outlineBoard2dObjects, m_pboDataSize, m_pboId, m_rt_render_state, m_shaderBuffer, m_stats_converted_dummy_to_plane, m_stats_converted_roundsegment2d_to_roundsegment, m_stats_start_rendering_time, m_xoffset, m_yoffset, NULL, and RT_RENDER_STATE_MAX.

◆ ~C3D_RENDER_RAYTRACING()

C3D_RENDER_RAYTRACING::~C3D_RENDER_RAYTRACING ( )

Definition at line 78 of file c3d_render_raytracing.cpp.

79 {
80  wxLogTrace( m_logTrace, wxT( "C3D_RENDER_RAYTRACING::~C3D_RENDER_RAYTRACING" ) );
81 
82  delete m_accelerator;
84 
87 
88  delete[] m_shaderBuffer;
90 
92 }
CGENERICACCELERATOR * m_accelerator
#define NULL
CCONTAINER2D * m_outlineBoard2dObjects
static const wxChar * m_logTrace
Trace mask used to enable or disable the trace output of this class.

References m_accelerator, C3D_RENDER_BASE::m_logTrace, m_outlineBoard2dObjects, m_shaderBuffer, NULL, and opengl_delete_pbo().

Member Function Documentation

◆ add_3D_models()

void C3D_RENDER_RAYTRACING::add_3D_models ( const S3DMODEL a3DModel,
const glm::mat4 &  aModelMatrix,
float  aModuleOpacity 
)
private

Definition at line 1394 of file c3d_render_createscene.cpp.

1397 {
1398 
1399  // Validate a3DModel pointers
1400  wxASSERT( a3DModel != NULL );
1401 
1402  if( a3DModel == NULL )
1403  return;
1404 
1405  wxASSERT( a3DModel->m_Materials != NULL );
1406  wxASSERT( a3DModel->m_Meshes != NULL );
1407  wxASSERT( a3DModel->m_MaterialsSize > 0 );
1408  wxASSERT( a3DModel->m_MeshesSize > 0 );
1409  wxASSERT( aModuleOpacity > 0.0f );
1410  wxASSERT( aModuleOpacity <= 1.0f );
1411 
1412  if( aModuleOpacity > 1.0f )
1413  {
1414  aModuleOpacity = 1.0f;
1415  }
1416 
1417  if( (a3DModel->m_Materials != NULL) && (a3DModel->m_Meshes != NULL) &&
1418  (a3DModel->m_MaterialsSize > 0) && (a3DModel->m_MeshesSize > 0) )
1419  {
1420 
1421  MODEL_MATERIALS *materialVector;
1422 
1423  // Try find if the materials already exists in the map list
1424  if( m_model_materials.find( a3DModel ) != m_model_materials.end() )
1425  {
1426  // Found it, so get the pointer
1427  materialVector = &m_model_materials[a3DModel];
1428  }
1429  else
1430  {
1431  // Materials was not found in the map, so it will create a new for
1432  // this model.
1433 
1434  m_model_materials[a3DModel] = MODEL_MATERIALS();
1435  materialVector = &m_model_materials[a3DModel];
1436 
1437  materialVector->resize( a3DModel->m_MaterialsSize );
1438 
1439  for( unsigned int imat = 0;
1440  imat < a3DModel->m_MaterialsSize;
1441  ++imat )
1442  {
1444  {
1445  const SMATERIAL &material = a3DModel->m_Materials[imat];
1446 
1447  // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiJtaW4oc3FydCh4LTAuMzUpKjAuNDAtMC4wNSwxLjApIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiMC4wNzA3NzM2NzMyMzY1OTAxMiIsIjEuNTY5NTcxNjI5MjI1NDY5OCIsIi0wLjI3NDYzNTMyMTc1OTkyOTMiLCIwLjY0NzcwMTg4MTkyNTUzNjIiXSwic2l6ZSI6WzY0NCwzOTRdfV0-
1448 
1449  float reflectionFactor = 0.0f;
1450 
1451  if( (material.m_Shininess - 0.35f) > FLT_EPSILON )
1452  {
1453  reflectionFactor = glm::clamp( glm::sqrt( (material.m_Shininess - 0.35f) ) *
1454  0.40f - 0.05f,
1455  0.0f,
1456  0.5f );
1457  }
1458 
1459  CBLINN_PHONG_MATERIAL &blinnMaterial = (*materialVector)[imat];
1460 
1461  SFVEC3F ambient;
1462 
1464  {
1465  // apply a gain to the (dark) ambient colors
1466 
1467  // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoKHgrMC4yMCleKDEvMi4wMCkpLTAuMzUiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjAsImVxIjoieCIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0xLjI0OTUwNTMzOTIyMzYyIiwiMS42Nzc4MzQ0MTg1NjcxODQzIiwiLTAuNDM1NTA0NjQyODEwOTMwMjYiLCIxLjM2NTkzNTIwODEzNzI1OCJdLCJzaXplIjpbNjQ5LDM5OV19XQ--
1468  // ambient = glm::max( (glm::pow((material.m_Ambient + 0.20f), SFVEC3F(1.0f / 2.00f)) - SFVEC3F(0.35f)), material.m_Ambient );
1469 
1470  // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoKHgrMC4yMCleKDEvMS41OCkpLTAuMzUiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjAsImVxIjoieCIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0xLjI0OTUwNTMzOTIyMzYyIiwiMS42Nzc4MzQ0MTg1NjcxODQzIiwiLTAuNDM1NTA0NjQyODEwOTMwMjYiLCIxLjM2NTkzNTIwODEzNzI1OCJdLCJzaXplIjpbNjQ5LDM5OV19XQ--
1471  //ambient = glm::max( (glm::pow((material.m_Ambient + 0.20f), SFVEC3F(1.0f / 1.58f)) - SFVEC3F(0.35f)), material.m_Ambient );
1472 
1473  // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoKHgrMC4yMCleKDEvMS41NCkpLTAuMzQiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjAsImVxIjoieCIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0yLjcyMTA5NTg0MjA1MDYwNSIsIjEuODUyODcyNTI5NDk3NTIyMyIsIi0xLjQyMTM3NjAxOTkyOTA4MDYiLCIxLjM5MzM3Mzc0NzE3NzQ2MTIiXSwic2l6ZSI6WzY0OSwzOTldfV0-
1474  ambient = ConvertSRGBToLinear(
1475  glm::pow((material.m_Ambient + 0.30f), SFVEC3F(1.0f / 1.54f)) - SFVEC3F(0.34f) );
1476  }
1477  else
1478  {
1479  ambient = ConvertSRGBToLinear( material.m_Ambient );
1480  }
1481 
1482 
1483  blinnMaterial = CBLINN_PHONG_MATERIAL(
1484  ambient,
1485  ConvertSRGBToLinear( material.m_Emissive ),
1486  ConvertSRGBToLinear( material.m_Specular ),
1487  material.m_Shininess * 180.0f,
1488  material.m_Transparency,
1489  reflectionFactor );
1490 
1492  {
1493  // Guess material type and apply a normal perturbator
1494 
1495  if( ( RGBtoGray(material.m_Diffuse) < 0.3f ) &&
1496  ( material.m_Shininess < 0.36f ) &&
1497  ( material.m_Transparency == 0.0f ) &&
1498  ( (glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) < 0.15f) &&
1499  (glm::abs( material.m_Diffuse.b - material.m_Diffuse.g ) < 0.15f) &&
1500  (glm::abs( material.m_Diffuse.r - material.m_Diffuse.b ) < 0.15f) ) )
1501  {
1502  // This may be a black plastic..
1503 
1504  if( material.m_Shininess < 0.26f )
1506  else
1508  }
1509  else
1510  {
1511  if( ( RGBtoGray(material.m_Diffuse) > 0.3f ) &&
1512  ( material.m_Shininess < 0.30f ) &&
1513  ( material.m_Transparency == 0.0f ) &&
1514  ( (glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) > 0.25f) ||
1515  (glm::abs( material.m_Diffuse.b - material.m_Diffuse.g ) > 0.25f) ||
1516  (glm::abs( material.m_Diffuse.r - material.m_Diffuse.b ) > 0.25f) ) )
1517  {
1518  // This may be a color plastic ...
1520  }
1521  else
1522  {
1523  if( ( RGBtoGray(material.m_Diffuse) > 0.6f ) &&
1524  ( material.m_Shininess > 0.35f ) &&
1525  ( material.m_Transparency == 0.0f ) &&
1526  ( (glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) < 0.40f) &&
1527  (glm::abs( material.m_Diffuse.b - material.m_Diffuse.g ) < 0.40f) &&
1528  (glm::abs( material.m_Diffuse.r - material.m_Diffuse.b ) < 0.40f) ) )
1529  {
1530  // This may be a brushed metal
1532  }
1533  }
1534  }
1535  }
1536  }
1537  else
1538  {
1539  (*materialVector)[imat] = CBLINN_PHONG_MATERIAL( SFVEC3F( 0.2f ),
1540  SFVEC3F( 0.0f ),
1541  SFVEC3F( 0.0f ),
1542  0.0f,
1543  0.0f,
1544  0.0f );
1545  }
1546  }
1547  }
1548 
1549  const glm::mat3 normalMatrix = glm::transpose( glm::inverse( glm::mat3( aModelMatrix ) ) );
1550 
1551  for( unsigned int mesh_i = 0;
1552  mesh_i < a3DModel->m_MeshesSize;
1553  ++mesh_i )
1554  {
1555  const SMESH &mesh = a3DModel->m_Meshes[mesh_i];
1556 
1557  // Validate the mesh pointers
1558  wxASSERT( mesh.m_Positions != NULL );
1559  wxASSERT( mesh.m_FaceIdx != NULL );
1560  wxASSERT( mesh.m_Normals != NULL );
1561  wxASSERT( mesh.m_FaceIdxSize > 0 );
1562  wxASSERT( (mesh.m_FaceIdxSize % 3) == 0 );
1563 
1564 
1565  if( (mesh.m_Positions != NULL) &&
1566  (mesh.m_Normals != NULL) &&
1567  (mesh.m_FaceIdx != NULL) &&
1568  (mesh.m_FaceIdxSize > 0) &&
1569  (mesh.m_VertexSize > 0) &&
1570  ((mesh.m_FaceIdxSize % 3) == 0) &&
1571  (mesh.m_MaterialIdx < a3DModel->m_MaterialsSize) )
1572  {
1573  const CBLINN_PHONG_MATERIAL &blinn_material = (*materialVector)[mesh.m_MaterialIdx];
1574 
1575  const float moduleTransparency = 1.0f - ( ( 1.0f - blinn_material.GetTransparency() ) * aModuleOpacity );
1576 
1577  // Add all face triangles
1578  for( unsigned int faceIdx = 0;
1579  faceIdx < mesh.m_FaceIdxSize;
1580  faceIdx += 3 )
1581  {
1582  const unsigned int idx0 = mesh.m_FaceIdx[faceIdx + 0];
1583  const unsigned int idx1 = mesh.m_FaceIdx[faceIdx + 1];
1584  const unsigned int idx2 = mesh.m_FaceIdx[faceIdx + 2];
1585 
1586  wxASSERT( idx0 < mesh.m_VertexSize );
1587  wxASSERT( idx1 < mesh.m_VertexSize );
1588  wxASSERT( idx2 < mesh.m_VertexSize );
1589 
1590  if( ( idx0 < mesh.m_VertexSize ) &&
1591  ( idx1 < mesh.m_VertexSize ) &&
1592  ( idx2 < mesh.m_VertexSize ) )
1593  {
1594  const SFVEC3F &v0 = mesh.m_Positions[idx0];
1595  const SFVEC3F &v1 = mesh.m_Positions[idx1];
1596  const SFVEC3F &v2 = mesh.m_Positions[idx2];
1597 
1598  const SFVEC3F &n0 = mesh.m_Normals[idx0];
1599  const SFVEC3F &n1 = mesh.m_Normals[idx1];
1600  const SFVEC3F &n2 = mesh.m_Normals[idx2];
1601 
1602  // Transform vertex with the model matrix
1603  const SFVEC3F vt0 = SFVEC3F( aModelMatrix * glm::vec4( v0, 1.0f) );
1604  const SFVEC3F vt1 = SFVEC3F( aModelMatrix * glm::vec4( v1, 1.0f) );
1605  const SFVEC3F vt2 = SFVEC3F( aModelMatrix * glm::vec4( v2, 1.0f) );
1606 
1607  const SFVEC3F nt0 = glm::normalize( SFVEC3F( normalMatrix * n0 ) );
1608  const SFVEC3F nt1 = glm::normalize( SFVEC3F( normalMatrix * n1 ) );
1609  const SFVEC3F nt2 = glm::normalize( SFVEC3F( normalMatrix * n2 ) );
1610 
1611  CTRIANGLE *newTriangle = new CTRIANGLE( vt0, vt2, vt1,
1612  nt0, nt2, nt1 );
1613 
1614  m_object_container.Add( newTriangle );
1615  newTriangle->SetMaterial( (const CMATERIAL *)&blinn_material );
1616 
1617  newTriangle->SetModelTransparency( moduleTransparency );
1618 
1619  if( mesh.m_Color == NULL )
1620  {
1621  const SFVEC3F diffuseColor =
1622  a3DModel->m_Materials[mesh.m_MaterialIdx].m_Diffuse;
1623 
1625  newTriangle->SetColor( ConvertSRGBToLinear( MaterialDiffuseToColorCAD( diffuseColor ) ) );
1626  else
1627  newTriangle->SetColor( ConvertSRGBToLinear( diffuseColor ) );
1628  }
1629  else
1630  {
1632  newTriangle->SetColor( ConvertSRGBToLinear( MaterialDiffuseToColorCAD( mesh.m_Color[idx0] ) ),
1635  else
1636  newTriangle->SetColor( ConvertSRGBToLinear( mesh.m_Color[idx0] ),
1637  ConvertSRGBToLinear( mesh.m_Color[idx1] ),
1638  ConvertSRGBToLinear( mesh.m_Color[idx2] ) );
1639  }
1640  }
1641  }
1642  }
1643  }
1644  }
1645 }
Use a gray shading based on diffuse material.
SFVEC3F * m_Normals
Vertex normals array.
Definition: c3dmodel.h:80
bool GetFlag(DISPLAY3D_FLG aFlag) const
GetFlag - get a configuration status of a flag.
float RGBtoGray(const SFVEC3F &aColor)
Definition: 3d_math.h:147
SFVEC3F m_Ambient
Definition: c3dmodel.h:39
CPLASTICNORMAL m_plastic_normal_perturbator
SFVEC3F ConvertSRGBToLinear(const SFVEC3F &aSRGBcolor)
A base material class that can be used to derive a material implementation.
Definition: cmaterial.h:195
void SetMaterial(const CMATERIAL *aMaterial)
Definition: cobject.h:66
CPLASTICSHINENORMAL m_plastic_shine_normal_perturbator
float m_Transparency
1.0 is completely transparent, 0.0 completely opaque
Definition: c3dmodel.h:44
void SetNormalPerturbator(const CPROCEDURALGENERATOR *aPerturbator)
Definition: cmaterial.h:250
SFVEC3F * m_Positions
Vertex position array.
Definition: c3dmodel.h:79
CMETALBRUSHEDNORMAL m_brushed_metal_normal_perturbator
Per-vertex normal/color/texcoors structure.
Definition: c3dmodel.h:76
SMESH * m_Meshes
The meshes list of this model.
Definition: c3dmodel.h:93
unsigned int m_FaceIdxSize
Number of elements of the m_FaceIdx array.
Definition: c3dmodel.h:83
std::vector< CBLINN_PHONG_MATERIAL > MODEL_MATERIALS
Vector of materials.
void SetColor(const SFVEC3F &aColor)
Definition: ctriangle.cpp:156
unsigned int m_VertexSize
Number of vertex in the arrays.
Definition: c3dmodel.h:78
#define NULL
Use all material properties from model file.
void SetModelTransparency(float aModelTransparency)
Definition: cobject.h:74
Blinn Phong based material https://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model.
Definition: cmaterial.h:278
SFVEC3F * m_Color
Vertex color array, can be NULL.
Definition: c3dmodel.h:82
float m_Shininess
Definition: c3dmodel.h:43
unsigned int m_MaterialsSize
Number of materials in the material array.
Definition: c3dmodel.h:95
A triangle object.
Definition: ctriangle.h:42
void Add(COBJECT *aObject)
Definition: ccontainer.h:52
BOARD_ADAPTER & m_boardAdapter
settings refrence in use for this render
float GetTransparency() const
Definition: cmaterial.h:213
SFVEC3F MaterialDiffuseToColorCAD(const SFVEC3F &aDiffuseColor)
Definition: 3d_math.h:154
SFVEC3F m_Emissive
Definition: c3dmodel.h:41
glm::vec3 SFVEC3F
Definition: xv3d_types.h:47
unsigned int m_MaterialIdx
Material Index to be used in this mesh (must be < m_MaterialsSize )
Definition: c3dmodel.h:85
SMATERIAL * m_Materials
The materials list of this model.
Definition: c3dmodel.h:96
SFVEC3F m_Diffuse
Default diffuse color if m_Color is NULL.
Definition: c3dmodel.h:40
unsigned int * m_FaceIdx
Triangle Face Indexes.
Definition: c3dmodel.h:84
MATERIAL_MODE MaterialModeGet() const noexcept
MaterialModeGet.
unsigned int m_MeshesSize
Number of meshes in the array.
Definition: c3dmodel.h:92
MAP_MODEL_MATERIALS m_model_materials
Stores materials of the 3D models.
SFVEC3F m_Specular
Definition: c3dmodel.h:42

References CGENERICCONTAINER::Add(), CAD_MODE, ConvertSRGBToLinear(), FL_RENDER_RAYTRACING_POST_PROCESSING, FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES, BOARD_ADAPTER::GetFlag(), CMATERIAL::GetTransparency(), SMATERIAL::m_Ambient, C3D_RENDER_BASE::m_boardAdapter, m_brushed_metal_normal_perturbator, SMESH::m_Color, SMATERIAL::m_Diffuse, SMATERIAL::m_Emissive, SMESH::m_FaceIdx, SMESH::m_FaceIdxSize, SMESH::m_MaterialIdx, S3DMODEL::m_Materials, S3DMODEL::m_MaterialsSize, S3DMODEL::m_Meshes, S3DMODEL::m_MeshesSize, m_model_materials, SMESH::m_Normals, m_object_container, m_plastic_normal_perturbator, m_plastic_shine_normal_perturbator, SMESH::m_Positions, SMATERIAL::m_Shininess, SMATERIAL::m_Specular, SMATERIAL::m_Transparency, SMESH::m_VertexSize, MaterialDiffuseToColorCAD(), BOARD_ADAPTER::MaterialModeGet(), NORMAL, NULL, RGBtoGray(), CTRIANGLE::SetColor(), COBJECT::SetMaterial(), COBJECT::SetModelTransparency(), and CMATERIAL::SetNormalPerturbator().

Referenced by load_3D_models().

◆ add_3D_vias_and_pads_to_container()

void C3D_RENDER_RAYTRACING::add_3D_vias_and_pads_to_container ( )
private

Definition at line 1265 of file c3d_render_createscene.cpp.

1266 {
1267  // Insert plated vertical holes inside the board
1268  // /////////////////////////////////////////////////////////////////////////
1269 
1270  // Insert vias holes (vertical cylinders)
1271  for( auto track : m_boardAdapter.GetBoard()->Tracks() )
1272  {
1273  if( track->Type() == PCB_VIA_T )
1274  {
1275  const VIA *via = static_cast<const VIA*>(track);
1276  insert3DViaHole( via );
1277  }
1278  }
1279 
1280  // Insert pads holes (vertical cylinders)
1281  for( auto module : m_boardAdapter.GetBoard()->Modules() )
1282  {
1283  for( auto pad : module->Pads() )
1284  if( pad->GetAttribute () != PAD_ATTRIB_HOLE_NOT_PLATED )
1285  {
1286  insert3DPadHole( pad );
1287  }
1288  }
1289 }
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:85
void insert3DViaHole(const VIA *aVia)
MODULES & Modules()
Definition: class_board.h:266
const BOARD * GetBoard() const noexcept
GetBoard - Get current board to be rendered.
BOARD_ADAPTER & m_boardAdapter
settings refrence in use for this render
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
void insert3DPadHole(const D_PAD *aPad)
TRACKS & Tracks()
Definition: class_board.h:257

References BOARD_ADAPTER::GetBoard(), insert3DPadHole(), insert3DViaHole(), C3D_RENDER_BASE::m_boardAdapter, BOARD::Modules(), PAD_ATTRIB_HOLE_NOT_PLATED, PCB_VIA_T, and BOARD::Tracks().

Referenced by reload().

◆ create_3d_object_from()

void C3D_RENDER_RAYTRACING::create_3d_object_from ( CCONTAINER aDstContainer,
const COBJECT2D aObject2D,
float  aZMin,
float  aZMax,
const CMATERIAL aMaterial,
const SFVEC3F aObjColor 
)
private

Function create_3d_object_from.

Creates on or more 3D objects form a 2D object and Z positions. It try optimize some types of objects that will be faster to trace than the CLAYERITEM object.

Parameters
aObject2D
aZMin
aZMax

Definition at line 201 of file c3d_render_createscene.cpp.

204 {
205  switch( aObject2D->GetObjectType() )
206  {
208  {
210 #if 1
211  CXYPLANE* objPtr;
212  objPtr = new CXYPLANE( CBBOX(
213  SFVEC3F( aObject2D->GetBBox().Min().x, aObject2D->GetBBox().Min().y, aZMin ),
214  SFVEC3F( aObject2D->GetBBox().Max().x, aObject2D->GetBBox().Max().y, aZMin ) ) );
215  objPtr->SetMaterial( aMaterial );
216  objPtr->SetColor( ConvertSRGBToLinear( aObjColor ) );
217  aDstContainer.Add( objPtr );
218 
219  objPtr = new CXYPLANE( CBBOX(
220  SFVEC3F( aObject2D->GetBBox().Min().x, aObject2D->GetBBox().Min().y, aZMax ),
221  SFVEC3F( aObject2D->GetBBox().Max().x, aObject2D->GetBBox().Max().y, aZMax ) ) );
222  objPtr->SetMaterial( aMaterial );
223  objPtr->SetColor( ConvertSRGBToLinear( aObjColor ) );
224  aDstContainer.Add( objPtr );
225 #else
226  objPtr = new CDUMMYBLOCK( CBBOX(
227  SFVEC3F( aObject2D->GetBBox().Min().x, aObject2D->GetBBox().Min().y, aZMin ),
228  SFVEC3F( aObject2D->GetBBox().Max().x, aObject2D->GetBBox().Max().y, aZMax ) ) );
229  objPtr->SetMaterial( aMaterial );
230  aDstContainer.Add( objPtr );
231 #endif
232  }
233  break;
234 
236  {
238 
239  const CROUNDSEGMENT2D* aRoundSeg2D = static_cast<const CROUNDSEGMENT2D*>( aObject2D );
240  CROUNDSEG* objPtr = new CROUNDSEG( *aRoundSeg2D, aZMin, aZMax );
241  objPtr->SetMaterial( aMaterial );
242  objPtr->SetColor( ConvertSRGBToLinear( aObjColor ) );
243  aDstContainer.Add( objPtr );
244  }
245  break;
246 
247 
248  default:
249  {
250  CLAYERITEM* objPtr = new CLAYERITEM( aObject2D, aZMin, aZMax );
251  objPtr->SetMaterial( aMaterial );
252  objPtr->SetColor( ConvertSRGBToLinear( aObjColor ) );
253  aDstContainer.Add( objPtr );
254  }
255  break;
256  }
257 }
SFVEC3F ConvertSRGBToLinear(const SFVEC3F &aSRGBcolor)
OBJECT2D_TYPE GetObjectType() const
Definition: cobject2d.h:125
const SFVEC2F & Min() const
Function Min return the minimun vertex pointer.
Definition: cbbox2d.h:176
void SetMaterial(const CMATERIAL *aMaterial)
Definition: cobject.h:66
A dummy block is used to fill the polygons.
Definition: cdummyblock.h:39
void SetColor(SFVEC3F aObjColor)
Definition: croundseg.h:48
A plane that is parallel to XY plane.
Definition: cplane.h:38
unsigned int m_stats_converted_dummy_to_plane
void SetColor(SFVEC3F aObjColor)
Definition: cplane.h:52
unsigned int m_stats_converted_roundsegment2d_to_roundsegment
const SFVEC2F & Max() const
Function Max return the maximum vertex pointer.
Definition: cbbox2d.h:183
void SetColor(SFVEC3F aObjColor)
Definition: clayeritem.h:46
void Add(COBJECT *aObject)
Definition: ccontainer.h:52
glm::vec3 SFVEC3F
Definition: xv3d_types.h:47
const CBBOX2D & GetBBox() const
Definition: cobject2d.h:121
CBBOX manages a bounding box defined by two SFVEC3F min max points.
Definition: cbbox.h:40

References CGENERICCONTAINER::Add(), ConvertSRGBToLinear(), DUMMYBLOCK, COBJECT2D::GetBBox(), COBJECT2D::GetObjectType(), m_stats_converted_dummy_to_plane, m_stats_converted_roundsegment2d_to_roundsegment, CBBOX2D::Max(), CBBOX2D::Min(), ROUNDSEG, CLAYERITEM::SetColor(), CROUNDSEG::SetColor(), CXYPLANE::SetColor(), and COBJECT::SetMaterial().

Referenced by reload().

◆ CreateBusyIndicator()

std::unique_ptr< BUSY_INDICATOR > C3D_RENDER_BASE::CreateBusyIndicator ( ) const
protectedinherited

Return a created busy indicator, if a factory has been set, else a null pointer.

Definition at line 65 of file c3d_render_base.cpp.

66 {
67  std::unique_ptr<BUSY_INDICATOR> busy;
68 
70  busy = m_busyIndicatorFactory();
71 
72  return busy;
73 }
BUSY_INDICATOR::FACTORY m_busyIndicatorFactory
Factory that returns a suitable busy indicator for the context.

References C3D_RENDER_BASE::m_busyIndicatorFactory.

Referenced by C3D_RENDER_OGL_LEGACY::Redraw(), and Redraw().

◆ GetWaitForEditingTimeOut()

int C3D_RENDER_RAYTRACING::GetWaitForEditingTimeOut ( )
overridevirtual

GetWaitForEditingTimeOut - Give the interface the time (in ms) that it should wait for editing or movements before (this works for display preview mode)

Returns
a value in miliseconds

Implements C3D_RENDER_BASE.

Definition at line 95 of file c3d_render_raytracing.cpp.

96 {
97  return 1000; // ms
98 }

◆ initialize_block_positions()

void C3D_RENDER_RAYTRACING::initialize_block_positions ( )
private

Definition at line 2022 of file c3d_render_raytracing.cpp.

2023 {
2024 
2025  m_realBufferSize = SFVEC2UI( 0 );
2026 
2027  // Calc block positions for fast preview mode
2028  // /////////////////////////////////////////////////////////////////////
2029  m_blockPositionsFast.clear();
2030 
2031  unsigned int i = 0;
2032 
2033  while(1)
2034  {
2035  const unsigned int mX = DecodeMorton2X(i);
2036  const unsigned int mY = DecodeMorton2Y(i);
2037 
2038  i++;
2039 
2040  const SFVEC2UI blockPos( mX * 4 * RAYPACKET_DIM - mX * 4,
2041  mY * 4 * RAYPACKET_DIM - mY * 4);
2042 
2043  if( ( blockPos.x >= ( (unsigned int)m_windowSize.x - ( 4 * RAYPACKET_DIM + 4 ) ) ) &&
2044  ( blockPos.y >= ( (unsigned int)m_windowSize.y - ( 4 * RAYPACKET_DIM + 4 ) ) ) )
2045  break;
2046 
2047  if( ( blockPos.x < ( (unsigned int)m_windowSize.x - ( 4 * RAYPACKET_DIM + 4) ) ) &&
2048  ( blockPos.y < ( (unsigned int)m_windowSize.y - ( 4 * RAYPACKET_DIM + 4) ) ) )
2049  {
2050  m_blockPositionsFast.push_back( blockPos );
2051 
2052  if( blockPos.x > m_realBufferSize.x )
2053  m_realBufferSize.x = blockPos.x;
2054 
2055  if( blockPos.y > m_realBufferSize.y )
2056  m_realBufferSize.y = blockPos.y;
2057  }
2058  }
2059 
2061 
2064 
2065  m_xoffset = (m_windowSize.x - m_realBufferSize.x) / 2;
2066  m_yoffset = (m_windowSize.y - m_realBufferSize.y) / 2;
2067 
2069 
2070 
2071  // Calc block positions for regular rendering. Choose an 'inside out'
2072  // style of rendering
2073  // /////////////////////////////////////////////////////////////////////
2074  m_blockPositions.clear();
2075  const int blocks_x = m_realBufferSize.x / RAYPACKET_DIM;
2076  const int blocks_y = m_realBufferSize.y / RAYPACKET_DIM;
2077  m_blockPositions.reserve( blocks_x * blocks_y );
2078 
2079  for( int x = 0; x < blocks_x; ++x )
2080  for( int y = 0; y < blocks_y; ++y )
2081  m_blockPositions.emplace_back( x * RAYPACKET_DIM, y * RAYPACKET_DIM );
2082 
2083  const SFVEC2UI center( m_realBufferSize.x / 2, m_realBufferSize.y / 2 );
2084  std::sort( m_blockPositions.begin(), m_blockPositions.end(),
2085  [&]( const SFVEC2UI& a, const SFVEC2UI& b ) {
2086  // Sort order: inside out.
2087  return distance( a, center ) < distance( b, center );
2088  } );
2089 
2090  // Create m_shader buffer
2091  delete[] m_shaderBuffer;
2093 
2094  opengl_init_pbo();
2095 }
#define RAYPACKET_DIM
Definition: raypacket.h:37
CPOSTSHADER_SSAO m_postshader_ssao
uint32_t DecodeMorton2X(uint32_t code)
Definition: mortoncodes.cpp:98
#define RAYPACKET_INVMASK
Definition: raypacket.h:39
uint32_t DecodeMorton2Y(uint32_t code)
glm::uvec2 SFVEC2UI
Definition: xv3d_types.h:41
wxSize m_windowSize
The window size that this camera is working.
std::vector< SFVEC2UI > m_blockPositionsFast
this encodes the Morton code positions (on fast preview mode)
glm::vec3 SFVEC3F
Definition: xv3d_types.h:47
std::vector< SFVEC2UI > m_blockPositions
this encodes the Morton code positions
static float distance(const SFVEC2UI &a, const SFVEC2UI &b)
void UpdateSize(const SFVEC2UI &aSize)
Definition: cpostshader.cpp:72

References DecodeMorton2X(), DecodeMorton2Y(), distance(), m_blockPositions, m_blockPositionsFast, m_fastPreviewModeSize, m_postshader_ssao, m_realBufferSize, m_shaderBuffer, C3D_RENDER_BASE::m_windowSize, m_xoffset, m_yoffset, opengl_init_pbo(), RAYPACKET_DIM, RAYPACKET_INVMASK, and CPOSTSHADER::UpdateSize().

Referenced by Redraw().

◆ initializeNewWindowSize()

void C3D_RENDER_RAYTRACING::initializeNewWindowSize ( )
private

Definition at line 1972 of file c3d_render_raytracing.cpp.

1973 {
1974  opengl_init_pbo();
1975 }

References opengl_init_pbo().

Referenced by SetCurWindowSize().

◆ initializeOpenGL()

bool C3D_RENDER_RAYTRACING::initializeOpenGL ( )
private

Definition at line 2007 of file c3d_render_raytracing.cpp.

2008 {
2009  m_is_opengl_initialized = true;
2010 
2011  return true;
2012 }
bool m_is_opengl_initialized
flag if the opengl specific for this render was already initialized

References C3D_RENDER_BASE::m_is_opengl_initialized.

Referenced by Redraw().

◆ insert3DPadHole()

void C3D_RENDER_RAYTRACING::insert3DPadHole ( const D_PAD aPad)
private

Definition at line 1108 of file c3d_render_createscene.cpp.

1109 {
1110  const COBJECT2D *object2d_A = NULL;
1111 
1112  SFVEC3F objColor;
1113 
1115  objColor = (SFVEC3F)m_boardAdapter.m_CopperColor;
1116  else
1118 
1119  const wxSize drillsize = aPad->GetDrillSize();
1120  const bool hasHole = drillsize.x && drillsize.y;
1121 
1122  if( !hasHole )
1123  return;
1124 
1125  const float topZ = m_boardAdapter.GetLayerBottomZpos3DU( F_Cu ) +
1127 
1128  const float botZ = m_boardAdapter.GetLayerBottomZpos3DU( B_Cu ) -
1130 
1131  if( drillsize.x == drillsize.y ) // usual round hole
1132  {
1133  SFVEC2F center = SFVEC2F( aPad->GetPosition().x * m_boardAdapter.BiuTo3Dunits(),
1134  -aPad->GetPosition().y * m_boardAdapter.BiuTo3Dunits() );
1135 
1136  CRING2D *ring = new CRING2D( center,
1137  ( drillsize.x / 2 ) * m_boardAdapter.BiuTo3Dunits(),
1138  (( drillsize.x / 2 ) +
1141  *aPad );
1142 
1144 
1145  object2d_A = ring;
1146  }
1147  else // Oblong hole
1148  {
1149  wxPoint ends_offset;
1150  int width;
1151 
1152  if( drillsize.x > drillsize.y ) // Horizontal oval
1153  {
1154  ends_offset.x = ( drillsize.x - drillsize.y ) / 2;
1155  width = drillsize.y;
1156  }
1157  else // Vertical oval
1158  {
1159  ends_offset.y = ( drillsize.y - drillsize.x ) / 2;
1160  width = drillsize.x;
1161  }
1162 
1163  RotatePoint( &ends_offset, aPad->GetOrientation() );
1164 
1165  wxPoint start = aPad->GetPosition() + ends_offset;
1166  wxPoint end = aPad->GetPosition() - ends_offset;
1167 
1168  CROUNDSEGMENT2D *innerSeg = new CROUNDSEGMENT2D(
1169  SFVEC2F( start.x * m_boardAdapter.BiuTo3Dunits(),
1170  -start.y * m_boardAdapter.BiuTo3Dunits() ),
1172  -end.y * m_boardAdapter.BiuTo3Dunits() ),
1173  width * m_boardAdapter.BiuTo3Dunits(),
1174  *aPad );
1175 
1176  CROUNDSEGMENT2D *outerSeg = new CROUNDSEGMENT2D(
1177  SFVEC2F( start.x * m_boardAdapter.BiuTo3Dunits(),
1178  -start.y * m_boardAdapter.BiuTo3Dunits() ),
1180  -end.y * m_boardAdapter.BiuTo3Dunits() ),
1181  ( width + m_boardAdapter.GetCopperThicknessBIU() * 2 ) *
1183  *aPad );
1184 
1185  // NOTE: the round segment width is the "diameter", so we double the thickness
1186 
1187  std::vector<const COBJECT2D *> *object2d_B = new std::vector<const COBJECT2D *>();
1188  object2d_B->push_back( innerSeg );
1189 
1190  CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( outerSeg,
1191  object2d_B,
1192  CSGITEM_FULL,
1193  *aPad );
1194 
1195  m_containerWithObjectsToDelete.Add( itemCSG2d );
1196  m_containerWithObjectsToDelete.Add( innerSeg );
1197  m_containerWithObjectsToDelete.Add( outerSeg );
1198 
1199  object2d_A = itemCSG2d;
1200  }
1201 
1202 
1203  if( object2d_A )
1204  {
1205  std::vector<const COBJECT2D *> *object2d_B = new std::vector<const COBJECT2D *>();
1206 
1207  // Check if there are any other THT that intersects this hole
1208  // It will use the non inflated holes
1209  if( !m_boardAdapter.GetThroughHole_Inner().GetList().empty() )
1210  {
1211 
1212  CONST_LIST_OBJECT2D intersectionList;
1214  intersectionList );
1215 
1216  if( !intersectionList.empty() )
1217  {
1218  for( CONST_LIST_OBJECT2D::const_iterator hole = intersectionList.begin();
1219  hole != intersectionList.end();
1220  ++hole )
1221  {
1222  const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*hole);
1223 
1224  if( object2d_A->Intersects( hole2d->GetBBox() ) )
1225  //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) )
1226  object2d_B->push_back( hole2d );
1227  }
1228  }
1229  }
1230 
1231  if( object2d_B->empty() )
1232  {
1233  delete object2d_B;
1234  object2d_B = CSGITEM_EMPTY;
1235  }
1236 
1237  if( object2d_B == CSGITEM_EMPTY )
1238  {
1239  CLAYERITEM *objPtr = new CLAYERITEM( object2d_A, topZ, botZ );
1240 
1241  objPtr->SetMaterial( &m_materials.m_Copper );
1242  objPtr->SetColor( ConvertSRGBToLinear( objColor ) );
1243  m_object_container.Add( objPtr );
1244  }
1245  else
1246  {
1247  CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( object2d_A,
1248  object2d_B,
1249  CSGITEM_FULL,
1250  (const BOARD_ITEM &)*aPad );
1251 
1252  m_containerWithObjectsToDelete.Add( itemCSG2d );
1253 
1254  CLAYERITEM *objPtr = new CLAYERITEM( itemCSG2d, topZ, botZ );
1255 
1256  objPtr->SetMaterial( &m_materials.m_Copper );
1257  objPtr->SetColor( ConvertSRGBToLinear( objColor ) );
1258 
1259  m_object_container.Add( objPtr );
1260  }
1261  }
1262 }
void GetListObjectsIntersects(const CBBOX2D &aBBox, CONST_LIST_OBJECT2D &aOutList) const override
GetListObjectsIntersects - Get a list of objects that intersects a bbox.
double BiuTo3Dunits() const noexcept
BiuTo3Dunits - Board integer units To 3D units.
bool GetFlag(DISPLAY3D_FLG aFlag) const
GetFlag - get a configuration status of a flag.
SFVEC3F ConvertSRGBToLinear(const SFVEC3F &aSRGBcolor)
multilayer pads, usually with holes
BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
wxPoint GetPosition() const override
Definition: class_pad.h:165
std::list< const COBJECT2D * > CONST_LIST_OBJECT2D
Definition: ccontainer2d.h:38
float GetCopperThickness3DU() const noexcept
GetCopperThickness3DU - Get the current copper layer thickness.
void SetMaterial(const CMATERIAL *aMaterial)
Definition: cobject.h:66
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:208
#define CSGITEM_EMPTY
This class is used to make constructive solig geometry for items objects on layers.
float GetLayerBottomZpos3DU(PCB_LAYER_ID aLayerId) const noexcept
GetLayerBottomZpos3DU - Get the bottom z position.
glm::vec2 SFVEC2F
Definition: xv3d_types.h:45
#define NULL
int GetCopperThicknessBIU() const noexcept
GetCopperThicknessBIU - Get the current copper layer thickness.
CCONTAINER2D m_containerWithObjectsToDelete
This will store the list of created objects special for RT, that will be clear in the end.
const CBVHCONTAINER2D & GetThroughHole_Inner() const noexcept
GetThroughHole_Inner - Get the ThroughHole container.
#define CSGITEM_FULL
void SetColor(SFVEC3F aObjColor)
Definition: clayeritem.h:46
void Add(COBJECT *aObject)
Definition: ccontainer.h:52
BOARD_ADAPTER & m_boardAdapter
settings refrence in use for this render
void Add(COBJECT2D *aObject)
Definition: ccontainer2d.h:52
struct C3D_RENDER_RAYTRACING::@3 m_materials
glm::vec3 SFVEC3F
Definition: xv3d_types.h:47
double GetOrientation() const
Function GetOrientation returns the rotation angle of the pad in tenths of degrees,...
Definition: class_pad.h:325
SFVEC3F GetItemColor(int aItemId) const
GetItemColor - get the technical color of a layer.
const wxSize & GetDrillSize() const
Definition: class_pad.h:230
SFVEC3D m_CopperColor
in realistic mode: copper color
const CBBOX2D & GetBBox() const
Definition: cobject2d.h:121
const LIST_OBJECT2D & GetList() const
Definition: ccontainer2d.h:64
virtual bool Intersects(const CBBOX2D &aBBox) const =0
Function Intersects.

References CGENERICCONTAINER2D::Add(), CGENERICCONTAINER::Add(), B_Cu, BOARD_ADAPTER::BiuTo3Dunits(), ConvertSRGBToLinear(), CSGITEM_EMPTY, CSGITEM_FULL, F_Cu, FL_USE_REALISTIC_MODE, COBJECT2D::GetBBox(), BOARD_ADAPTER::GetCopperThickness3DU(), BOARD_ADAPTER::GetCopperThicknessBIU(), D_PAD::GetDrillSize(), BOARD_ADAPTER::GetFlag(), BOARD_ADAPTER::GetItemColor(), BOARD_ADAPTER::GetLayerBottomZpos3DU(), CGENERICCONTAINER2D::GetList(), CBVHCONTAINER2D::GetListObjectsIntersects(), D_PAD::GetOrientation(), D_PAD::GetPosition(), BOARD_ADAPTER::GetThroughHole_Inner(), COBJECT2D::Intersects(), LAYER_PADS_TH, C3D_RENDER_BASE::m_boardAdapter, m_containerWithObjectsToDelete, BOARD_ADAPTER::m_CopperColor, m_materials, m_object_container, NULL, RotatePoint(), CLAYERITEM::SetColor(), COBJECT::SetMaterial(), wxPoint::x, and wxPoint::y.

Referenced by add_3D_vias_and_pads_to_container().

◆ insert3DViaHole()

void C3D_RENDER_RAYTRACING::insert3DViaHole ( const VIA aVia)
private

Definition at line 1067 of file c3d_render_createscene.cpp.

1068 {
1069  PCB_LAYER_ID top_layer, bottom_layer;
1070  int radiusBUI = (aVia->GetDrillValue() / 2);
1071 
1072  aVia->LayerPair( &top_layer, &bottom_layer );
1073 
1074  float topZ = m_boardAdapter.GetLayerBottomZpos3DU( top_layer ) +
1076 
1077  float botZ = m_boardAdapter.GetLayerBottomZpos3DU( bottom_layer ) -
1079 
1080  const SFVEC2F center = SFVEC2F( aVia->GetStart().x * m_boardAdapter.BiuTo3Dunits(),
1081  -aVia->GetStart().y * m_boardAdapter.BiuTo3Dunits() );
1082 
1083  CRING2D *ring = new CRING2D( center,
1084  radiusBUI * m_boardAdapter.BiuTo3Dunits(),
1085  ( radiusBUI + m_boardAdapter.GetCopperThicknessBIU() ) *
1087  *aVia );
1088 
1090 
1091 
1092  CLAYERITEM *objPtr = new CLAYERITEM( ring, topZ, botZ );
1093 
1094  objPtr->SetMaterial( &m_materials.m_Copper );
1095 
1098  else
1099  objPtr->SetColor( ConvertSRGBToLinear(
1100  m_boardAdapter.GetItemColor( LAYER_VIAS + static_cast<int>( aVia->GetViaType() ) ) ) );
1101 
1102  m_object_container.Add( objPtr );
1103 }
double BiuTo3Dunits() const noexcept
BiuTo3Dunits - Board integer units To 3D units.
bool GetFlag(DISPLAY3D_FLG aFlag) const
GetFlag - get a configuration status of a flag.
void LayerPair(PCB_LAYER_ID *top_layer, PCB_LAYER_ID *bottom_layer) const
Function LayerPair Return the 2 layers used by the via (the via actually uses all layers between thes...
SFVEC3F ConvertSRGBToLinear(const SFVEC3F &aSRGBcolor)
const wxPoint & GetStart() const
Definition: class_track.h:118
float GetCopperThickness3DU() const noexcept
GetCopperThickness3DU - Get the current copper layer thickness.
void SetMaterial(const CMATERIAL *aMaterial)
Definition: cobject.h:66
PCB_LAYER_ID
A quick note on layer IDs:
float GetLayerBottomZpos3DU(PCB_LAYER_ID aLayerId) const noexcept
GetLayerBottomZpos3DU - Get the bottom z position.
glm::vec2 SFVEC2F
Definition: xv3d_types.h:45
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
int GetCopperThicknessBIU() const noexcept
GetCopperThicknessBIU - Get the current copper layer thickness.
CCONTAINER2D m_containerWithObjectsToDelete
This will store the list of created objects special for RT, that will be clear in the end.
void SetColor(SFVEC3F aObjColor)
Definition: clayeritem.h:46
void Add(COBJECT *aObject)
Definition: ccontainer.h:52
BOARD_ADAPTER & m_boardAdapter
settings refrence in use for this render
void Add(COBJECT2D *aObject)
Definition: ccontainer2d.h:52
struct C3D_RENDER_RAYTRACING::@3 m_materials
glm::vec3 SFVEC3F
Definition: xv3d_types.h:47
SFVEC3F GetItemColor(int aItemId) const
GetItemColor - get the technical color of a layer.
SFVEC3D m_CopperColor
in realistic mode: copper color
VIATYPE GetViaType() const
Definition: class_track.h:378

References CGENERICCONTAINER2D::Add(), CGENERICCONTAINER::Add(), BOARD_ADAPTER::BiuTo3Dunits(), ConvertSRGBToLinear(), FL_USE_REALISTIC_MODE, BOARD_ADAPTER::GetCopperThickness3DU(), BOARD_ADAPTER::GetCopperThicknessBIU(), VIA::GetDrillValue(), BOARD_ADAPTER::GetFlag(), BOARD_ADAPTER::GetItemColor(), BOARD_ADAPTER::GetLayerBottomZpos3DU(), TRACK::GetStart(), VIA::GetViaType(), LAYER_VIAS, VIA::LayerPair(), C3D_RENDER_BASE::m_boardAdapter, m_containerWithObjectsToDelete, BOARD_ADAPTER::m_CopperColor, m_materials, m_object_container, CLAYERITEM::SetColor(), COBJECT::SetMaterial(), wxPoint::x, and wxPoint::y.

Referenced by add_3D_vias_and_pads_to_container().

◆ IsReloadRequestPending()

bool C3D_RENDER_BASE::IsReloadRequestPending ( ) const
inlineinherited

IsReloadRequestPending - Query if there is a pending reload request.

Returns
true if it wants to reload, false if there is no reload pending

Definition at line 82 of file c3d_render_base.h.

82 { return m_reloadRequested; }
bool m_reloadRequested
!TODO: this must be reviewed in order to flag change types

References C3D_RENDER_BASE::m_reloadRequested.

Referenced by EDA_3D_CANVAS::IsReloadRequestPending().

◆ load_3D_models()

void C3D_RENDER_RAYTRACING::load_3D_models ( )
private

Definition at line 1292 of file c3d_render_createscene.cpp.

1293 {
1294  // Go for all modules
1295  for( auto module : m_boardAdapter.GetBoard()->Modules() )
1296  {
1297  if((!module->Models().empty() ) &&
1298  m_boardAdapter.ShouldModuleBeDisplayed((MODULE_ATTR_T)module->GetAttributes() ) )
1299  {
1300  double zpos = m_boardAdapter.GetModulesZcoord3DIU( module->IsFlipped() );
1301 
1302  wxPoint pos = module->GetPosition();
1303 
1304  glm::mat4 moduleMatrix = glm::mat4( 1.0f );
1305 
1306  moduleMatrix = glm::translate( moduleMatrix,
1308  -pos.y * m_boardAdapter.BiuTo3Dunits(),
1309  zpos ) );
1310 
1311  if( module->GetOrientation() )
1312  {
1313  moduleMatrix = glm::rotate( moduleMatrix,
1314  ( (float)(module->GetOrientation() / 10.0f) / 180.0f ) *
1315  glm::pi<float>(),
1316  SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1317  }
1318 
1319 
1320  if( module->IsFlipped() )
1321  {
1322  moduleMatrix = glm::rotate( moduleMatrix,
1323  glm::pi<float>(),
1324  SFVEC3F( 0.0f, 1.0f, 0.0f ) );
1325 
1326  moduleMatrix = glm::rotate( moduleMatrix,
1327  glm::pi<float>(),
1328  SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1329  }
1330 
1331  const double modelunit_to_3d_units_factor = m_boardAdapter.BiuTo3Dunits() *
1333 
1334  moduleMatrix = glm::scale( moduleMatrix,
1335  SFVEC3F( modelunit_to_3d_units_factor,
1336  modelunit_to_3d_units_factor,
1337  modelunit_to_3d_units_factor ) );
1338 
1339 
1340  // Get the list of model files for this model
1342  auto sM = module->Models().begin();
1343  auto eM = module->Models().end();
1344 
1345  while( sM != eM )
1346  {
1347  if( ( static_cast<float>( sM->m_Opacity ) > FLT_EPSILON ) &&
1348  ( sM->m_Show && !sM->m_Filename.empty() ) )
1349  {
1350  // get it from cache
1351  const S3DMODEL *modelPtr = cacheMgr->GetModel( sM->m_Filename );
1352 
1353  // only add it if the return is not NULL
1354  if( modelPtr )
1355  {
1356  glm::mat4 modelMatrix = moduleMatrix;
1357 
1358  modelMatrix = glm::translate( modelMatrix,
1359  SFVEC3F( sM->m_Offset.x,
1360  sM->m_Offset.y,
1361  sM->m_Offset.z ) );
1362 
1363  modelMatrix = glm::rotate( modelMatrix,
1364  (float)-( sM->m_Rotation.z / 180.0f ) *
1365  glm::pi<float>(),
1366  SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1367 
1368  modelMatrix = glm::rotate( modelMatrix,
1369  (float)-( sM->m_Rotation.y / 180.0f ) *
1370  glm::pi<float>(),
1371  SFVEC3F( 0.0f, 1.0f, 0.0f ) );
1372 
1373  modelMatrix = glm::rotate( modelMatrix,
1374  (float)-( sM->m_Rotation.x / 180.0f ) *
1375  glm::pi<float>(),
1376  SFVEC3F( 1.0f, 0.0f, 0.0f ) );
1377 
1378  modelMatrix = glm::scale( modelMatrix,
1379  SFVEC3F( sM->m_Scale.x,
1380  sM->m_Scale.y,
1381  sM->m_Scale.z ) );
1382 
1383  add_3D_models( modelPtr, modelMatrix, (float)sM->m_Opacity );
1384  }
1385  }
1386 
1387  ++sM;
1388  }
1389  }
1390  }
1391 }
double BiuTo3Dunits() const noexcept
BiuTo3Dunits - Board integer units To 3D units.
S3D_CACHE.
Definition: 3d_cache.h:54
#define UNITS3D_TO_UNITSPCB
Scale convertion from 3d model units to pcb units.
S3DMODEL * GetModel(const wxString &aModelFileName)
Function GetModel attempts to load the scene data for a model and to translate it into an S3D_MODEL s...
Definition: 3d_cache.cpp:654
MODULES & Modules()
Definition: class_board.h:266
S3D_CACHE * Get3DCacheManager() const noexcept
Get3DCacheManager - Return the 3d cache manager pointer.
Definition: board_adapter.h:89
const BOARD * GetBoard() const noexcept
GetBoard - Get current board to be rendered.
MODULE_ATTR_T
Enum MODULE_ATTR_T is the set of attributes allowed within a MODULE, using MODULE::SetAttributes() an...
Definition: class_module.h:65
BOARD_ADAPTER & m_boardAdapter
settings refrence in use for this render
const int scale
bool ShouldModuleBeDisplayed(MODULE_ATTR_T aModuleAttributs) const
ShouldModuleBeDisplayed - Test if module should be displayed in relation to attributs and the flags.
glm::vec3 SFVEC3F
Definition: xv3d_types.h:47
void add_3D_models(const S3DMODEL *a3DModel, const glm::mat4 &aModelMatrix, float aModuleOpacity)
float GetModulesZcoord3DIU(bool aIsFlipped) const
GetModulesZcoord3DIU - Get the position of the module in 3d integer units considering if it is flippe...
Store the a model based on meshes and materials.
Definition: c3dmodel.h:90

References add_3D_models(), BOARD_ADAPTER::BiuTo3Dunits(), BOARD_ADAPTER::Get3DCacheManager(), BOARD_ADAPTER::GetBoard(), S3D_CACHE::GetModel(), BOARD_ADAPTER::GetModulesZcoord3DIU(), C3D_RENDER_BASE::m_boardAdapter, BOARD::Modules(), scale, BOARD_ADAPTER::ShouldModuleBeDisplayed(), UNITS3D_TO_UNITSPCB, wxPoint::x, and wxPoint::y.

Referenced by reload().

◆ opengl_delete_pbo()

void C3D_RENDER_RAYTRACING::opengl_delete_pbo ( )
private

Definition at line 101 of file c3d_render_raytracing.cpp.

102 {
103  // Delete PBO if it was created
105  {
106  if( glIsBufferARB( m_pboId ) )
107  glDeleteBuffers( 1, &m_pboId );
108 
109  m_pboId = GL_NONE;
110  }
111 }

References m_opengl_support_vertex_buffer_object, and m_pboId.

Referenced by opengl_init_pbo(), and ~C3D_RENDER_RAYTRACING().

◆ opengl_init_pbo()

void C3D_RENDER_RAYTRACING::opengl_init_pbo ( )
private

Definition at line 1978 of file c3d_render_raytracing.cpp.

1979 {
1980  if( GLEW_ARB_pixel_buffer_object )
1981  {
1983 
1984  // Try to delete vbo if it was already initialized
1986 
1987  // Learn about Pixel buffer objects at:
1988  // http://www.songho.ca/opengl/gl_pbo.html
1989  // http://web.eecs.umich.edu/~sugih/courses/eecs487/lectures/25-PBO+Mipmapping.pdf
1990  // "create 2 pixel buffer objects, you need to delete them when program exits.
1991  // glBufferDataARB with NULL pointer reserves only memory space."
1992 
1993  // This sets the number of RGBA pixels
1995 
1996  glGenBuffersARB( 1, &m_pboId );
1997  glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboId );
1998  glBufferDataARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboDataSize, 0, GL_STREAM_DRAW_ARB );
1999  glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, 0 );
2000 
2001  wxLogTrace( m_logTrace,
2002  wxT( "C3D_RENDER_RAYTRACING:: GLEW_ARB_pixel_buffer_object is supported" ) );
2003  }
2004 }
static const wxChar * m_logTrace
Trace mask used to enable or disable the trace output of this class.

References C3D_RENDER_BASE::m_logTrace, m_opengl_support_vertex_buffer_object, m_pboDataSize, m_pboId, m_realBufferSize, and opengl_delete_pbo().

Referenced by initialize_block_positions(), and initializeNewWindowSize().

◆ Redraw()

bool C3D_RENDER_RAYTRACING::Redraw ( bool  aIsMoving,
REPORTER aStatusReporter,
REPORTER aWarningReporter 
)
overridevirtual

Redraw - Ask to redraw the view.

Parameters
aIsMovingif the user is moving the scene, it should be render in preview mode
aStatusReportera pointer to the status progress reporter
Returns
it will return true if the render would like to redraw again

Implements C3D_RENDER_BASE.

Definition at line 150 of file c3d_render_raytracing.cpp.

152 {
153  bool requestRedraw = false;
154 
155  // Initialize openGL if need
156  // /////////////////////////////////////////////////////////////////////////
158  {
159  if( !initializeOpenGL() )
160  return false;
161 
162  //aIsMoving = true;
163  requestRedraw = true;
164 
165  // It will assign the first time the windows size, so it will now
166  // revert to preview mode the first time the Redraw is called
169  }
170 
171  std::unique_ptr<BUSY_INDICATOR> busy = CreateBusyIndicator();
172 
173  // Reload board if it was requested
174  // /////////////////////////////////////////////////////////////////////////
175  if( m_reloadRequested )
176  {
177  if( aStatusReporter )
178  aStatusReporter->Report( _( "Loading..." ) );
179 
180  //aIsMoving = true;
181  requestRedraw = true;
182  reload( aStatusReporter, aWarningReporter );
183  }
184 
185 
186  // Recalculate constants if windows size was changed
187  // /////////////////////////////////////////////////////////////////////////
189  {
191  aIsMoving = true;
192  requestRedraw = true;
193 
195  }
196 
197 
198  // Clear buffers
199  // /////////////////////////////////////////////////////////////////////////
200  glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
201  glClearDepth( 1.0f );
202  glClearStencil( 0x00 );
203  glClear( GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
204 
205  // 4-byte pixel alignment
206  glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
207 
208  glDisable( GL_STENCIL_TEST );
209  glDisable( GL_LIGHTING );
210  glDisable( GL_COLOR_MATERIAL );
211  glDisable( GL_DEPTH_TEST );
212  glDisable( GL_TEXTURE_2D );
213  glDisable( GL_BLEND );
214  glDisable( GL_MULTISAMPLE );
215 
216  const bool was_camera_changed = m_camera.ParametersChanged();
217 
218  if( requestRedraw || aIsMoving || was_camera_changed )
219  m_rt_render_state = RT_RENDER_STATE_MAX; // Set to an invalid state,
220  // so it will restart again latter
221 
222 
223  // This will only render if need, otherwise it will redraw the PBO on the screen again
224  if( aIsMoving || was_camera_changed )
225  {
226  // Set head light (camera view light) with the oposite direction of the camera
227  if( m_camera_light )
229 
232 
233  // Bind PBO
234  glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboId );
235 
236  // Get the PBO pixel pointer to write the data
237  GLubyte *ptrPBO = (GLubyte *)glMapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB,
238  GL_WRITE_ONLY_ARB );
239 
240  if( ptrPBO )
241  {
242  render_preview( ptrPBO );
243 
244  // release pointer to mapping buffer, this initialize the coping to PBO
245  glUnmapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB );
246  }
247 
248  glWindowPos2i( m_xoffset, m_yoffset );
249  }
250  else
251  {
252  // Bind PBO
253  glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboId );
254 
256  {
257  // Get the PBO pixel pointer to write the data
258  GLubyte *ptrPBO = (GLubyte *)glMapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB,
259  GL_WRITE_ONLY_ARB );
260 
261  if( ptrPBO )
262  {
263  render( ptrPBO, aStatusReporter );
264 
266  requestRedraw = true;
267 
268  // release pointer to mapping buffer, this initialize the coping to PBO
269  glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);
270  }
271  }
272 
274  {
275  glClear( GL_COLOR_BUFFER_BIT );
276  // Options if we want draw background instead
277  //OGL_DrawBackground( SFVEC3F(m_boardAdapter.m_BgColorTop),
278  // SFVEC3F(m_boardAdapter.m_BgColorBot) );
279  }
280 
281  glWindowPos2i( m_xoffset, m_yoffset );
282  }
283 
284  // This way it will blend the progress rendering with the last buffer. eg:
285  // if it was called after a openGL.
286  glEnable( GL_BLEND );
287  glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
288  glEnable( GL_ALPHA_TEST );
289 
290  glDrawPixels( m_realBufferSize.x,
292  GL_RGBA,
293  GL_UNSIGNED_BYTE,
294  0 );
295 
296  glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, 0 );
297 
298  return requestRedraw;
299 }
wxSize m_oldWindowsSize
used to see if the windows size changed
const SFVEC3F & GetDir() const
Definition: ccamera.h:112
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Function Report is a pure virtual function to override in the derived object.
SFVEC3D m_BgColorTop
background top color
void OGL_DrawBackground(const SFVEC3F &aTopColor, const SFVEC3F &aBotColor)
OGL_DrawBackground.
Definition: ogl_utils.cpp:184
bool m_is_opengl_initialized
flag if the opengl specific for this render was already initialized
RT_RENDER_STATE m_rt_render_state
State used on quality render.
wxSize m_windowSize
The window size that this camera is working.
std::unique_ptr< BUSY_INDICATOR > CreateBusyIndicator() const
Return a created busy indicator, if a factory has been set, else a null pointer.
CDIRECTIONALLIGHT * m_camera_light
void render(GLubyte *ptrPBO, REPORTER *aStatusReporter)
SFVEC3D m_BgColorBot
background bottom color
BOARD_ADAPTER & m_boardAdapter
settings refrence in use for this render
void SetDirection(const SFVEC3F &aDir)
SetDirection - Set directional light orientation.
Definition: clight.h:129
bool m_reloadRequested
!TODO: this must be reviewed in order to flag change types
#define _(s)
Definition: 3d_actions.cpp:33
glm::vec3 SFVEC3F
Definition: xv3d_types.h:47
void reload(REPORTER *aStatusReporter, REPORTER *aWarningReporter)
void render_preview(GLubyte *ptrPBO)
bool ParametersChanged()
Function ParametersChanged.
Definition: ccamera.cpp:587

References _, C3D_RENDER_BASE::CreateBusyIndicator(), CCAMERA::GetDir(), initialize_block_positions(), initializeOpenGL(), BOARD_ADAPTER::m_BgColorBot, BOARD_ADAPTER::m_BgColorTop, C3D_RENDER_BASE::m_boardAdapter, C3D_RENDER_BASE::m_camera, m_camera_light, C3D_RENDER_BASE::m_is_opengl_initialized, m_oldWindowsSize, m_pboId, m_realBufferSize, C3D_RENDER_BASE::m_reloadRequested, m_rt_render_state, C3D_RENDER_BASE::m_windowSize, m_xoffset, m_yoffset, OGL_DrawBackground(), CCAMERA::ParametersChanged(), reload(), render(), render_preview(), REPORTER::Report(), RT_RENDER_STATE_FINISH, RT_RENDER_STATE_MAX, and CDIRECTIONALLIGHT::SetDirection().

◆ reload()

void C3D_RENDER_RAYTRACING::reload ( REPORTER aStatusReporter,
REPORTER aWarningReporter 
)
private

Definition at line 260 of file c3d_render_createscene.cpp.

261 {
262  m_reloadRequested = false;
263 
264  m_model_materials.clear();
265 
268 
269 #ifdef PRINT_STATISTICS_3D_VIEWER
270  printf("InitSettings...\n");
271 #endif
272 
273  unsigned stats_startReloadTime = GetRunningMicroSecs();
274 
275  m_boardAdapter.InitSettings( aStatusReporter, aWarningReporter );
276 
277 #ifdef PRINT_STATISTICS_3D_VIEWER
278  unsigned stats_endReloadTime = GetRunningMicroSecs();
279  unsigned stats_startConvertTime = GetRunningMicroSecs();
280  #endif
281 
283  m_camera.SetBoardLookAtPos( camera_pos );
284 
287 
288  setupMaterials();
289 
290  // Create and add the outline board
291  // /////////////////////////////////////////////////////////////////////////
292 
293 #ifdef PRINT_STATISTICS_3D_VIEWER
294  printf("Create outline board...\n");
295 #endif
296 
298 
300 
301  const int outlineCount = m_boardAdapter.GetBoardPoly().OutlineCount();
302 
303  if( outlineCount > 0 )
304  {
305  float divFactor = 0.0f;
306 
309  else
311  divFactor = m_boardAdapter.GetStats_Med_Hole_Diameter3DU() * 8.0f;
312 
313  SHAPE_POLY_SET boardPolyCopy = m_boardAdapter.GetBoardPoly();
314  boardPolyCopy.Fracture( SHAPE_POLY_SET::PM_FAST );
315 
316  for( int iOutlinePolyIdx = 0; iOutlinePolyIdx < outlineCount; iOutlinePolyIdx++ )
317  {
319  boardPolyCopy,
322  divFactor,
323  *dynamic_cast<const BOARD_ITEM*>( m_boardAdapter.GetBoard() ),
324  iOutlinePolyIdx );
325  }
326 
328  {
329  const LIST_OBJECT2D &listObjects = m_outlineBoard2dObjects->GetList();
330 
331  for( LIST_OBJECT2D::const_iterator object2d_iterator = listObjects.begin();
332  object2d_iterator != listObjects.end();
333  ++object2d_iterator )
334  {
335  const COBJECT2D *object2d_A = static_cast<const COBJECT2D *>(*object2d_iterator);
336 
337  std::vector<const COBJECT2D *> *object2d_B = new std::vector<const COBJECT2D *>();
338 
339  // Check if there are any THT that intersects this outline object part
340  if( !m_boardAdapter.GetThroughHole_Outer().GetList().empty() )
341  {
342 
343  CONST_LIST_OBJECT2D intersectionList;
345  object2d_A->GetBBox(),
346  intersectionList );
347 
348  if( !intersectionList.empty() )
349  {
350  for( CONST_LIST_OBJECT2D::const_iterator hole = intersectionList.begin();
351  hole != intersectionList.end();
352  ++hole )
353  {
354  const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*hole);
355 
356  if( object2d_A->Intersects( hole2d->GetBBox() ) )
357  //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) )
358  object2d_B->push_back( hole2d );
359  }
360  }
361  }
362 
363  if( object2d_B->empty() )
364  {
365  delete object2d_B;
366  object2d_B = CSGITEM_EMPTY;
367  }
368 
369  if( object2d_B == CSGITEM_EMPTY )
370  {
371  #if 0
375  &m_materials.m_EpoxyBoard,
376  g_epoxyColor );
377  #else
378  CLAYERITEM *objPtr = new CLAYERITEM( object2d_A,
381 
382  objPtr->SetMaterial( &m_materials.m_EpoxyBoard );
384  m_object_container.Add( objPtr );
385  #endif
386  }
387  else
388  {
389  CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D(
390  object2d_A,
391  object2d_B,
392  CSGITEM_FULL,
393  (const BOARD_ITEM &)*m_boardAdapter.GetBoard() );
394 
395  m_containerWithObjectsToDelete.Add( itemCSG2d );
396 
397  CLAYERITEM *objPtr = new CLAYERITEM( itemCSG2d,
400 
401  objPtr->SetMaterial( &m_materials.m_EpoxyBoard );
403  m_object_container.Add( objPtr );
404  }
405  }
406 
407  // Add cylinders of the board body to container
408  // Note: This is actually a workarround for the holes in the board.
409  // The issue is because if a hole is in a border of a divided polygon ( ex
410  // a polygon or dummyblock) it will cut also the render of the hole.
411  // So this will add a full hole.
412  // In fact, that is not need if the hole have copper.
413  // /////////////////////////////////////////////////////////////////////////
414  if( !m_boardAdapter.GetThroughHole_Outer().GetList().empty() )
415  {
417 
418  for( LIST_OBJECT2D::const_iterator hole = holeList.begin();
419  hole != holeList.end();
420  ++hole )
421  {
422  const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*hole);
423 
424  switch( hole2d->GetObjectType() )
425  {
427  {
428  const float radius = hole2d->GetBBox().GetExtent().x * 0.5f * 0.999f;
429 
430  CVCYLINDER *objPtr = new CVCYLINDER(
431  hole2d->GetCentroid(),
434  radius );
435 
436  objPtr->SetMaterial( &m_materials.m_EpoxyBoard );
438 
439  m_object_container.Add( objPtr );
440  }
441  break;
442 
443  default:
444  break;
445  }
446  }
447  }
448  }
449  }
450 
451 
452  // Add layers maps (except B_Mask and F_Mask)
453  // /////////////////////////////////////////////////////////////////////////
454 
455 #ifdef PRINT_STATISTICS_3D_VIEWER
456  printf("Add layers maps...\n");
457 #endif
458 
459  for( MAP_CONTAINER_2D::const_iterator ii = m_boardAdapter.GetMapLayers().begin();
460  ii != m_boardAdapter.GetMapLayers().end();
461  ++ii )
462  {
463  PCB_LAYER_ID layer_id = static_cast<PCB_LAYER_ID>(ii->first);
464 
465  // Mask kayers are not processed here because they are a special case
466  if( (layer_id == B_Mask) || (layer_id == F_Mask) )
467  continue;
468 
469  CMATERIAL *materialLayer = &m_materials.m_SilkS;
470  SFVEC3F layerColor = SFVEC3F( 0.0f, 0.0f, 0.0f );
471 
472  switch( layer_id )
473  {
474  case B_Adhes:
475  case F_Adhes:
476  break;
477 
478  case B_Paste:
479  case F_Paste:
480  materialLayer = &m_materials.m_Paste;
481 
483  layerColor = m_boardAdapter.m_SolderPasteColor;
484  else
485  layerColor = m_boardAdapter.GetLayerColor( layer_id );
486  break;
487 
488  case B_SilkS:
489  materialLayer = &m_materials.m_SilkS;
490 
493  else
494  layerColor = m_boardAdapter.GetLayerColor( layer_id );
495  break;
496  case F_SilkS:
497  materialLayer = &m_materials.m_SilkS;
498 
501  else
502  layerColor = m_boardAdapter.GetLayerColor( layer_id );
503  break;
504 
505  case Dwgs_User:
506  case Cmts_User:
507  case Eco1_User:
508  case Eco2_User:
509  case Edge_Cuts:
510  case Margin:
511  break;
512 
513  case B_CrtYd:
514  case F_CrtYd:
515  break;
516 
517  case B_Fab:
518  case F_Fab:
519  break;
520 
521  default:
522  materialLayer = &m_materials.m_Copper;
523 
525  layerColor = m_boardAdapter.m_CopperColor;
526  else
527  layerColor = m_boardAdapter.GetLayerColor( layer_id );
528  break;
529  }
530 
531  const CBVHCONTAINER2D *container2d = static_cast<const CBVHCONTAINER2D *>(ii->second);
532  const LIST_OBJECT2D &listObject2d = container2d->GetList();
533 
534  for( LIST_OBJECT2D::const_iterator itemOnLayer = listObject2d.begin();
535  itemOnLayer != listObject2d.end();
536  ++itemOnLayer )
537  {
538  const COBJECT2D *object2d_A = static_cast<const COBJECT2D *>(*itemOnLayer);
539 
540  // not yet used / implemented (can be used in future to clip the objects in the board borders
541  COBJECT2D *object2d_C = CSGITEM_FULL;
542 
543  std::vector<const COBJECT2D *> *object2d_B = CSGITEM_EMPTY;
544 
545  object2d_B = new std::vector<const COBJECT2D*>();
546 
547  // Subtract holes but not in SolderPaste
548  // (can be added as an option in future)
549  if( !( ( layer_id == B_Paste ) || ( layer_id == F_Paste ) ) )
550  {
551  // Check if there are any layerhole that intersects this object
552  // Eg: a segment is cutted by a via hole or THT hole.
553  // /////////////////////////////////////////////////////////////
554  const MAP_CONTAINER_2D &layerHolesMap = m_boardAdapter.GetMapLayersHoles();
555 
556  if( layerHolesMap.find(layer_id) != layerHolesMap.end() )
557  {
558  MAP_CONTAINER_2D::const_iterator ii_hole = layerHolesMap.find(layer_id);
559 
560  const CBVHCONTAINER2D *containerLayerHoles2d =
561  static_cast<const CBVHCONTAINER2D *>(ii_hole->second);
562 
563  CONST_LIST_OBJECT2D intersectionList;
564  containerLayerHoles2d->GetListObjectsIntersects( object2d_A->GetBBox(),
565  intersectionList );
566 
567  if( !intersectionList.empty() )
568  {
569  for( CONST_LIST_OBJECT2D::const_iterator holeOnLayer =
570  intersectionList.begin();
571  holeOnLayer != intersectionList.end();
572  ++holeOnLayer )
573  {
574  const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*holeOnLayer);
575 
576  //if( object2d_A->Intersects( hole2d->GetBBox() ) )
577  //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) )
578  object2d_B->push_back( hole2d );
579  }
580  }
581  }
582 
583  // Check if there are any THT that intersects this object
584  // /////////////////////////////////////////////////////////////
585 
586  // If we're processing a silk screen layer and the flag is set, then
587  // clip the silk screening at the outer edge of the annular ring, rather
588  // than the at the outer edge of the copper plating.
589  const CBVHCONTAINER2D& throughHoleOuter =
591  && ( ( layer_id == B_SilkS ) || ( layer_id == F_SilkS ) ) ) ?
594 
595  if( !throughHoleOuter.GetList().empty() )
596  {
597  CONST_LIST_OBJECT2D intersectionList;
598 
599  throughHoleOuter.GetListObjectsIntersects(
600  object2d_A->GetBBox(), intersectionList );
601 
602  if( !intersectionList.empty() )
603  {
604  for( CONST_LIST_OBJECT2D::const_iterator hole = intersectionList.begin();
605  hole != intersectionList.end();
606  ++hole )
607  {
608  const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*hole);
609 
610  //if( object2d_A->Intersects( hole2d->GetBBox() ) )
611  //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) )
612  object2d_B->push_back( hole2d );
613  }
614  }
615  }
616  }
617 
618 
619  const MAP_CONTAINER_2D& mapLayers = m_boardAdapter.GetMapLayers();
620 
622  ( ( ( layer_id == B_SilkS ) &&
623  ( mapLayers.find( B_Mask ) != mapLayers.end() ) ) ||
624  ( ( layer_id == F_SilkS ) &&
625  ( mapLayers.find( F_Mask ) != mapLayers.end() ) ) ) )
626  {
627  const PCB_LAYER_ID layerMask_id = ( layer_id == B_SilkS ) ? B_Mask : F_Mask;
628 
629  const CBVHCONTAINER2D *containerMaskLayer2d =
630  static_cast<const CBVHCONTAINER2D*>( mapLayers.at( layerMask_id ) );
631 
632  CONST_LIST_OBJECT2D intersectionList;
633 
634  if( containerMaskLayer2d ) // can be null if B_Mask or F_Mask is not shown
635  containerMaskLayer2d->GetListObjectsIntersects( object2d_A->GetBBox(),
636  intersectionList );
637 
638  if( !intersectionList.empty() )
639  {
640  for( CONST_LIST_OBJECT2D::const_iterator objOnLayer =
641  intersectionList.begin();
642  objOnLayer != intersectionList.end();
643  ++objOnLayer )
644  {
645  const COBJECT2D* obj2d = static_cast<const COBJECT2D*>( *objOnLayer );
646 
647  object2d_B->push_back( obj2d );
648  }
649  }
650  }
651 
652  if( object2d_B->empty() )
653  {
654  delete object2d_B;
655  object2d_B = CSGITEM_EMPTY;
656  }
657 
658  if( (object2d_B == CSGITEM_EMPTY) &&
659  (object2d_C == CSGITEM_FULL) )
660  {
661 #if 0
663  object2d_A,
666  materialLayer,
667  layerColor );
668 #else
669  CLAYERITEM *objPtr = new CLAYERITEM( object2d_A,
671  m_boardAdapter.GetLayerTopZpos3DU( layer_id ) );
672  objPtr->SetMaterial( materialLayer );
673  objPtr->SetColor( ConvertSRGBToLinear( layerColor ) );
674  m_object_container.Add( objPtr );
675 #endif
676  }
677  else
678  {
679 #if 1
680  CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( object2d_A,
681  object2d_B,
682  object2d_C,
683  object2d_A->GetBoardItem() );
684  m_containerWithObjectsToDelete.Add( itemCSG2d );
685 
686  CLAYERITEM *objPtr = new CLAYERITEM( itemCSG2d,
688  m_boardAdapter.GetLayerTopZpos3DU( layer_id ) );
689 
690  objPtr->SetMaterial( materialLayer );
691  objPtr->SetColor( ConvertSRGBToLinear( layerColor ) );
692 
693  m_object_container.Add( objPtr );
694 #endif
695  }
696  }
697  }// for each layer on map
698 
699 
700 
701  // Add Mask layer
702  // Solder mask layers are "negative" layers so the elements that we have
703  // (in the container) should remove the board outline.
704  // We will check for all objects in the outline if it intersects any object
705  // in the layer container and also any hole.
706  // /////////////////////////////////////////////////////////////////////////
708  (m_outlineBoard2dObjects->GetList().size() >= 1) )
709  {
710  const CMATERIAL *materialLayer = &m_materials.m_SolderMask;
711 
712  for( MAP_CONTAINER_2D::const_iterator ii = m_boardAdapter.GetMapLayers().begin();
713  ii != m_boardAdapter.GetMapLayers().end();
714  ++ii )
715  {
716  PCB_LAYER_ID layer_id = static_cast<PCB_LAYER_ID>(ii->first);
717 
718  const CBVHCONTAINER2D *containerLayer2d =
719  static_cast<const CBVHCONTAINER2D *>(ii->second);
720 
721  // Only get the Solder mask layers
722  if( !((layer_id == B_Mask) || (layer_id == F_Mask)) )
723  continue;
724 
725  SFVEC3F layerColor;
727  {
728  if( layer_id == B_Mask )
730  else
732  }
733  else
734  layerColor = m_boardAdapter.GetLayerColor( layer_id );
735 
736  const float zLayerMin = m_boardAdapter.GetLayerBottomZpos3DU( layer_id );
737  const float zLayerMax = m_boardAdapter.GetLayerTopZpos3DU( layer_id );
738 
739  // Get the outline board objects
740  const LIST_OBJECT2D &listObjects = m_outlineBoard2dObjects->GetList();
741 
742  for( LIST_OBJECT2D::const_iterator object2d_iterator = listObjects.begin();
743  object2d_iterator != listObjects.end();
744  ++object2d_iterator )
745  {
746  const COBJECT2D *object2d_A = static_cast<const COBJECT2D *>(*object2d_iterator);
747 
748  std::vector<const COBJECT2D *> *object2d_B = new std::vector<const COBJECT2D *>();
749 
750  // Check if there are any THT that intersects this outline object part
751  if( !m_boardAdapter.GetThroughHole_Outer().GetList().empty() )
752  {
753 
754  CONST_LIST_OBJECT2D intersectionList;
755 
757  object2d_A->GetBBox(),
758  intersectionList );
759 
760  if( !intersectionList.empty() )
761  {
762  for( CONST_LIST_OBJECT2D::const_iterator hole = intersectionList.begin();
763  hole != intersectionList.end();
764  ++hole )
765  {
766  const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*hole);
767 
768  if( object2d_A->Intersects( hole2d->GetBBox() ) )
769  //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) )
770  object2d_B->push_back( hole2d );
771  }
772  }
773  }
774 
775  // Check if there are any objects in the layer to subtract with the
776  // corrent object
777  if( !containerLayer2d->GetList().empty() )
778  {
779  CONST_LIST_OBJECT2D intersectionList;
780 
781  containerLayer2d->GetListObjectsIntersects( object2d_A->GetBBox(),
782  intersectionList );
783 
784  if( !intersectionList.empty() )
785  {
786  for( CONST_LIST_OBJECT2D::const_iterator obj = intersectionList.begin();
787  obj != intersectionList.end();
788  ++obj )
789  {
790  const COBJECT2D *obj2d = static_cast<const COBJECT2D *>(*obj);
791 
792  //if( object2d_A->Intersects( obj2d->GetBBox() ) )
793  //if( object2d_A->GetBBox().Intersects( obj2d->GetBBox() ) )
794  object2d_B->push_back( obj2d );
795  }
796  }
797  }
798 
799  if( object2d_B->empty() )
800  {
801  delete object2d_B;
802  object2d_B = CSGITEM_EMPTY;
803  }
804 
805  if( object2d_B == CSGITEM_EMPTY )
806  {
807  #if 0
809  object2d_A,
810  zLayerMin,
811  zLayerMax,
812  materialLayer,
813  layerColor );
814  #else
815  CLAYERITEM *objPtr = new CLAYERITEM( object2d_A,
816  zLayerMin,
817  zLayerMax );
818 
819  objPtr->SetMaterial( materialLayer );
820  objPtr->SetColor( ConvertSRGBToLinear( layerColor ) );
821 
822  m_object_container.Add( objPtr );
823  #endif
824  }
825  else
826  {
827  CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( object2d_A,
828  object2d_B,
829  CSGITEM_FULL,
830  object2d_A->GetBoardItem() );
831 
832  m_containerWithObjectsToDelete.Add( itemCSG2d );
833 
834  CLAYERITEM *objPtr = new CLAYERITEM( itemCSG2d,
835  zLayerMin,
836  zLayerMax );
837  objPtr->SetMaterial( materialLayer );
838  objPtr->SetColor( ConvertSRGBToLinear( layerColor ) );
839 
840  m_object_container.Add( objPtr );
841  }
842  }
843  }
844  }
845 
847 
848 #ifdef PRINT_STATISTICS_3D_VIEWER
849  unsigned stats_endConvertTime = GetRunningMicroSecs();
850  unsigned stats_startLoad3DmodelsTime = stats_endConvertTime;
851 #endif
852 
853 
854  load_3D_models();
855 
856 
857 #ifdef PRINT_STATISTICS_3D_VIEWER
858  unsigned stats_endLoad3DmodelsTime = GetRunningMicroSecs();
859 #endif
860 
861  // Add floor
862  // /////////////////////////////////////////////////////////////////////////
864  {
865  CBBOX boardBBox = m_boardAdapter.GetBBox3DU();
866 
867  if( boardBBox.IsInitialized() )
868  {
869  boardBBox.Scale( 3.0f );
870 
871  if( m_object_container.GetList().size() > 0 )
872  {
873  CBBOX containerBBox = m_object_container.GetBBox();
874 
875  containerBBox.Scale( 1.3f );
876 
877  const SFVEC3F centerBBox = containerBBox.GetCenter();
878 
879  // Floor triangles
880  const float minZ = glm::min( containerBBox.Min().z,
881  boardBBox.Min().z );
882 
883  const SFVEC3F v1 = SFVEC3F( -RANGE_SCALE_3D * 4.0f,
884  -RANGE_SCALE_3D * 4.0f,
885  minZ ) +
886  SFVEC3F( centerBBox.x,
887  centerBBox.y,
888  0.0f );
889 
890  const SFVEC3F v3 = SFVEC3F( +RANGE_SCALE_3D * 4.0f,
891  +RANGE_SCALE_3D * 4.0f,
892  minZ ) +
893  SFVEC3F( centerBBox.x,
894  centerBBox.y,
895  0.0f );
896 
897  const SFVEC3F v2 = SFVEC3F( v1.x, v3.y, v1.z );
898  const SFVEC3F v4 = SFVEC3F( v3.x, v1.y, v1.z );
899 
900  SFVEC3F backgroundColor =
901  ConvertSRGBToLinear( static_cast<SFVEC3F>( m_boardAdapter.m_BgColorTop ) );
902 
903  CTRIANGLE *newTriangle1 = new CTRIANGLE( v1, v2, v3 );
904  CTRIANGLE *newTriangle2 = new CTRIANGLE( v3, v4, v1 );
905 
906  m_object_container.Add( newTriangle1 );
907  m_object_container.Add( newTriangle2 );
908 
909  newTriangle1->SetMaterial( (const CMATERIAL *)&m_materials.m_Floor );
910  newTriangle2->SetMaterial( (const CMATERIAL *)&m_materials.m_Floor );
911 
912  newTriangle1->SetColor( backgroundColor );
913  newTriangle2->SetColor( backgroundColor );
914 
915  // Ceiling triangles
916  const float maxZ = glm::max( containerBBox.Max().z,
917  boardBBox.Max().z );
918 
919  const SFVEC3F v5 = SFVEC3F( v1.x, v1.y, maxZ );
920  const SFVEC3F v6 = SFVEC3F( v2.x, v2.y, maxZ );
921  const SFVEC3F v7 = SFVEC3F( v3.x, v3.y, maxZ );
922  const SFVEC3F v8 = SFVEC3F( v4.x, v4.y, maxZ );
923 
924  CTRIANGLE *newTriangle3 = new CTRIANGLE( v7, v6, v5 );
925  CTRIANGLE *newTriangle4 = new CTRIANGLE( v5, v8, v7 );
926 
927  m_object_container.Add( newTriangle3 );
928  m_object_container.Add( newTriangle4 );
929 
930  newTriangle3->SetMaterial( (const CMATERIAL *)&m_materials.m_Floor );
931  newTriangle4->SetMaterial( (const CMATERIAL *)&m_materials.m_Floor );
932 
933  newTriangle3->SetColor( backgroundColor );
934  newTriangle4->SetColor( backgroundColor );
935  }
936  }
937  }
938 
939 
940  // Init initial lights
941  // /////////////////////////////////////////////////////////////////////////
942  m_lights.Clear();
943 
944  // This will work as the front camera light.
945  const float light_camera_intensity = 0.20f;
946  const float light_top_bottom = 0.25f;
947  const float light_directional_intensity = ( 1.0f - ( light_camera_intensity +
948  light_top_bottom * 0.5f ) ) / 4.0f;
949 
950  m_camera_light = new CDIRECTIONALLIGHT( SFVEC3F( 0.0f, 0.0f, 0.0f ),
951  SFVEC3F( light_camera_intensity ) );
952  m_camera_light->SetCastShadows( false );
954 
955  // Option 1 - using Point Lights
956 
957  const SFVEC3F &boarCenter = m_boardAdapter.GetBBox3DU().GetCenter();
958 
959  m_lights.Add( new CPOINTLIGHT( SFVEC3F( boarCenter.x, boarCenter.y, +RANGE_SCALE_3D * 2.0f ),
960  SFVEC3F( light_top_bottom ) ) );
961 
962  m_lights.Add( new CPOINTLIGHT( SFVEC3F( boarCenter.x, boarCenter.y, -RANGE_SCALE_3D * 2.0f ),
963  SFVEC3F( light_top_bottom ) ) );
964 
965 
966  // http://www.flashandmath.com/mathlets/multicalc/coords/shilmay23fin.html
967 
968  // Option 2 - Top/Bottom direction lights
969  /*
970  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 0.03f,
971  glm::pi<float>() * 0.25f ),
972  SFVEC3F( light_top_bottom ) ) );
973 
974  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 0.97f,
975  glm::pi<float>() * 1.25f ),
976  SFVEC3F( light_top_bottom ) ) );
977  */
978 
979  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 1.0f / 8.0f,
980  glm::pi<float>() * 1 / 4.0f ),
981  SFVEC3F( light_directional_intensity ) ) );
982  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 1.0f / 8.0f,
983  glm::pi<float>() * 3 / 4.0f ),
984  SFVEC3F( light_directional_intensity ) ) );
985  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 1.0f / 8.0f,
986  glm::pi<float>() * 5 / 4.0f ),
987  SFVEC3F( light_directional_intensity ) ) );
988  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 1.0f / 8.0f,
989  glm::pi<float>() * 7 / 4.0f ),
990  SFVEC3F( light_directional_intensity ) ) );
991 
992 
993  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 7.0f / 8.0f,
994  glm::pi<float>() * 1 / 4.0f ),
995  SFVEC3F( light_directional_intensity ) ) );
996  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 7.0f / 8.0f,
997  glm::pi<float>() * 3 / 4.0f ),
998  SFVEC3F( light_directional_intensity ) ) );
999  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 7.0f / 8.0f,
1000  glm::pi<float>() * 5 / 4.0f ),
1001  SFVEC3F( light_directional_intensity ) ) );
1002  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 7.0f / 8.0f,
1003  glm::pi<float>() * 7 / 4.0f ),
1004  SFVEC3F( light_directional_intensity ) ) );
1005 
1006 
1007  // Create an accelerator
1008  // /////////////////////////////////////////////////////////////////////////
1009 
1010 #ifdef PRINT_STATISTICS_3D_VIEWER
1011  unsigned stats_startAcceleratorTime = GetRunningMicroSecs();
1012 #endif
1013 
1014  if( m_accelerator )
1015  {
1016  delete m_accelerator;
1017  }
1018  m_accelerator = 0;
1019 
1021 
1022 #ifdef PRINT_STATISTICS_3D_VIEWER
1023  unsigned stats_endAcceleratorTime = GetRunningMicroSecs();
1024 #endif
1025 
1026 #ifdef PRINT_STATISTICS_3D_VIEWER
1027  printf( "C3D_RENDER_RAYTRACING::reload times:\n" );
1028  printf( " Reload board: %.3f ms\n", (float)( stats_endReloadTime -
1029  stats_startReloadTime ) /
1030 
1031  1000.0f );
1032  printf( " Convert to 3D objects: %.3f ms\n", (float)( stats_endConvertTime -
1033  stats_startConvertTime ) /
1034  1000.0f );
1035  printf( " Accelerator construction: %.3f ms\n", (float)( stats_endAcceleratorTime -
1036  stats_startAcceleratorTime ) /
1037  1000.0f );
1038  printf( " Load and add 3D models: %.3f ms\n", (float)( stats_endLoad3DmodelsTime -
1039  stats_startLoad3DmodelsTime ) /
1040  1000.0f );
1041  printf( "Optimizations\n" );
1042 
1043  printf( " m_stats_converted_dummy_to_plane: %u\n",
1045 
1046  printf( " m_stats_converted_roundsegment2d_to_roundsegment: %u\n",
1048 
1051 #endif
1052 
1053  if( aStatusReporter )
1054  {
1055  // Calculation time in seconds
1056  const double calculation_time = (double)( GetRunningMicroSecs() -
1057  stats_startReloadTime ) / 1e6;
1058 
1059  aStatusReporter->Report( wxString::Format( _( "Reload time %.3f s" ), calculation_time ) );
1060  }
1061 }
void GetListObjectsIntersects(const CBBOX2D &aBBox, CONST_LIST_OBJECT2D &aOutList) const override
GetListObjectsIntersects - Get a list of objects that intersects a bbox.
double BiuTo3Dunits() const noexcept
BiuTo3Dunits - Board integer units To 3D units.
bool GetFlag(DISPLAY3D_FLG aFlag) const
GetFlag - get a configuration status of a flag.
const CBBOX & GetBBox() const
Definition: ccontainer.h:67
std::map< PCB_LAYER_ID, CBVHCONTAINER2D * > MAP_CONTAINER_2D
A type that stores a container of 2d objects for each layer id.
Definition: board_adapter.h:50
const SFVEC3F & Max() const
Function Max return the maximum vertex pointer.
Definition: cbbox.h:212
int OutlineCount() const
Returns the number of outlines in the set
SFVEC3F ConvertSRGBToLinear(const SFVEC3F &aSRGBcolor)
OBJECT2D_TYPE GetObjectType() const
Definition: cobject2d.h:125
const LIST_OBJECT & GetList() const
Definition: ccontainer.h:63
Directional light - a light based only on a direction vector.
Definition: clight.h:114
void PrintStats()
Definition: cobject2d.cpp:65
SFVEC3D m_SolderPasteColor
in realistic mode: solder paste color
BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
A base material class that can be used to derive a material implementation.
Definition: cmaterial.h:195
float GetStats_Med_Hole_Diameter3DU() const noexcept
GetStats_Med_Hole_Diameter3DU - Average diameter of holes.
SFVEC3D m_SolderMaskColorBot
in realistic mode: solder mask color ( bot )
void create_3d_object_from(CCONTAINER &aDstContainer, const COBJECT2D *aObject2D, float aZMin, float aZMax, const CMATERIAL *aMaterial, const SFVEC3F &aObjColor)
Function create_3d_object_from.
const MAP_CONTAINER_2D & GetMapLayersHoles() const noexcept
GetMapLayersHoles -Get the map of container that have the holes per layer.
std::list< const COBJECT2D * > CONST_LIST_OBJECT2D
Definition: ccontainer2d.h:38
const CBBOX & GetBBox3DU() const noexcept
GetBBox3DU - Get the bbox of the pcb board.
float GetLayerTopZpos3DU(PCB_LAYER_ID aLayerId) const noexcept
GetLayerTopZpos3DU - Get the top z position.
void InitSettings(REPORTER *aStatusReporter, REPORTER *aWarningReporter)
InitSettings - Function to be called by the render when it need to reload the settings for the board.
void SetMaterial(const CMATERIAL *aMaterial)
Definition: cobject.h:66
void PrintStats()
Definition: cobject.cpp:64
SFVEC3D m_SilkScreenColorBot
in realistic mode: SilkScreen color ( bot )
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Function Report is a pure virtual function to override in the derived object.
const MAP_CONTAINER_2D & GetMapLayers() const noexcept
GetMapLayers - Get the map of container that have the objects per layer.
unsigned int m_stats_converted_dummy_to_plane
SFVEC3D m_BgColorTop
background top color
#define CSGITEM_EMPTY
This class is used to make constructive solig geometry for items objects on layers.
SFVEC3F GetCenter() const
Function GetCenter return the center point of the bounding box.
Definition: cbbox.cpp:135
CGENERICACCELERATOR * m_accelerator
void Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(const SHAPE_POLY_SET &aMainPath, CGENERICCONTAINER2D &aDstContainer, float aBiuTo3DunitsScale, float aDivFactor, const BOARD_ITEM &aBoardItem, int aPolyIndex)
Convert_path_polygon_to_polygon_blocks_and_dummy_blocks This function will use a polygon in the forma...
Definition: cpolygon2d.cpp:404
void SetColor(const SFVEC3F &aColor)
Definition: ctriangle.cpp:156
const BOARD_ITEM & GetBoardItem() const
Definition: cobject2d.h:75
PCB_LAYER_ID
A quick note on layer IDs:
void SetColor(SFVEC3F aObjColor)
Definition: ccylinder.h:51
const CBVHCONTAINER2D & GetThroughHole_Outer() const noexcept
GetThroughHole_Outer - Get the inflated ThroughHole container.
float GetLayerBottomZpos3DU(PCB_LAYER_ID aLayerId) const noexcept
GetLayerBottomZpos3DU - Get the bottom z position.
float NextFloatDown(float v)
Definition: 3d_fastmath.h:157
SHAPE_POLY_SET.
CCONTAINER2D m_containerWithObjectsToDelete
This will store the list of created objects special for RT, that will be clear in the end.
const BOARD * GetBoard() const noexcept
GetBoard - Get current board to be rendered.
void Add(CLIGHT *aLight)
Add - Add a light to the container.
Definition: clight.h:186
Point light based on: http://ogldev.atspace.co.uk/www/tutorial20/tutorial20.html.
Definition: clight.h:67
unsigned int m_stats_converted_roundsegment2d_to_roundsegment
const SHAPE_POLY_SET & GetBoardPoly() const noexcept
GetBoardPoly - Get the current polygon of the epoxy board.
#define CSGITEM_FULL
void SetColor(SFVEC3F aObjColor)
Definition: clayeritem.h:46
A triangle object.
Definition: ctriangle.h:42
CDIRECTIONALLIGHT * m_camera_light
void Add(COBJECT *aObject)
Definition: ccontainer.h:52
SFVEC3F GetLayerColor(PCB_LAYER_ID aLayerId) const
GetLayerColor - get the technical color of a layer.
void Fracture(POLYGON_MODE aFastMode)
Converts a set of polygons with holes to a singe outline with "slits"/"fractures" connecting the oute...
static COBJECT2D_STATS & Instance()
Definition: cobject2d.h:152
void Scale(float aScale)
Function Scale scales a bounding box by its center.
Definition: cbbox.cpp:194
A vertical cylinder.
Definition: ccylinder.h:38
BOARD_ADAPTER & m_boardAdapter
settings refrence in use for this render
const CBVHCONTAINER2D & GetThroughHole_Outer_Ring() const noexcept
GetThroughHole_Outer_Ring - Get the ThroughHole container that include the width of the annular ring.
const SFVEC3F & Min() const
Function Min return the minimun vertex pointer.
Definition: cbbox.h:205
void ResetStats()
Definition: cobject.h:116
SFVEC3D m_SolderMaskColorTop
in realistic mode: solder mask color ( top )
void Add(COBJECT2D *aObject)
Definition: ccontainer2d.h:52
SFVEC3D m_SilkScreenColorTop
in realistic mode: SilkScreen color ( top )
const SFVEC3F & GetBoardCenter3DU() const noexcept
GetBoardCenter - the board center position in 3d units.
SFVEC2F GetExtent() const
Function GetExtent.
Definition: cbbox2d.cpp:127
struct C3D_RENDER_RAYTRACING::@3 m_materials
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
bool m_reloadRequested
!TODO: this must be reviewed in order to flag change types
std::list< COBJECT2D * > LIST_OBJECT2D
Definition: ccontainer2d.h:37
#define _(s)
Definition: 3d_actions.cpp:33
unsigned GetRunningMicroSecs()
Function GetRunningMicroSecs An alternate way to calculate an elapset time (in microsecondes) to clas...
glm::vec3 SFVEC3F
Definition: xv3d_types.h:47
unsigned int GetStats_Nr_Holes() const noexcept
GetStats_Nr_Holes - Get statistics of the nr of holes.
SFVEC3D m_BoardBodyColor
in realistic mode: FR4 board color
float NextFloatUp(float v)
Definition: 3d_fastmath.h:136
void SetBoardLookAtPos(const SFVEC3F &aBoardPos)
Definition: ccamera.h:118
static COBJECT3D_STATS & Instance()
Definition: cobject.h:133
void SetCastShadows(bool aCastShadow)
Definition: clight.h:57
SFVEC3D m_CopperColor
in realistic mode: copper color
SFVEC3F SphericalToCartesian(float aInclination, float aAzimuth)
SphericalToCartesian.
Definition: 3d_math.h:43
void ResetStats()
Definition: cobject2d.h:135
CCONTAINER2D * m_outlineBoard2dObjects
const SFVEC2F & GetCentroid() const
Definition: cobject2d.h:123
const CBBOX2D & GetBBox() const
Definition: cobject2d.h:121
unsigned int GetStats_Nr_Vias() const noexcept
GetStats_Nr_Vias - Get statistics of the nr of vias.
float GetStats_Med_Via_Hole_Diameter3DU() const noexcept
GetStats_Med_Via_Hole_Diameter3DU - Average diameter of the via holes.
const LIST_OBJECT2D & GetList() const
Definition: ccontainer2d.h:64
void Clear()
Clear - Remove all lights from the container.
Definition: clight.h:165
virtual bool Intersects(const CBBOX2D &aBBox) const =0
Function Intersects.
#define RANGE_SCALE_3D
This defines the range that all coord will have to be rendered.
Definition: board_adapter.h:61
CBBOX manages a bounding box defined by two SFVEC3F min max points.
Definition: cbbox.h:40
MAP_MODEL_MATERIALS m_model_materials
Stores materials of the 3D models.
bool IsInitialized() const
Function IsInitialized check if this bounding box is already initialized.
Definition: cbbox.cpp:87

References _, CGENERICCONTAINER::Add(), CGENERICCONTAINER2D::Add(), CLIGHTCONTAINER::Add(), add_3D_vias_and_pads_to_container(), B_Adhes, B_CrtYd, B_Cu, B_Fab, B_Mask, B_Paste, B_SilkS, BOARD_ADAPTER::BiuTo3Dunits(), CGENERICCONTAINER::Clear(), CGENERICCONTAINER2D::Clear(), CLIGHTCONTAINER::Clear(), Cmts_User, Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(), ConvertSRGBToLinear(), create_3d_object_from(), CSGITEM_EMPTY, CSGITEM_FULL, Dwgs_User, Eco1_User, Eco2_User, Edge_Cuts, F_Adhes, F_CrtYd, F_Cu, F_Fab, F_Mask, F_Paste, F_SilkS, FILLED_CIRCLE, FL_CLIP_SILK_ON_VIA_ANNULUS, FL_RENDER_RAYTRACING_BACKFLOOR, FL_SHOW_BOARD_BODY, FL_SOLDERMASK, FL_SUBTRACT_MASK_FROM_SILK, FL_USE_REALISTIC_MODE, Format(), SHAPE_POLY_SET::Fracture(), CGENERICCONTAINER::GetBBox(), COBJECT2D::GetBBox(), BOARD_ADAPTER::GetBBox3DU(), BOARD_ADAPTER::GetBoard(), BOARD_ADAPTER::GetBoardCenter3DU(), COBJECT2D::GetBoardItem(), BOARD_ADAPTER::GetBoardPoly(), CBBOX::GetCenter(), COBJECT2D::GetCentroid(), CBBOX2D::GetExtent(), BOARD_ADAPTER::GetFlag(), BOARD_ADAPTER::GetLayerBottomZpos3DU(), BOARD_ADAPTER::GetLayerColor(), BOARD_ADAPTER::GetLayerTopZpos3DU(), CGENERICCONTAINER::GetList(), CGENERICCONTAINER2D::GetList(), CBVHCONTAINER2D::GetListObjectsIntersects(), BOARD_ADAPTER::GetMapLayers(), BOARD_ADAPTER::GetMapLayersHoles(), COBJECT2D::GetObjectType(), GetRunningMicroSecs(), BOARD_ADAPTER::GetStats_Med_Hole_Diameter3DU(), BOARD_ADAPTER::GetStats_Med_Via_Hole_Diameter3DU(), BOARD_ADAPTER::GetStats_Nr_Holes(), BOARD_ADAPTER::GetStats_Nr_Vias(), BOARD_ADAPTER::GetThroughHole_Outer(), BOARD_ADAPTER::GetThroughHole_Outer_Ring(), BOARD_ADAPTER::InitSettings(), COBJECT3D_STATS::Instance(), COBJECT2D_STATS::Instance(), COBJECT2D::Intersects(), CBBOX::IsInitialized(), load_3D_models(), m_accelerator, BOARD_ADAPTER::m_BgColorTop, C3D_RENDER_BASE::m_boardAdapter, BOARD_ADAPTER::m_BoardBodyColor, C3D_RENDER_BASE::m_camera, m_camera_light, m_containerWithObjectsToDelete, BOARD_ADAPTER::m_CopperColor, m_lights, m_materials, m_model_materials, m_object_container, m_outlineBoard2dObjects, C3D_RENDER_BASE::m_reloadRequested, BOARD_ADAPTER::m_SilkScreenColorBot, BOARD_ADAPTER::m_SilkScreenColorTop, BOARD_ADAPTER::m_SolderMaskColorBot, BOARD_ADAPTER::m_SolderMaskColorTop, BOARD_ADAPTER::m_SolderPasteColor, m_stats_converted_dummy_to_plane, m_stats_converted_roundsegment2d_to_roundsegment, Margin, CBBOX::Max(), CBBOX::Min(), NextFloatDown(), NextFloatUp(), SHAPE_POLY_SET::OutlineCount(), SHAPE_POLY_SET::PM_FAST, COBJECT3D_STATS::PrintStats(), COBJECT2D_STATS::PrintStats(), RANGE_SCALE_3D, REPORTER::Report(), COBJECT3D_STATS::ResetStats(), COBJECT2D_STATS::ResetStats(), CBBOX::Scale(), CCAMERA::SetBoardLookAtPos(), CLIGHT::SetCastShadows(), CLAYERITEM::SetColor(), CVCYLINDER::SetColor(), CTRIANGLE::SetColor(), COBJECT::SetMaterial(), setupMaterials(), and SphericalToCartesian().

Referenced by Redraw().

◆ ReloadRequest()

void C3D_RENDER_BASE::ReloadRequest ( )
inlineinherited

ReloadRequest - !TODO: this must be reviewed to add flags to improve specific render.

Definition at line 76 of file c3d_render_base.h.

76 { m_reloadRequested = true; }
bool m_reloadRequested
!TODO: this must be reviewed in order to flag change types

References C3D_RENDER_BASE::m_reloadRequested.

Referenced by EDA_3D_CANVAS::ReloadRequest(), EDA_3D_CANVAS::RenderEngineChanged(), and EDA_3D_CANVAS::RenderRaytracingRequest().

◆ render()

void C3D_RENDER_RAYTRACING::render ( GLubyte *  ptrPBO,
REPORTER aStatusReporter 
)
private

Definition at line 302 of file c3d_render_raytracing.cpp.

303 {
306  {
308 
309  if( m_camera_light )
311 
313  {
314  // Set all pixels of PBO transparent (Alpha to 0)
315  // This way it will draw the full buffer but only shows the updated (
316  // already calculated) squares
317  // /////////////////////////////////////////////////////////////////////
318  unsigned int nPixels = m_realBufferSize.x * m_realBufferSize.y;
319  GLubyte *tmp_ptrPBO = ptrPBO + 3; // PBO is RGBA
320 
321  for( unsigned int i = 0; i < nPixels; ++i )
322  {
323  *tmp_ptrPBO = 0;
324  tmp_ptrPBO += 4; // PBO is RGBA
325  }
326  }
327 
330  }
331 
332  switch( m_rt_render_state )
333  {
335  rt_render_tracing( ptrPBO, aStatusReporter );
336  break;
337 
339  rt_render_post_process_shade( ptrPBO, aStatusReporter );
340  break;
341 
343  rt_render_post_process_blur_finish( ptrPBO, aStatusReporter );
344  break;
345 
346  default:
347  wxASSERT_MSG( false, "Invalid state on m_rt_render_state");
349  break;
350  }
351 
352  if( aStatusReporter && ( m_rt_render_state == RT_RENDER_STATE_FINISH ) )
353  {
354  // Calculation time in seconds
355  const double calculation_time = (double)( GetRunningMicroSecs() -
357 
358  aStatusReporter->Report( wxString::Format( _( "Rendering time %.3f s" ),
359  calculation_time ) );
360  }
361 }
void rt_render_post_process_shade(GLubyte *ptrPBO, REPORTER *aStatusReporter)
SFVEC3F ConvertSRGBToLinear(const SFVEC3F &aSRGBcolor)
const SFVEC3F & GetDir() const
Definition: ccamera.h:112
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Function Report is a pure virtual function to override in the derived object.
SFVEC3D m_BgColorTop
background top color
RT_RENDER_STATE m_rt_render_state
State used on quality render.
RENDER_ENGINE RenderEngineGet() const noexcept
RenderEngineGet.
CDIRECTIONALLIGHT * m_camera_light
SFVEC3D m_BgColorBot
background bottom color
BOARD_ADAPTER & m_boardAdapter
settings refrence in use for this render
void rt_render_tracing(GLubyte *ptrPBO, REPORTER *aStatusReporter)
void SetDirection(const SFVEC3F &aDir)
SetDirection - Set directional light orientation.
Definition: clight.h:129
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
#define _(s)
Definition: 3d_actions.cpp:33
unsigned GetRunningMicroSecs()
Function GetRunningMicroSecs An alternate way to calculate an elapset time (in microsecondes) to clas...
glm::vec3 SFVEC3F
Definition: xv3d_types.h:47
unsigned long int m_stats_start_rendering_time
Time that the render starts.
void rt_render_post_process_blur_finish(GLubyte *ptrPBO, REPORTER *aStatusReporter)

References _, ConvertSRGBToLinear(), Format(), CCAMERA::GetDir(), GetRunningMicroSecs(), BOARD_ADAPTER::m_BgColorBot, m_BgColorBot_LinearRGB, BOARD_ADAPTER::m_BgColorTop, m_BgColorTop_LinearRGB, C3D_RENDER_BASE::m_boardAdapter, C3D_RENDER_BASE::m_camera, m_camera_light, m_realBufferSize, m_rt_render_state, m_stats_start_rendering_time, OPENGL_LEGACY, BOARD_ADAPTER::RenderEngineGet(), REPORTER::Report(), restart_render_state(), rt_render_post_process_blur_finish(), rt_render_post_process_shade(), RT_RENDER_STATE_FINISH, RT_RENDER_STATE_MAX, RT_RENDER_STATE_POST_PROCESS_BLUR_AND_FINISH, RT_RENDER_STATE_POST_PROCESS_SHADE, RT_RENDER_STATE_TRACING, rt_render_tracing(), and CDIRECTIONALLIGHT::SetDirection().

Referenced by Redraw().

◆ render_preview()

void C3D_RENDER_RAYTRACING::render_preview ( GLubyte *  ptrPBO)
private

Definition at line 1022 of file c3d_render_raytracing.cpp.

1023 {
1024  m_isPreview = true;
1025 
1026  std::atomic<size_t> nextBlock( 0 );
1027  std::atomic<size_t> threadsFinished( 0 );
1028 
1029  size_t parallelThreadCount = std::min<size_t>(
1030  std::max<size_t>( std::thread::hardware_concurrency(), 2 ),
1031  m_blockPositions.size() );
1032  for( size_t ii = 0; ii < parallelThreadCount; ++ii )
1033  {
1034  std::thread t = std::thread( [&]()
1035  {
1036  for( size_t iBlock = nextBlock.fetch_add( 1 );
1037  iBlock < m_blockPositionsFast.size();
1038  iBlock = nextBlock.fetch_add( 1 ) )
1039  {
1040  const SFVEC2UI &windowPosUI = m_blockPositionsFast[ iBlock ];
1041  const SFVEC2I windowsPos = SFVEC2I( windowPosUI.x + m_xoffset,
1042  windowPosUI.y + m_yoffset );
1043 
1044  RAYPACKET blockPacket( m_camera, windowsPos, 4 );
1045 
1047 
1048  // Initialize hitPacket with a "not hit" information
1049  for( HITINFO_PACKET& packet : hitPacket )
1050  {
1051  packet.m_HitInfo.m_tHit = std::numeric_limits<float>::infinity();
1052  packet.m_HitInfo.m_acc_node_info = 0;
1053  packet.m_hitresult = false;
1054  }
1055 
1056  // Intersect packet block
1057  m_accelerator->Intersect( blockPacket, hitPacket );
1058 
1059 
1060  // Calculate background gradient color
1061  // /////////////////////////////////////////////////////////////////////
1062  SFVEC3F bgColor[RAYPACKET_DIM];
1063 
1064  for( unsigned int y = 0; y < RAYPACKET_DIM; ++y )
1065  {
1066  const float posYfactor = (float)(windowsPos.y + y * 4.0f) / (float)m_windowSize.y;
1067 
1068  bgColor[y] = (SFVEC3F)m_boardAdapter.m_BgColorTop * SFVEC3F( posYfactor) +
1069  (SFVEC3F)m_boardAdapter.m_BgColorBot * ( SFVEC3F( 1.0f) - SFVEC3F( posYfactor) );
1070  }
1071 
1072  CCOLORRGB hitColorShading[RAYPACKET_RAYS_PER_PACKET];
1073 
1074  for( unsigned int i = 0; i < RAYPACKET_RAYS_PER_PACKET; ++i )
1075  {
1076  const SFVEC3F bhColorY = bgColor[i / RAYPACKET_DIM];
1077 
1078  if( hitPacket[i].m_hitresult == true )
1079  {
1080  const SFVEC3F hitColor = shadeHit( bhColorY,
1081  blockPacket.m_ray[i],
1082  hitPacket[i].m_HitInfo,
1083  false,
1084  0,
1085  false );
1086 
1087  hitColorShading[i] = CCOLORRGB( hitColor );
1088  }
1089  else
1090  hitColorShading[i] = bhColorY;
1091  }
1092 
1093  CCOLORRGB cLRB_old[(RAYPACKET_DIM - 1)];
1094 
1095  for( unsigned int y = 0; y < (RAYPACKET_DIM - 1); ++y )
1096  {
1097 
1098  const SFVEC3F bgColorY = bgColor[y];
1099  const CCOLORRGB bgColorYRGB = CCOLORRGB( bgColorY );
1100 
1101  // This stores cRTB from the last block to be reused next time in a cLTB pixel
1102  CCOLORRGB cRTB_old;
1103 
1104  //RAY cRTB_ray;
1105  //HITINFO cRTB_hitInfo;
1106 
1107  for( unsigned int x = 0; x < (RAYPACKET_DIM - 1); ++x )
1108  {
1109  // pxl 0 pxl 1 pxl 2 pxl 3 pxl 4
1110  // x0 x1 ...
1111  // .---------------------------.
1112  // y0 | cLT | cxxx | cLRT | cxxx | cRT |
1113  // | cxxx | cLTC | cxxx | cRTC | cxxx |
1114  // | cLTB | cxxx | cC | cxxx | cRTB |
1115  // | cxxx | cLBC | cxxx | cRBC | cxxx |
1116  // '---------------------------'
1117  // y1 | cLB | cxxx | cLRB | cxxx | cRB |
1118 
1119  const unsigned int iLT = ((x + 0) + RAYPACKET_DIM * (y + 0));
1120  const unsigned int iRT = ((x + 1) + RAYPACKET_DIM * (y + 0));
1121  const unsigned int iLB = ((x + 0) + RAYPACKET_DIM * (y + 1));
1122  const unsigned int iRB = ((x + 1) + RAYPACKET_DIM * (y + 1));
1123 
1124  // !TODO: skip when there are no hits
1125 
1126 
1127  const CCOLORRGB &cLT = hitColorShading[ iLT ];
1128  const CCOLORRGB &cRT = hitColorShading[ iRT ];
1129  const CCOLORRGB &cLB = hitColorShading[ iLB ];
1130  const CCOLORRGB &cRB = hitColorShading[ iRB ];
1131 
1132  // Trace and shade cC
1133  // /////////////////////////////////////////////////////////////
1134  CCOLORRGB cC = bgColorYRGB;
1135 
1136  const SFVEC3F &oriLT = blockPacket.m_ray[ iLT ].m_Origin;
1137  const SFVEC3F &oriRB = blockPacket.m_ray[ iRB ].m_Origin;
1138 
1139  const SFVEC3F &dirLT = blockPacket.m_ray[ iLT ].m_Dir;
1140  const SFVEC3F &dirRB = blockPacket.m_ray[ iRB ].m_Dir;
1141 
1142  SFVEC3F oriC;
1143  SFVEC3F dirC;
1144 
1145  HITINFO centerHitInfo;
1146  centerHitInfo.m_tHit = std::numeric_limits<float>::infinity();
1147 
1148  bool hittedC = false;
1149 
1150  if( (hitPacket[ iLT ].m_hitresult == true) ||
1151  (hitPacket[ iRT ].m_hitresult == true) ||
1152  (hitPacket[ iLB ].m_hitresult == true) ||
1153  (hitPacket[ iRB ].m_hitresult == true) )
1154  {
1155 
1156  oriC = ( oriLT + oriRB ) * 0.5f;
1157  dirC = glm::normalize( ( dirLT + dirRB ) * 0.5f );
1158 
1159  // Trace the center ray
1160  RAY centerRay;
1161  centerRay.Init( oriC, dirC );
1162 
1163  const unsigned int nodeLT = hitPacket[ iLT ].m_HitInfo.m_acc_node_info;
1164  const unsigned int nodeRT = hitPacket[ iRT ].m_HitInfo.m_acc_node_info;
1165  const unsigned int nodeLB = hitPacket[ iLB ].m_HitInfo.m_acc_node_info;
1166  const unsigned int nodeRB = hitPacket[ iRB ].m_HitInfo.m_acc_node_info;
1167 
1168  if( nodeLT != 0 )
1169  hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo, nodeLT );
1170 
1171  if( ( nodeRT != 0 ) &&
1172  ( nodeRT != nodeLT ) )
1173  hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo, nodeRT );
1174 
1175  if( ( nodeLB != 0 ) &&
1176  ( nodeLB != nodeLT ) &&
1177  ( nodeLB != nodeRT ) )
1178  hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo, nodeLB );
1179 
1180  if( ( nodeRB != 0 ) &&
1181  ( nodeRB != nodeLB ) &&
1182  ( nodeRB != nodeLT ) &&
1183  ( nodeRB != nodeRT ) )
1184  hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo, nodeRB );
1185 
1186  if( hittedC )
1187  cC = CCOLORRGB( shadeHit( bgColorY, centerRay, centerHitInfo, false, 0, false ) );
1188  else
1189  {
1190  centerHitInfo.m_tHit = std::numeric_limits<float>::infinity();
1191  hittedC = m_accelerator->Intersect( centerRay, centerHitInfo );
1192 
1193  if( hittedC )
1194  cC = CCOLORRGB( shadeHit( bgColorY,
1195  centerRay,
1196  centerHitInfo,
1197  false,
1198  0,
1199  false ) );
1200  }
1201  }
1202 
1203  // Trace and shade cLRT
1204  // /////////////////////////////////////////////////////////////
1205  CCOLORRGB cLRT = bgColorYRGB;
1206 
1207  const SFVEC3F &oriRT = blockPacket.m_ray[ iRT ].m_Origin;
1208  const SFVEC3F &dirRT = blockPacket.m_ray[ iRT ].m_Dir;
1209 
1210  if( y == 0 )
1211  {
1212  // Trace the center ray
1213  RAY rayLRT;
1214  rayLRT.Init( ( oriLT + oriRT ) * 0.5f,
1215  glm::normalize( ( dirLT + dirRT ) * 0.5f ) );
1216 
1217  HITINFO hitInfoLRT;
1218  hitInfoLRT.m_tHit = std::numeric_limits<float>::infinity();
1219 
1220  if( hitPacket[ iLT ].m_hitresult &&
1221  hitPacket[ iRT ].m_hitresult &&
1222  (hitPacket[ iLT ].m_HitInfo.pHitObject == hitPacket[ iRT ].m_HitInfo.pHitObject) )
1223  {
1224  hitInfoLRT.pHitObject = hitPacket[ iLT ].m_HitInfo.pHitObject;
1225  hitInfoLRT.m_tHit = ( hitPacket[ iLT ].m_HitInfo.m_tHit +
1226  hitPacket[ iRT ].m_HitInfo.m_tHit ) * 0.5f;
1227  hitInfoLRT.m_HitNormal =
1228  glm::normalize( ( hitPacket[ iLT ].m_HitInfo.m_HitNormal +
1229  hitPacket[ iRT ].m_HitInfo.m_HitNormal ) * 0.5f );
1230 
1231  cLRT = CCOLORRGB( shadeHit( bgColorY, rayLRT, hitInfoLRT, false, 0, false ) );
1232  cLRT = BlendColor( cLRT, BlendColor( cLT, cRT) );
1233  }
1234  else
1235  {
1236  if( hitPacket[ iLT ].m_hitresult ||
1237  hitPacket[ iRT ].m_hitresult ) // If any hits
1238  {
1239  const unsigned int nodeLT = hitPacket[ iLT ].m_HitInfo.m_acc_node_info;
1240  const unsigned int nodeRT = hitPacket[ iRT ].m_HitInfo.m_acc_node_info;
1241 
1242  bool hittedLRT = false;
1243 
1244  if( nodeLT != 0 )
1245  hittedLRT |= m_accelerator->Intersect( rayLRT, hitInfoLRT, nodeLT );
1246 
1247  if( ( nodeRT != 0 ) &&
1248  ( nodeRT != nodeLT ) )
1249  hittedLRT |= m_accelerator->Intersect( rayLRT,
1250  hitInfoLRT,
1251  nodeRT );
1252 
1253  if( hittedLRT )
1254  cLRT = CCOLORRGB( shadeHit( bgColorY,
1255  rayLRT,
1256  hitInfoLRT,
1257  false,
1258  0,
1259  false ) );
1260  else
1261  {
1262  hitInfoLRT.m_tHit = std::numeric_limits<float>::infinity();
1263 
1264  if( m_accelerator->Intersect( rayLRT,hitInfoLRT ) )
1265  cLRT = CCOLORRGB( shadeHit( bgColorY,
1266  rayLRT,
1267  hitInfoLRT,
1268  false,
1269  0,
1270  false ) );
1271  }
1272  }
1273  }
1274  }
1275  else
1276  cLRT = cLRB_old[x];
1277 
1278 
1279  // Trace and shade cLTB
1280  // /////////////////////////////////////////////////////////////
1281  CCOLORRGB cLTB = bgColorYRGB;
1282 
1283  if( x == 0 )
1284  {
1285  const SFVEC3F &oriLB = blockPacket.m_ray[ iLB ].m_Origin;
1286  const SFVEC3F &dirLB = blockPacket.m_ray[ iLB ].m_Dir;
1287 
1288  // Trace the center ray
1289  RAY rayLTB;
1290  rayLTB.Init( ( oriLT + oriLB ) * 0.5f,
1291  glm::normalize( ( dirLT + dirLB ) * 0.5f ) );
1292 
1293  HITINFO hitInfoLTB;
1294  hitInfoLTB.m_tHit = std::numeric_limits<float>::infinity();
1295 
1296  if( hitPacket[ iLT ].m_hitresult &&
1297  hitPacket[ iLB ].m_hitresult &&
1298  ( hitPacket[ iLT ].m_HitInfo.pHitObject ==
1299  hitPacket[ iLB ].m_HitInfo.pHitObject ) )
1300  {
1301  hitInfoLTB.pHitObject = hitPacket[ iLT ].m_HitInfo.pHitObject;
1302  hitInfoLTB.m_tHit = ( hitPacket[ iLT ].m_HitInfo.m_tHit +
1303  hitPacket[ iLB ].m_HitInfo.m_tHit ) * 0.5f;
1304  hitInfoLTB.m_HitNormal =
1305  glm::normalize( ( hitPacket[ iLT ].m_HitInfo.m_HitNormal +
1306  hitPacket[ iLB ].m_HitInfo.m_HitNormal ) * 0.5f );
1307  cLTB = CCOLORRGB( shadeHit( bgColorY, rayLTB, hitInfoLTB, false, 0, false ) );
1308  cLTB = BlendColor( cLTB, BlendColor( cLT, cLB) );
1309  }
1310  else
1311  {
1312  if( hitPacket[ iLT ].m_hitresult ||
1313  hitPacket[ iLB ].m_hitresult ) // If any hits
1314  {
1315  const unsigned int nodeLT = hitPacket[ iLT ].m_HitInfo.m_acc_node_info;
1316  const unsigned int nodeLB = hitPacket[ iLB ].m_HitInfo.m_acc_node_info;
1317 
1318  bool hittedLTB = false;
1319 
1320  if( nodeLT != 0 )
1321  hittedLTB |= m_accelerator->Intersect( rayLTB,
1322  hitInfoLTB,
1323  nodeLT );
1324 
1325  if( ( nodeLB != 0 ) &&
1326  ( nodeLB != nodeLT ) )
1327  hittedLTB |= m_accelerator->Intersect( rayLTB,
1328  hitInfoLTB,
1329  nodeLB );
1330 
1331  if( hittedLTB )
1332  cLTB = CCOLORRGB( shadeHit( bgColorY,
1333  rayLTB,
1334  hitInfoLTB,
1335  false,
1336  0,
1337  false ) );
1338  else
1339  {
1340  hitInfoLTB.m_tHit = std::numeric_limits<float>::infinity();
1341 
1342  if( m_accelerator->Intersect( rayLTB, hitInfoLTB ) )
1343  cLTB = CCOLORRGB( shadeHit( bgColorY,
1344  rayLTB,
1345  hitInfoLTB,
1346  false,
1347  0,
1348  false ) );
1349  }
1350  }
1351  }
1352  }
1353  else
1354  cLTB = cRTB_old;
1355 
1356 
1357  // Trace and shade cRTB
1358  // /////////////////////////////////////////////////////////////
1359  CCOLORRGB cRTB = bgColorYRGB;
1360 
1361  // Trace the center ray
1362  RAY rayRTB;
1363  rayRTB.Init( ( oriRT + oriRB ) * 0.5f,
1364  glm::normalize( ( dirRT + dirRB ) * 0.5f ) );
1365 
1366  HITINFO hitInfoRTB;
1367  hitInfoRTB.m_tHit = std::numeric_limits<float>::infinity();
1368 
1369  if( hitPacket[ iRT ].m_hitresult &&
1370  hitPacket[ iRB ].m_hitresult &&
1371  ( hitPacket[ iRT ].m_HitInfo.pHitObject ==
1372  hitPacket[ iRB ].m_HitInfo.pHitObject ) )
1373  {
1374  hitInfoRTB.pHitObject = hitPacket[ iRT ].m_HitInfo.pHitObject;
1375 
1376  hitInfoRTB.m_tHit = ( hitPacket[ iRT ].m_HitInfo.m_tHit +
1377  hitPacket[ iRB ].m_HitInfo.m_tHit ) * 0.5f;
1378 
1379  hitInfoRTB.m_HitNormal =
1380  glm::normalize( ( hitPacket[ iRT ].m_HitInfo.m_HitNormal +
1381  hitPacket[ iRB ].m_HitInfo.m_HitNormal ) * 0.5f );
1382 
1383  cRTB = CCOLORRGB( shadeHit( bgColorY, rayRTB, hitInfoRTB, false, 0, false ) );
1384  cRTB = BlendColor( cRTB, BlendColor( cRT, cRB) );
1385  }
1386  else
1387  {
1388  if( hitPacket[ iRT ].m_hitresult ||
1389  hitPacket[ iRB ].m_hitresult ) // If any hits
1390  {
1391  const unsigned int nodeRT = hitPacket[ iRT ].m_HitInfo.m_acc_node_info;
1392  const unsigned int nodeRB = hitPacket[ iRB ].m_HitInfo.m_acc_node_info;
1393 
1394  bool hittedRTB = false;
1395 
1396  if( nodeRT != 0 )
1397  hittedRTB |= m_accelerator->Intersect( rayRTB, hitInfoRTB, nodeRT );
1398 
1399  if( ( nodeRB != 0 ) &&
1400  ( nodeRB != nodeRT ) )
1401  hittedRTB |= m_accelerator->Intersect( rayRTB, hitInfoRTB, nodeRB );
1402 
1403  if( hittedRTB )
1404  cRTB = CCOLORRGB( shadeHit( bgColorY,
1405  rayRTB,
1406  hitInfoRTB,
1407  false,
1408  0,
1409  false) );
1410  else
1411  {
1412  hitInfoRTB.m_tHit = std::numeric_limits<float>::infinity();
1413 
1414  if( m_accelerator->Intersect( rayRTB, hitInfoRTB ) )
1415  cRTB = CCOLORRGB( shadeHit( bgColorY,
1416  rayRTB,
1417  hitInfoRTB,
1418  false,
1419  0,
1420  false ) );
1421  }
1422  }
1423  }
1424 
1425  cRTB_old = cRTB;
1426 
1427 
1428  // Trace and shade cLRB
1429  // /////////////////////////////////////////////////////////////
1430  CCOLORRGB cLRB = bgColorYRGB;
1431 
1432  const SFVEC3F &oriLB = blockPacket.m_ray[ iLB ].m_Origin;
1433  const SFVEC3F &dirLB = blockPacket.m_ray[ iLB ].m_Dir;
1434 
1435  // Trace the center ray
1436  RAY rayLRB;
1437  rayLRB.Init( ( oriLB + oriRB ) * 0.5f,
1438  glm::normalize( ( dirLB + dirRB ) * 0.5f ) );
1439 
1440  HITINFO hitInfoLRB;
1441  hitInfoLRB.m_tHit = std::numeric_limits<float>::infinity();
1442 
1443  if( hitPacket[ iLB ].m_hitresult &&
1444  hitPacket[ iRB ].m_hitresult &&
1445  ( hitPacket[ iLB ].m_HitInfo.pHitObject ==
1446  hitPacket[ iRB ].m_HitInfo.pHitObject ) )
1447  {
1448  hitInfoLRB.pHitObject = hitPacket[ iLB ].m_HitInfo.pHitObject;
1449 
1450  hitInfoLRB.m_tHit = ( hitPacket[ iLB ].m_HitInfo.m_tHit +
1451  hitPacket[ iRB ].m_HitInfo.m_tHit ) * 0.5f;
1452 
1453  hitInfoLRB.m_HitNormal =
1454  glm::normalize( ( hitPacket[ iLB ].m_HitInfo.m_HitNormal +
1455  hitPacket[ iRB ].m_HitInfo.m_HitNormal ) * 0.5f );
1456 
1457  cLRB = CCOLORRGB( shadeHit( bgColorY, rayLRB, hitInfoLRB, false, 0, false ) );
1458  cLRB = BlendColor( cLRB, BlendColor( cLB, cRB) );
1459  }
1460  else
1461  {
1462  if( hitPacket[ iLB ].m_hitresult ||
1463  hitPacket[ iRB ].m_hitresult ) // If any hits
1464  {
1465  const unsigned int nodeLB = hitPacket[ iLB ].m_HitInfo.m_acc_node_info;
1466  const unsigned int nodeRB = hitPacket[ iRB ].m_HitInfo.m_acc_node_info;
1467 
1468  bool hittedLRB = false;
1469 
1470  if( nodeLB != 0 )
1471  hittedLRB |= m_accelerator->Intersect( rayLRB, hitInfoLRB, nodeLB );
1472 
1473  if( ( nodeRB != 0 ) &&
1474  ( nodeRB != nodeLB ) )
1475  hittedLRB |= m_accelerator->Intersect( rayLRB, hitInfoLRB, nodeRB );
1476 
1477  if( hittedLRB )
1478  cLRB = CCOLORRGB( shadeHit( bgColorY, rayLRB, hitInfoLRB, false, 0, false ) );
1479  else
1480  {
1481  hitInfoLRB.m_tHit = std::numeric_limits<float>::infinity();
1482 
1483  if( m_accelerator->Intersect( rayLRB, hitInfoLRB ) )
1484  cLRB = CCOLORRGB( shadeHit( bgColorY,
1485  rayLRB,
1486  hitInfoLRB,
1487  false,
1488  0,
1489  false ) );
1490  }
1491  }
1492  }
1493 
1494  cLRB_old[x] = cLRB;
1495 
1496 
1497  // Trace and shade cLTC
1498  // /////////////////////////////////////////////////////////////
1499  CCOLORRGB cLTC = BlendColor( cLT , cC );
1500 
1501  if( hitPacket[ iLT ].m_hitresult || hittedC )
1502  {
1503  // Trace the center ray
1504  RAY rayLTC;
1505  rayLTC.Init( ( oriLT + oriC ) * 0.5f,
1506  glm::normalize( ( dirLT + dirC ) * 0.5f ) );
1507 
1508  HITINFO hitInfoLTC;
1509  hitInfoLTC.m_tHit = std::numeric_limits<float>::infinity();
1510 
1511  bool hitted = false;
1512 
1513  if( hittedC )
1514  hitted = centerHitInfo.pHitObject->Intersect( rayLTC, hitInfoLTC );
1515  else
1516  if( hitPacket[ iLT ].m_hitresult )
1517  hitted = hitPacket[ iLT ].m_HitInfo.pHitObject->Intersect( rayLTC,
1518  hitInfoLTC );
1519 
1520  if( hitted )
1521  cLTC = CCOLORRGB( shadeHit( bgColorY, rayLTC, hitInfoLTC, false, 0, false ) );
1522  }
1523 
1524 
1525  // Trace and shade cRTC
1526  // /////////////////////////////////////////////////////////////
1527  CCOLORRGB cRTC = BlendColor( cRT , cC );
1528 
1529  if( hitPacket[ iRT ].m_hitresult || hittedC )
1530  {
1531  // Trace the center ray
1532  RAY rayRTC;
1533  rayRTC.Init( ( oriRT + oriC ) * 0.5f,
1534  glm::normalize( ( dirRT + dirC ) * 0.5f ) );
1535 
1536  HITINFO hitInfoRTC;
1537  hitInfoRTC.m_tHit = std::numeric_limits<float>::infinity();
1538 
1539  bool hitted = false;
1540 
1541  if( hittedC )
1542  hitted = centerHitInfo.pHitObject->Intersect( rayRTC, hitInfoRTC );
1543  else
1544  if( hitPacket[ iRT ].m_hitresult )
1545  hitted = hitPacket[ iRT ].m_HitInfo.pHitObject->Intersect( rayRTC,
1546  hitInfoRTC );
1547 
1548  if( hitted )
1549  cRTC = CCOLORRGB( shadeHit( bgColorY, rayRTC, hitInfoRTC, false, 0, false ) );
1550  }
1551 
1552 
1553  // Trace and shade cLBC
1554  // /////////////////////////////////////////////////////////////
1555  CCOLORRGB cLBC = BlendColor( cLB , cC );
1556 
1557  if( hitPacket[ iLB ].m_hitresult || hittedC )
1558  {
1559  // Trace the center ray
1560  RAY rayLBC;
1561  rayLBC.Init( ( oriLB + oriC ) * 0.5f,
1562  glm::normalize( ( dirLB + dirC ) * 0.5f ) );
1563 
1564  HITINFO hitInfoLBC;
1565  hitInfoLBC.m_tHit = std::numeric_limits<float>::infinity();
1566 
1567  bool hitted = false;
1568 
1569  if( hittedC )
1570  hitted = centerHitInfo.pHitObject->Intersect( rayLBC, hitInfoLBC );
1571  else
1572  if( hitPacket[ iLB ].m_hitresult )
1573  hitted = hitPacket[ iLB ].m_HitInfo.pHitObject->Intersect( rayLBC,
1574  hitInfoLBC );
1575 
1576  if( hitted )
1577  cLBC = CCOLORRGB( shadeHit( bgColorY, rayLBC, hitInfoLBC, false, 0, false ) );
1578  }
1579 
1580 
1581  // Trace and shade cRBC
1582  // /////////////////////////////////////////////////////////////
1583  CCOLORRGB cRBC = BlendColor( cRB , cC );
1584 
1585  if( hitPacket[ iRB ].m_hitresult || hittedC )
1586  {
1587  // Trace the center ray
1588  RAY rayRBC;
1589  rayRBC.Init( ( oriRB + oriC ) * 0.5f,
1590  glm::normalize( ( dirRB + dirC ) * 0.5f ) );
1591 
1592  HITINFO hitInfoRBC;
1593  hitInfoRBC.m_tHit = std::numeric_limits<float>::infinity();
1594 
1595  bool hitted = false;
1596 
1597  if( hittedC )
1598  hitted = centerHitInfo.pHitObject->Intersect( rayRBC, hitInfoRBC );
1599  else
1600  if( hitPacket[ iRB ].m_hitresult )
1601  hitted = hitPacket[ iRB ].m_HitInfo.pHitObject->Intersect( rayRBC,
1602  hitInfoRBC );
1603 
1604  if( hitted )
1605  cRBC = CCOLORRGB( shadeHit( bgColorY, rayRBC, hitInfoRBC, false, 0, false ) );
1606  }
1607 
1608 
1609  // Set pixel colors
1610  // /////////////////////////////////////////////////////////////
1611 
1612  GLubyte *ptr = &ptrPBO[ (4 * x + m_blockPositionsFast[iBlock].x +
1613  m_realBufferSize.x *
1614  (m_blockPositionsFast[iBlock].y + 4 * y)) * 4 ];
1615  SetPixel( ptr + 0, cLT );
1616  SetPixel( ptr + 4, BlendColor( cLT, cLRT, cLTC ) );
1617  SetPixel( ptr + 8, cLRT );
1618  SetPixel( ptr + 12, BlendColor( cLRT, cRT, cRTC ) );
1619 
1620  ptr += m_realBufferSize.x * 4;
1621  SetPixel( ptr + 0, BlendColor( cLT , cLTB, cLTC ) );
1622  SetPixel( ptr + 4, BlendColor( cLTC, BlendColor( cLT , cC ) ) );
1623  SetPixel( ptr + 8, BlendColor( cC, BlendColor( cLRT, cLTC, cRTC ) ) );
1624  SetPixel( ptr + 12, BlendColor( cRTC, BlendColor( cRT , cC ) ) );
1625 
1626  ptr += m_realBufferSize.x * 4;
1627  SetPixel( ptr + 0, cLTB );
1628  SetPixel( ptr + 4, BlendColor( cC, BlendColor( cLTB, cLTC, cLBC ) ) );
1629  SetPixel( ptr + 8, cC );
1630  SetPixel( ptr + 12, BlendColor( cC, BlendColor( cRTB, cRTC, cRBC ) ) );
1631 
1632  ptr += m_realBufferSize.x * 4;
1633  SetPixel( ptr + 0, BlendColor( cLB , cLTB, cLBC ) );
1634  SetPixel( ptr + 4, BlendColor( cLBC, BlendColor( cLB , cC ) ) );
1635  SetPixel( ptr + 8, BlendColor( cC, BlendColor( cLRB, cLBC, cRBC ) ) );
1636  SetPixel( ptr + 12, BlendColor( cRBC, BlendColor( cRB , cC ) ) );
1637  }
1638  }
1639  }
1640 
1641  threadsFinished++;
1642  } );
1643 
1644  t.detach();
1645  }
1646 
1647  while( threadsFinished < parallelThreadCount )
1648  std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
1649 }
#define RAYPACKET_DIM
Definition: raypacket.h:37
void Init(const SFVEC3F &o, const SFVEC3F &d)
Definition: ray.cpp:40
Definition: ray.h:67
glm::ivec2 SFVEC2I
Definition: xv3d_types.h:42
float m_tHit
( 4) distance
Definition: hitinfo.h:43
SFVEC3D m_BgColorTop
background top color
glm::uvec2 SFVEC2UI
Definition: xv3d_types.h:41
CGENERICACCELERATOR * m_accelerator
SFVEC3F shadeHit(const SFVEC3F &aBgColor, const RAY &aRay, HITINFO &aHitInfo, bool aIsInsideObject, unsigned int aRecursiveLevel, bool is_testShadow) const
virtual bool Intersect(const RAY &aRay, HITINFO &aHitInfo) const =0
HITINFO m_HitInfo
Definition: hitinfo.h:63
wxSize m_windowSize
The window size that this camera is working.
const COBJECT * pHitObject
( 4) Object that was hitted
Definition: hitinfo.h:45
SFVEC3D m_BgColorBot
background bottom color
std::vector< SFVEC2UI > m_blockPositionsFast
this encodes the Morton code positions (on fast preview mode)
BOARD_ADAPTER & m_boardAdapter
settings refrence in use for this render
virtual bool Intersect(const RAY &aRay, HITINFO &aHitInfo) const =0
Functions Intersect.
static void SetPixel(GLubyte *p, const CCOLORRGB &v)
Stores the hit information of a ray with a point on the surface of a object.
Definition: hitinfo.h:40
#define RAYPACKET_RAYS_PER_PACKET
Definition: raypacket.h:40
glm::vec3 SFVEC3F
Definition: xv3d_types.h:47
CCOLORRGB BlendColor(const CCOLORRGB &aC1, const CCOLORRGB &aC2)
Definition: ccolorrgb.cpp:42
std::vector< SFVEC2UI > m_blockPositions
this encodes the Morton code positions
SFVEC3F m_HitNormal
(12) normal at the hit point
Definition: hitinfo.h:42

References BlendColor(), RAY::Init(), CGENERICACCELERATOR::Intersect(), COBJECT::Intersect(), m_accelerator, BOARD_ADAPTER::m_BgColorBot, BOARD_ADAPTER::m_BgColorTop, m_blockPositions, m_blockPositionsFast, C3D_RENDER_BASE::m_boardAdapter, C3D_RENDER_BASE::m_camera, RAY::m_Dir, HITINFO_PACKET::m_HitInfo, HITINFO::m_HitNormal, m_isPreview, RAY::m_Origin, RAYPACKET::m_ray, m_realBufferSize, HITINFO::m_tHit, C3D_RENDER_BASE::m_windowSize, m_xoffset, m_yoffset, HITINFO::pHitObject, RAYPACKET_DIM, RAYPACKET_RAYS_PER_PACKET, SetPixel(), and shadeHit().

Referenced by Redraw().

◆ restart_render_state()

void C3D_RENDER_RAYTRACING::restart_render_state ( )
private

Definition at line 126 of file c3d_render_raytracing.cpp.

127 {
129 
132 
134 
136 
137  // Mark the blocks not processed yet
138  std::fill( m_blockPositionsWasProcessed.begin(),
140  0 );
141 }
CPOSTSHADER_SSAO m_postshader_ssao
std::vector< int > m_blockPositionsWasProcessed
this flags if a position was already processed (cleared each new render)
size_t m_nrBlocksRenderProgress
Save the number of blocks progress of the render.
RT_RENDER_STATE m_rt_render_state
State used on quality render.
void InitFrame()
Definition: cpostshader.h:54
unsigned GetRunningMicroSecs()
Function GetRunningMicroSecs An alternate way to calculate an elapset time (in microsecondes) to clas...
std::vector< SFVEC2UI > m_blockPositions
this encodes the Morton code positions
unsigned long int m_stats_start_rendering_time
Time that the render starts.

References GetRunningMicroSecs(), CPOSTSHADER::InitFrame(), m_blockPositions, m_blockPositionsWasProcessed, m_nrBlocksRenderProgress, m_postshader_ssao, m_rt_render_state, m_stats_start_rendering_time, and RT_RENDER_STATE_TRACING.

Referenced by render().

◆ rt_final_color()

void C3D_RENDER_RAYTRACING::rt_final_color ( GLubyte *  ptrPBO,
const SFVEC3F rgbColor,
bool  applyColorSpaceConversion 
)
private

Definition at line 463 of file c3d_render_raytracing.cpp.

465 {
466 
467  SFVEC3F color = rgbColor;
468 
469 #ifdef USE_SRGB_SPACE
470 
471  // This should be used in future when the KiCad support a greater version of
472  // glm lib.
473  // if( applyColorSpaceConversion )
474  // rgbColor = glm::convertLinearToSRGB( rgbColor );
475 
476  if( applyColorSpaceConversion )
477  color = convertLinearToSRGB( rgbColor );
478 #endif
479 
480  ptrPBO[0] = (unsigned int)glm::clamp( (int)(color.r * 255), 0, 255 );
481  ptrPBO[1] = (unsigned int)glm::clamp( (int)(color.g * 255), 0, 255 );
482  ptrPBO[2] = (unsigned int)glm::clamp( (int)(color.b * 255), 0, 255 );
483  ptrPBO[3] = 255;
484 }
int color
Definition: DXF_plotter.cpp:61
glm::vec3 SFVEC3F
Definition: xv3d_types.h:47
static SFVEC3F convertLinearToSRGB(const SFVEC3F &aRGBcolor)

References color, and convertLinearToSRGB().

Referenced by rt_render_post_process_blur_finish(), and rt_render_trace_block().

◆ rt_render_post_process_blur_finish()

void C3D_RENDER_RAYTRACING::rt_render_post_process_blur_finish ( GLubyte *  ptrPBO,
REPORTER aStatusReporter 
)
private

Definition at line 964 of file c3d_render_raytracing.cpp.

966 {
967  (void) aStatusReporter; //unused
968 
970  {
971  // Now blurs the shader result and compute the final color
972  std::atomic<size_t> nextBlock( 0 );
973  std::atomic<size_t> threadsFinished( 0 );
974 
975  size_t parallelThreadCount = std::max<size_t>( std::thread::hardware_concurrency(), 2 );
976  for( size_t ii = 0; ii < parallelThreadCount; ++ii )
977  {
978  std::thread t = std::thread( [&]()
979  {
980  for( size_t y = nextBlock.fetch_add( 1 );
981  y < m_realBufferSize.y;
982  y = nextBlock.fetch_add( 1 ) )
983  {
984  GLubyte *ptr = &ptrPBO[ y * m_realBufferSize.x * 4 ];
985 
986  for( signed int x = 0; x < (int)m_realBufferSize.x; ++x )
987  {
988  const SFVEC3F bluredShadeColor = m_postshader_ssao.Blur( SFVEC2I( x, y ) );
989 
990 #ifdef USE_SRGB_SPACE
992 #else
993  const SFVEC3F originColor = m_postshader_ssao.GetColorAtNotProtected( SFVEC2I( x,y ) );
994 #endif
995  const SFVEC3F shadedColor = m_postshader_ssao.ApplyShadeColor( SFVEC2I( x,y ), originColor, bluredShadeColor );
996 
997  rt_final_color( ptr, shadedColor, false );
998 
999  ptr += 4;
1000  }
1001  }
1002 
1003  threadsFinished++;
1004  } );
1005 
1006  t.detach();
1007  }
1008 
1009  while( threadsFinished < parallelThreadCount )
1010  std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
1011 
1012 
1013  // Debug code
1014  //m_postshader_ssao.DebugBuffersOutputAsImages();
1015  }
1016 
1017  // End rendering
1019 }
bool GetFlag(DISPLAY3D_FLG aFlag) const
GetFlag - get a configuration status of a flag.
SFVEC3F ApplyShadeColor(const SFVEC2I &aShaderPos, const SFVEC3F &aInputColor, const SFVEC3F &aShadeColor) const override
ApplyShadeColor - apply the final color process using a previous stage color.
void rt_final_color(GLubyte *ptrPBO, const SFVEC3F &rgbColor, bool applyColorSpaceConversion)
CPOSTSHADER_SSAO m_postshader_ssao
glm::ivec2 SFVEC2I
Definition: xv3d_types.h:42
RT_RENDER_STATE m_rt_render_state
State used on quality render.
SFVEC3F Blur(const SFVEC2I &aShaderPos) const
BOARD_ADAPTER & m_boardAdapter
settings refrence in use for this render
glm::vec3 SFVEC3F
Definition: xv3d_types.h:47
static SFVEC3F convertLinearToSRGB(const SFVEC3F &aRGBcolor)
const SFVEC3F & GetColorAtNotProtected(const SFVEC2I &aPos) const

References CPOSTSHADER_SSAO::ApplyShadeColor(), CPOSTSHADER_SSAO::Blur(), convertLinearToSRGB(), FL_RENDER_RAYTRACING_POST_PROCESSING, CPOSTSHADER::GetColorAtNotProtected(), BOARD_ADAPTER::GetFlag(), C3D_RENDER_BASE::m_boardAdapter, m_postshader_ssao, m_realBufferSize, m_rt_render_state, rt_final_color(), and RT_RENDER_STATE_FINISH.

Referenced by render().

◆ rt_render_post_process_shade()

void C3D_RENDER_RAYTRACING::rt_render_post_process_shade ( GLubyte *  ptrPBO,
REPORTER aStatusReporter 
)
private

Definition at line 909 of file c3d_render_raytracing.cpp.

911 {
912  (void)ptrPBO; // unused
913 
915  {
916  if( aStatusReporter )
917  aStatusReporter->Report( _( "Rendering: Post processing shader" ) );
918 
920 
921  std::atomic<size_t> nextBlock( 0 );
922  std::atomic<size_t> threadsFinished( 0 );
923 
924  size_t parallelThreadCount = std::max<size_t>( std::thread::hardware_concurrency(), 2 );
925  for( size_t ii = 0; ii < parallelThreadCount; ++ii )
926  {
927  std::thread t = std::thread( [&]()
928  {
929  for( size_t y = nextBlock.fetch_add( 1 );
930  y < m_realBufferSize.y;
931  y = nextBlock.fetch_add( 1 ) )
932  {
933  SFVEC3F *ptr = &m_shaderBuffer[ y * m_realBufferSize.x ];
934 
935  for( signed int x = 0; x < (int)m_realBufferSize.x; ++x )
936  {
937  *ptr = m_postshader_ssao.Shade( SFVEC2I( x, y ) );
938  ptr++;
939  }
940  }
941 
942  threadsFinished++;
943  } );
944 
945  t.detach();
946  }
947 
948  while( threadsFinished < parallelThreadCount )
949  std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
950 
952 
953  // Set next state
955  }
956  else
957  {
958  // As this was an invalid state, set to finish
960  }
961 }
bool GetFlag(DISPLAY3D_FLG aFlag) const
GetFlag - get a configuration status of a flag.
SFVEC3F Shade(const SFVEC2I &aShaderPos) const override
CPOSTSHADER_SSAO m_postshader_ssao
glm::ivec2 SFVEC2I
Definition: xv3d_types.h:42
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Function Report is a pure virtual function to override in the derived object.
void SetShadowsEnabled(bool aIsShadowsEnabled)
RT_RENDER_STATE m_rt_render_state
State used on quality render.
BOARD_ADAPTER & m_boardAdapter
settings refrence in use for this render
#define _(s)
Definition: 3d_actions.cpp:33
glm::vec3 SFVEC3F
Definition: xv3d_types.h:47
void SetShadedBuffer(SFVEC3F *aShadedBuffer)

References _, FL_RENDER_RAYTRACING_POST_PROCESSING, FL_RENDER_RAYTRACING_SHADOWS, BOARD_ADAPTER::GetFlag(), C3D_RENDER_BASE::m_boardAdapter, m_postshader_ssao, m_realBufferSize, m_rt_render_state, m_shaderBuffer, REPORTER::Report(), RT_RENDER_STATE_FINISH, RT_RENDER_STATE_POST_PROCESS_BLUR_AND_FINISH, CPOSTSHADER_SSAO::SetShadedBuffer(), CPOSTSHADER_SSAO::SetShadowsEnabled(), and CPOSTSHADER_SSAO::Shade().

Referenced by render().

◆ rt_render_trace_block()

void C3D_RENDER_RAYTRACING::rt_render_trace_block ( GLubyte *  ptrPBO,
signed int  iBlock 
)
private

Definition at line 656 of file c3d_render_raytracing.cpp.

658 {
659  // Initialize ray packets
660  // /////////////////////////////////////////////////////////////////////////
661  const SFVEC2UI &blockPos = m_blockPositions[iBlock];
662  const SFVEC2I blockPosI = SFVEC2I( blockPos.x + m_xoffset,
663  blockPos.y + m_yoffset );
664 
665  RAYPACKET blockPacket( m_camera, (SFVEC2F)blockPosI + SFVEC2F(DISP_FACTOR, DISP_FACTOR),
666  SFVEC2F(DISP_FACTOR, DISP_FACTOR) /* Displacement random factor */ );
667 
668 
670 
671  HITINFO_PACKET_init( hitPacket_X0Y0 );
672 
673  // Calculate background gradient color
674  // /////////////////////////////////////////////////////////////////////////
675  SFVEC3F bgColor[RAYPACKET_DIM];// Store a vertical gradient color
676 
677  for( unsigned int y = 0; y < RAYPACKET_DIM; ++y )
678  {
679  const float posYfactor = (float)(blockPosI.y + y) / (float)m_windowSize.y;
680 
681  bgColor[y] = m_BgColorTop_LinearRGB * SFVEC3F(posYfactor) +
682  m_BgColorBot_LinearRGB * ( SFVEC3F(1.0f) - SFVEC3F(posYfactor) );
683  }
684 
685  // Intersect ray packets (calculate the intersection with rays and objects)
686  // /////////////////////////////////////////////////////////////////////////
687  if( !m_accelerator->Intersect( blockPacket, hitPacket_X0Y0 ) )
688  {
689 
690  // If block is empty then set shades and continue
692  {
693  for( unsigned int y = 0; y < RAYPACKET_DIM; ++y )
694  {
695  const SFVEC3F &outColor = bgColor[y];
696 
697  const unsigned int yBlockPos = blockPos.y + y;
698 
699  for( unsigned int x = 0; x < RAYPACKET_DIM; ++x )
700  {
701  m_postshader_ssao.SetPixelData( blockPos.x + x,
702  yBlockPos,
703  SFVEC3F( 0.0f ),
704  outColor,
705  SFVEC3F( 0.0f ),
706  0,
707  1.0f );
708  }
709  }
710  }
711 
712  // This will set the output color to be displayed
713  // If post processing is enabled, it will not reflect the final result
714  // (as the final color will be computed on post processing)
715  // but it is used for report progress
716 
717  const bool isFinalColor = !m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING );
718 
719  for( unsigned int y = 0; y < RAYPACKET_DIM; ++y )
720  {
721  const SFVEC3F &outColor = bgColor[y];
722 
723  const unsigned int yConst = blockPos.x + ( (y + blockPos.y) * m_realBufferSize.x);
724 
725  for( unsigned int x = 0; x < RAYPACKET_DIM; ++x )
726  {
727  GLubyte *ptr = &ptrPBO[ (yConst + x) * 4 ];
728 
729  rt_final_color( ptr, outColor, isFinalColor );
730  }
731  }
732 
733  // There is nothing more here to do.. there are no hits ..
734  // just background so continue
735  return;
736  }
737 
738 
739  SFVEC3F hitColor_X0Y0[RAYPACKET_RAYS_PER_PACKET];
740 
741  // Shade original (0, 0) hits ("paint" the intersected objects)
742  // /////////////////////////////////////////////////////////////////////////
743  rt_shades_packet( bgColor,
744  blockPacket.m_ray,
745  hitPacket_X0Y0,
747  hitColor_X0Y0 );
748 
750  {
751  SFVEC3F hitColor_AA_X1Y1[RAYPACKET_RAYS_PER_PACKET];
752 
753 
754  // Intersect one blockPosI + (0.5, 0.5) used for anti aliasing calculation
755  // /////////////////////////////////////////////////////////////////////////
756  HITINFO_PACKET hitPacket_AA_X1Y1[RAYPACKET_RAYS_PER_PACKET];
757  HITINFO_PACKET_init( hitPacket_AA_X1Y1 );
758 
759  RAYPACKET blockPacket_AA_X1Y1( m_camera, (SFVEC2F)blockPosI + SFVEC2F(0.5f, 0.5f),
761 
762  if( !m_accelerator->Intersect( blockPacket_AA_X1Y1, hitPacket_AA_X1Y1 ) )
763  {
764  // Missed all the package
765  for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
766  {
767  const SFVEC3F &outColor = bgColor[y];
768 
769  for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
770  {
771  hitColor_AA_X1Y1[i] = outColor;
772  }
773  }
774  }
775  else
776  {
777  rt_shades_packet( bgColor,
778  blockPacket_AA_X1Y1.m_ray,
779  hitPacket_AA_X1Y1,
781  hitColor_AA_X1Y1
782  );
783  }
784 
785  SFVEC3F hitColor_AA_X1Y0[RAYPACKET_RAYS_PER_PACKET];
786  SFVEC3F hitColor_AA_X0Y1[RAYPACKET_RAYS_PER_PACKET];
787  SFVEC3F hitColor_AA_X0Y1_half[RAYPACKET_RAYS_PER_PACKET];
788 
789  for( unsigned int i = 0; i < RAYPACKET_RAYS_PER_PACKET; ++i )
790  {
791  const SFVEC3F color_average = ( hitColor_X0Y0[i] +
792  hitColor_AA_X1Y1[i] ) * SFVEC3F(0.5f);
793 
794  hitColor_AA_X1Y0[i] = color_average;
795  hitColor_AA_X0Y1[i] = color_average;
796  hitColor_AA_X0Y1_half[i] = color_average;
797  }
798 
799  RAY blockRayPck_AA_X1Y0[RAYPACKET_RAYS_PER_PACKET];
800  RAY blockRayPck_AA_X0Y1[RAYPACKET_RAYS_PER_PACKET];
801  RAY blockRayPck_AA_X1Y1_half[RAYPACKET_RAYS_PER_PACKET];
802 
804  (SFVEC2F)blockPosI + SFVEC2F(0.5f - DISP_FACTOR, DISP_FACTOR),
805  SFVEC2F(DISP_FACTOR, DISP_FACTOR), // Displacement random factor
806  blockRayPck_AA_X1Y0 );
807 
809  (SFVEC2F)blockPosI + SFVEC2F(DISP_FACTOR, 0.5f - DISP_FACTOR),
810  SFVEC2F(DISP_FACTOR, DISP_FACTOR), // Displacement random factor
811  blockRayPck_AA_X0Y1 );
812 
814  (SFVEC2F)blockPosI + SFVEC2F(0.25f - DISP_FACTOR, 0.25f - DISP_FACTOR),
815  SFVEC2F(DISP_FACTOR, DISP_FACTOR), // Displacement random factor
816  blockRayPck_AA_X1Y1_half );
817 
818  rt_trace_AA_packet( bgColor,
819  hitPacket_X0Y0, hitPacket_AA_X1Y1,
820  blockRayPck_AA_X1Y0,
821  hitColor_AA_X1Y0 );
822 
823  rt_trace_AA_packet( bgColor,
824  hitPacket_X0Y0, hitPacket_AA_X1Y1,
825  blockRayPck_AA_X0Y1,
826  hitColor_AA_X0Y1 );
827 
828  rt_trace_AA_packet( bgColor,
829  hitPacket_X0Y0, hitPacket_AA_X1Y1,
830  blockRayPck_AA_X1Y1_half,
831  hitColor_AA_X0Y1_half );
832 
833  // Average the result
834  for( unsigned int i = 0; i < RAYPACKET_RAYS_PER_PACKET; ++i )
835  {
836  hitColor_X0Y0[i] = ( hitColor_X0Y0[i] +
837  hitColor_AA_X1Y1[i] +
838  hitColor_AA_X1Y0[i] +
839  hitColor_AA_X0Y1[i] +
840  hitColor_AA_X0Y1_half[i]
841  ) * SFVEC3F(1.0f / 5.0f);
842  }
843  }
844 
845 
846  // Copy results to the next stage
847  // /////////////////////////////////////////////////////////////////////
848 
849  GLubyte *ptr = &ptrPBO[ ( blockPos.x +
850  (blockPos.y * m_realBufferSize.x) ) * 4 ];
851 
852  const uint32_t ptrInc = (m_realBufferSize.x - RAYPACKET_DIM) * 4;
853 
855  {
856  SFVEC2I bPos;
857  bPos.y = blockPos.y;
858 
859  for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
860  {
861  bPos.x = blockPos.x;
862 
863  for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
864  {
865  const SFVEC3F &hColor = hitColor_X0Y0[i];
866 
867  if( hitPacket_X0Y0[i].m_hitresult == true )
868  m_postshader_ssao.SetPixelData( bPos.x, bPos.y,
869  hitPacket_X0Y0[i].m_HitInfo.m_HitNormal,
870  hColor,
871  blockPacket.m_ray[i].at(
872  hitPacket_X0Y0[i].m_HitInfo.m_tHit ),
873  hitPacket_X0Y0[i].m_HitInfo.m_tHit,
874  hitPacket_X0Y0[i].m_HitInfo.m_ShadowFactor );
875  else
876  m_postshader_ssao.SetPixelData( bPos.x, bPos.y,
877  SFVEC3F( 0.0f ),
878  hColor,
879  SFVEC3F( 0.0f ),
880  0,
881  1.0f );
882 
883  rt_final_color( ptr, hColor, false );
884 
885  bPos.x++;
886  ptr += 4;
887  }
888 
889  ptr += ptrInc;
890  bPos.y++;
891  }
892  }
893  else
894  {
895  for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
896  {
897  for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
898  {
899  rt_final_color( ptr, hitColor_X0Y0[i], true );
900  ptr += 4;
901  }
902 
903  ptr += ptrInc;
904  }
905  }
906 }
#define RAYPACKET_DIM
Definition: raypacket.h:37
float m_ShadowFactor
( 4) Shadow attenuation (1.0 no shadow, 0.0f darkness)
Definition: hitinfo.h:50
bool GetFlag(DISPLAY3D_FLG aFlag) const
GetFlag - get a configuration status of a flag.
void rt_shades_packet(const SFVEC3F *bgColorY, const RAY *aRayPkt, HITINFO_PACKET *aHitPacket, bool is_testShadow, SFVEC3F *aOutHitColor)
void rt_final_color(GLubyte *ptrPBO, const SFVEC3F &rgbColor, bool applyColorSpaceConversion)
CPOSTSHADER_SSAO m_postshader_ssao
Definition: ray.h:67
glm::ivec2 SFVEC2I
Definition: xv3d_types.h:42
float m_tHit
( 4) distance
Definition: hitinfo.h:43
glm::uvec2 SFVEC2UI
Definition: xv3d_types.h:41
CGENERICACCELERATOR * m_accelerator
glm::vec2 SFVEC2F
Definition: xv3d_types.h:45
virtual bool Intersect(const RAY &aRay, HITINFO &aHitInfo) const =0
HITINFO m_HitInfo
Definition: hitinfo.h:63
wxSize m_windowSize
The window size that this camera is working.
void rt_trace_AA_packet(const SFVEC3F *aBgColorY, const HITINFO_PACKET *aHitPck_X0Y0, const HITINFO_PACKET *aHitPck_AA_X1Y1, const RAY *aRayPck, SFVEC3F *aOutHitColor)
BOARD_ADAPTER & m_boardAdapter
settings refrence in use for this render
static void HITINFO_PACKET_init(HITINFO_PACKET *aHitPacket)
void SetPixelData(unsigned int x, unsigned int y, const SFVEC3F &aNormal, const SFVEC3F &aColor, const SFVEC3F &aHitPosition, float aDepth, float aShadowAttFactor)
Definition: cpostshader.cpp:78
#define RAYPACKET_RAYS_PER_PACKET
Definition: raypacket.h:40
glm::vec3 SFVEC3F
Definition: xv3d_types.h:47
#define DISP_FACTOR
std::vector< SFVEC2UI > m_blockPositions
this encodes the Morton code positions
void RAYPACKET_InitRays_with2DDisplacement(const CCAMERA &aCamera, const SFVEC2F &aWindowsPosition, const SFVEC2F &a2DWindowsPosDisplacementFactor, RAY *aRayPck)
Definition: raypacket.cpp:174

References RAY::at(), DISP_FACTOR, FL_RENDER_RAYTRACING_ANTI_ALIASING, FL_RENDER_RAYTRACING_POST_PROCESSING, FL_RENDER_RAYTRACING_SHADOWS, BOARD_ADAPTER::GetFlag(), HITINFO_PACKET_init(), CGENERICACCELERATOR::Intersect(), m_accelerator, m_BgColorBot_LinearRGB, m_BgColorTop_LinearRGB, m_blockPositions, C3D_RENDER_BASE::m_boardAdapter, C3D_RENDER_BASE::m_camera, HITINFO_PACKET::m_HitInfo, HITINFO::m_HitNormal, m_postshader_ssao, RAYPACKET::m_ray, m_realBufferSize, HITINFO::m_ShadowFactor, HITINFO::m_tHit, C3D_RENDER_BASE::m_windowSize, m_xoffset, m_yoffset, RAYPACKET_DIM, RAYPACKET_InitRays_with2DDisplacement(), RAYPACKET_RAYS_PER_PACKET, rt_final_color(), rt_shades_packet(), rt_trace_AA_packet(), and CPOSTSHADER::SetPixelData().

Referenced by rt_render_tracing().

◆ rt_render_tracing()

void C3D_RENDER_RAYTRACING::rt_render_tracing ( GLubyte *  ptrPBO,
REPORTER aStatusReporter 
)
private

Definition at line 364 of file c3d_render_raytracing.cpp.

366 {
367  m_isPreview = false;
368 
369  auto startTime = std::chrono::steady_clock::now();
370  bool breakLoop = false;
371 
372  std::atomic<size_t> numBlocksRendered( 0 );
373  std::atomic<size_t> currentBlock( 0 );
374  std::atomic<size_t> threadsFinished( 0 );
375 
376  size_t parallelThreadCount = std::min<size_t>(
377  std::max<size_t>( std::thread::hardware_concurrency(), 2 ),
378  m_blockPositions.size() );
379  for( size_t ii = 0; ii < parallelThreadCount; ++ii )
380  {
381  std::thread t = std::thread( [&]()
382  {
383  for( size_t iBlock = currentBlock.fetch_add( 1 );
384  iBlock < m_blockPositions.size() && !breakLoop;
385  iBlock = currentBlock.fetch_add( 1 ) )
386  {
387  if( !m_blockPositionsWasProcessed[iBlock] )
388  {
389  rt_render_trace_block( ptrPBO, iBlock );
390  numBlocksRendered++;
391  m_blockPositionsWasProcessed[iBlock] = 1;
392 
393  // Check if it spend already some time render and request to exit
394  // to display the progress
395  if( std::chrono::duration_cast<std::chrono::milliseconds>(
396  std::chrono::steady_clock::now() - startTime ).count() > 150 )
397  breakLoop = true;
398  }
399  }
400 
401  threadsFinished++;
402  } );
403 
404  t.detach();
405  }
406 
407  while( threadsFinished < parallelThreadCount )
408  std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
409 
410  m_nrBlocksRenderProgress += numBlocksRendered;
411 
412  if( aStatusReporter )
413  aStatusReporter->Report( wxString::Format( _( "Rendering: %.0f %%" ),
414  (float)(m_nrBlocksRenderProgress * 100) /
415  (float)m_blockPositions.size() ) );
416 
417  // Check if it finish the rendering and if should continue to a post processing
418  // or mark it as finished
420  {
423  else
425  }
426 }
bool GetFlag(DISPLAY3D_FLG aFlag) const
GetFlag - get a configuration status of a flag.
std::vector< int > m_blockPositionsWasProcessed
this flags if a position was already processed (cleared each new render)
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Function Report is a pure virtual function to override in the derived object.
size_t m_nrBlocksRenderProgress
Save the number of blocks progress of the render.
RT_RENDER_STATE m_rt_render_state
State used on quality render.
BOARD_ADAPTER & m_boardAdapter
settings refrence in use for this render
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:205
#define _(s)
Definition: 3d_actions.cpp:33
std::vector< SFVEC2UI > m_blockPositions
this encodes the Morton code positions
void rt_render_trace_block(GLubyte *ptrPBO, signed int iBlock)

References _, FL_RENDER_RAYTRACING_POST_PROCESSING, Format(), BOARD_ADAPTER::GetFlag(), m_blockPositions, m_blockPositionsWasProcessed, C3D_RENDER_BASE::m_boardAdapter, m_isPreview, m_nrBlocksRenderProgress, m_rt_render_state, REPORTER::Report(), RT_RENDER_STATE_FINISH, RT_RENDER_STATE_POST_PROCESS_SHADE, and rt_render_trace_block().

Referenced by render().

◆ rt_shades_packet()

void C3D_RENDER_RAYTRACING::rt_shades_packet ( const SFVEC3F bgColorY,
const RAY aRayPkt,
HITINFO_PACKET aHitPacket,
bool  is_testShadow,
SFVEC3F aOutHitColor 
)
private

Definition at line 501 of file c3d_render_raytracing.cpp.

506 {
507  for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
508  {
509  for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
510  {
511  if( aHitPacket[i].m_hitresult == true )
512  {
513  aOutHitColor[i] = shadeHit( bgColorY[y],
514  aRayPkt[i],
515  aHitPacket[i].m_HitInfo,
516  false,
517  0,
518  is_testShadow );
519  }
520  else
521  {
522  aOutHitColor[i] = bgColorY[y];
523  }
524  }
525  }
526 }
#define RAYPACKET_DIM
Definition: raypacket.h:37
SFVEC3F shadeHit(const SFVEC3F &aBgColor, const RAY &aRay, HITINFO &aHitInfo, bool aIsInsideObject, unsigned int aRecursiveLevel, bool is_testShadow) const

References RAYPACKET_DIM, and shadeHit().

Referenced by rt_render_trace_block().

◆ rt_trace_AA_packet()

void C3D_RENDER_RAYTRACING::rt_trace_AA_packet ( const SFVEC3F aBgColorY,
const HITINFO_PACKET aHitPck_X0Y0,
const HITINFO_PACKET aHitPck_AA_X1Y1,
const RAY aRayPck,
SFVEC3F aOutHitColor 
)
private

Definition at line 529 of file c3d_render_raytracing.cpp.

534 {
535  const bool is_testShadow = m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_SHADOWS );
536 
537  for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y )
538  {
539  for( unsigned int x = 0; x < RAYPACKET_DIM; ++x, ++i )
540  {
541  const RAY &rayAA = aRayPck[i];
542 
543  HITINFO hitAA;
544  hitAA.m_tHit = std::numeric_limits<float>::infinity();
545  hitAA.m_acc_node_info = 0;
546 
547  bool hitted = false;
548 
549  const unsigned int idx0y1 = ( x + 0 ) + RAYPACKET_DIM * ( y + 1 );
550  const unsigned int idx1y1 = ( x + 1 ) + RAYPACKET_DIM * ( y + 1 );
551 
552  // Gets the node info from the hit.
553  const unsigned int nodex0y0 = aHitPck_X0Y0[ i ].m_HitInfo.m_acc_node_info;
554  const unsigned int node_AA_x0y0 = aHitPck_AA_X1Y1[ i ].m_HitInfo.m_acc_node_info;
555 
556  unsigned int nodex1y0 = 0;
557 
558  if( x < (RAYPACKET_DIM - 1) )
559  nodex1y0 = aHitPck_X0Y0[ i + 1 ].m_HitInfo.m_acc_node_info;
560 
561  unsigned int nodex0y1 = 0;
562 
563  if( y < (RAYPACKET_DIM - 1) )
564  nodex0y1 = aHitPck_X0Y0[ idx0y1 ].m_HitInfo.m_acc_node_info;
565 
566  unsigned int nodex1y1 = 0;
567 
568  if( ((x < (RAYPACKET_DIM - 1)) &&
569  (y < (RAYPACKET_DIM - 1))) )
570  nodex1y1 = aHitPck_X0Y0[ idx1y1 ].m_HitInfo.m_acc_node_info;
571 
572 
573  if( ((nodex0y0 == nodex1y0) || (nodex1y0 == 0)) && // If all notes are equal we assume there was no change on the object hits
574  ((nodex0y0 == nodex0y1) || (nodex0y1 == 0)) &&
575  ((nodex0y0 == nodex1y1) || (nodex1y1 == 0)) &&
576  (nodex0y0 == node_AA_x0y0) )
577  {
578  // Option 1
579  // This option will give a very good quality on reflections (slow)
580  /*
581  if( m_accelerator->Intersect( rayAA, hitAA, nodex0y0 ) )
582  {
583  aOutHitColor[i] += shadeHit( aBgColorY[y], rayAA, hitAA, false, 0 );
584  }
585  else
586  {
587  if( m_accelerator->Intersect( rayAA, hitAA ) )
588  aOutHitColor[i] += shadeHit( aBgColorY[y], rayAA, hitAA, false, 0 );
589  else
590  aOutHitColor[i] += hitColor[i];
591  }
592  */
593 
594  // Option 2
595  // Trace again with the same node,
596  // then if miss just give the same color as before
597  //if( m_accelerator->Intersect( rayAA, hitAA, nodex0y0 ) )
598  // aOutHitColor[i] += shadeHit( aBgColorY[y], rayAA, hitAA, false, 0 );
599 
600  // Option 3
601  // Use same color
602 
603  }
604  else
605  {
606  // Try to intersect the different nodes
607  // It tests the possible combination of hitted or not hitted points
608  // This will try to get the best hit for this ray
609 
610  if( nodex0y0 != 0 )
611  hitted |= m_accelerator->Intersect( rayAA, hitAA, nodex0y0 );
612 
613  if( ( nodex1y0 != 0 ) &&
614  ( nodex0y0 != nodex1y0 ) )
615  hitted |= m_accelerator->Intersect( rayAA, hitAA, nodex1y0 );
616 
617  if( ( nodex0y1 != 0 ) &&
618  ( nodex0y0 != nodex0y1 ) &&
619  ( nodex1y0 != nodex0y1 ) )
620  hitted |= m_accelerator->Intersect( rayAA, hitAA, nodex0y1 );
621 
622  if( (nodex1y1 != 0 ) &&
623  ( nodex0y0 != nodex1y1 ) &&
624  ( nodex0y1 != nodex1y1 ) &&
625  ( nodex1y0 != nodex1y1 ) )
626  hitted |= m_accelerator->Intersect( rayAA, hitAA, nodex1y1 );
627 
628  if( (node_AA_x0y0 != 0 ) &&
629  ( nodex0y0 != node_AA_x0y0 ) &&
630  ( nodex0y1 != node_AA_x0y0 ) &&
631  ( nodex1y0 != node_AA_x0y0 ) &&
632  ( nodex1y1 != node_AA_x0y0 ) )
633  hitted |= m_accelerator->Intersect( rayAA, hitAA, node_AA_x0y0 );
634 
635  if( hitted )
636  {
637  // If we got any result, shade it
638  aOutHitColor[i] = shadeHit( aBgColorY[y], rayAA, hitAA, false, 0, is_testShadow );
639  }
640  else
641  {
642  // Note: There are very few cases that will end on this situation
643  // so it is not so expensive to trace a single ray from the beginning
644 
645  // It was missed the 'last nodes' so, trace a ray from the beginning
646  if( m_accelerator->Intersect( rayAA, hitAA ) )
647  aOutHitColor[i] = shadeHit( aBgColorY[y], rayAA, hitAA, false, 0, is_testShadow );
648  }
649  }
650  }
651  }
652 }
#define RAYPACKET_DIM
Definition: raypacket.h:37
bool GetFlag(DISPLAY3D_FLG aFlag) const
GetFlag - get a configuration status of a flag.
Definition: ray.h:67
float m_tHit
( 4) distance
Definition: hitinfo.h:43
CGENERICACCELERATOR * m_accelerator
SFVEC3F shadeHit(const SFVEC3F &aBgColor, const RAY &aRay, HITINFO &aHitInfo, bool aIsInsideObject, unsigned int aRecursiveLevel, bool is_testShadow) const
virtual bool Intersect(const RAY &aRay, HITINFO &aHitInfo) const =0
HITINFO m_HitInfo
Definition: hitinfo.h:63
BOARD_ADAPTER & m_boardAdapter
settings refrence in use for this render
Stores the hit information of a ray with a point on the surface of a object.
Definition: hitinfo.h:40
unsigned int m_acc_node_info
( 4) The acc stores here the node that it hits
Definition: hitinfo.h:47

References FL_RENDER_RAYTRACING_SHADOWS, BOARD_ADAPTER::GetFlag(), CGENERICACCELERATOR::Intersect(), HITINFO::m_acc_node_info, m_accelerator, C3D_RENDER_BASE::m_boardAdapter, HITINFO_PACKET::m_HitInfo, HITINFO::m_tHit, RAYPACKET_DIM, and shadeHit().

Referenced by rt_render_trace_block().

◆ SetBusyIndicatorFactory()

void C3D_RENDER_BASE::SetBusyIndicatorFactory ( BUSY_INDICATOR::FACTORY  aNewFactory)
inherited

Set a new busy indicator factory.

When set, this factory will be used to generate busy indicators when suitable. If not set, no busy indicator will be used.

Definition at line 59 of file c3d_render_base.cpp.

60 {
61  m_busyIndicatorFactory = aNewFactory;
62 }
BUSY_INDICATOR::FACTORY m_busyIndicatorFactory
Factory that returns a suitable busy indicator for the context.

References C3D_RENDER_BASE::m_busyIndicatorFactory.

◆ SetCurWindowSize()

void C3D_RENDER_RAYTRACING::SetCurWindowSize ( const wxSize &  aSize)
overridevirtual

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.

Parameters
aSizethe current size of the render window

Implements C3D_RENDER_BASE.

Definition at line 114 of file c3d_render_raytracing.cpp.

115 {
116  if( m_windowSize != aSize )
117  {
118  m_windowSize = aSize;
119  glViewport( 0, 0, m_windowSize.x, m_windowSize.y );
120 
122  }
123 }
wxSize m_windowSize
The window size that this camera is working.

References initializeNewWindowSize(), and C3D_RENDER_BASE::m_windowSize.

◆ setupMaterials()

void C3D_RENDER_RAYTRACING::setupMaterials ( )
private

Definition at line 56 of file c3d_render_createscene.cpp.

57 {
58  double mmTo3Dunits = IU_PER_MM * m_boardAdapter.BiuTo3Dunits();
59 
61  {
62  m_board_normal_perturbator = CBOARDNORMAL( 0.5f * mmTo3Dunits );
63 
64  m_copper_normal_perturbator = CCOPPERNORMAL( 4.0f * mmTo3Dunits,
66 
68 
69  m_plastic_normal_perturbator = CPLASTICNORMAL( 0.15f * mmTo3Dunits );
70 
72 
74  }
75 
76  // http://devernay.free.fr/cours/opengl/materials.html
77 
78  // Copper
81  (SFVEC3F)(0.18f), // ambient
82  SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
83  glm::clamp( ((SFVEC3F)(1.0f) -
85  SFVEC3F( 0.0f ),
86  SFVEC3F( 0.35f ) ), // specular
87  0.4f * 128.0f, // shiness
88  0.0f, // transparency
89  0.0f );
90 
92  m_materials.m_Copper.SetNormalPerturbator( &m_copper_normal_perturbator );
93 
97  SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
100  0.10f * 128.0f, // shiness
101  0.0f, // transparency
102  0.0f );
103 
104  m_materials.m_SilkS = CBLINN_PHONG_MATERIAL( ConvertSRGBToLinear( SFVEC3F( 0.11f ) ), // ambient
105  SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
106  glm::clamp(
107  ( ( SFVEC3F )( 1.0f )
109  SFVEC3F( 0.0f ),
110  SFVEC3F( 0.10f ) ), // specular
111  0.078125f * 128.0f, // shiness
112  0.0f, // transparency
113  0.0f );
114 
115  const float solderMaskTop_gray =
118  / 3.0f;
119 
120  const float solderMaskTop_transparency = solderMaskTop_gray * 0.40f + 0.005f;
121 
122  m_materials.m_SolderMask = CBLINN_PHONG_MATERIAL(
124  SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
125  glm::clamp(
126  ( ( SFVEC3F )( 1.0f )
128  SFVEC3F( 0.0f ),
129  SFVEC3F( solderMaskTop_gray * 2.0f ) ), // specular
130  0.85f * 128.0f, // shiness
131  solderMaskTop_transparency, // transparency
132  0.16f ); // reflection
133 
134  const float solderMaskBot_gray =
137  / 3.0f;
138 
139  const float solderMaskBot_transparency = solderMaskBot_gray * 0.40f + 0.005f;
140 
141  m_materials.m_SolderMask = CBLINN_PHONG_MATERIAL(
143  SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
144  glm::clamp(
145  ( ( SFVEC3F )( 1.0f )
147  SFVEC3F( 0.0f ),
148  SFVEC3F( solderMaskBot_gray * 2.0f ) ), // specular
149  0.85f * 128.0f, // shiness
150  solderMaskBot_transparency, // transparency
151  0.16f );
152 
153  m_materials.m_SolderMask.SetCastShadows( true );
154  m_materials.m_SolderMask.SetNrRefractionsSamples( 1 );
155  m_materials.m_SolderMask.SetNrReflectionsSamples( 2 );
156 
158  m_materials.m_SolderMask.SetNormalPerturbator( &m_solder_mask_normal_perturbator );
159 
160  m_materials.m_EpoxyBoard = CBLINN_PHONG_MATERIAL(
161  ConvertSRGBToLinear( SFVEC3F( 16.0f / 255.0f,
162  14.0f / 255.0f,
163  10.0f / 255.0f ) ), // ambient
164  SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
165  ConvertSRGBToLinear( SFVEC3F( 10.0f / 255.0f,
166  8.0f / 255.0f,
167  10.0f / 255.0f ) ), // specular
168  0.1f * 128.0f, // shiness
169  0.10f, // transparency
170  0.0f ); // reflection
171 
172  m_materials.m_EpoxyBoard.SetAbsorvance( 10.0f );
173  m_materials.m_EpoxyBoard.SetNrRefractionsSamples( 3 );
174 
176  m_materials.m_EpoxyBoard.SetNormalPerturbator( &m_board_normal_perturbator );
177 
179  //SFVEC3F bgBot = (SFVEC3F)m_boardAdapter.m_BgColorBot;
180 
182  bgTop * 0.125f, // ambient
183  SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
184  (SFVEC3F(1.0f) - bgTop) / 3.0f, // specular
185  0.10f * 128.0f, // shiness
186  0.0f, // transparency
187  0.50f ); // reflection
188  m_materials.m_Floor.SetCastShadows( false );
189 }
double BiuTo3Dunits() const noexcept
BiuTo3Dunits - Board integer units To 3D units.
bool GetFlag(DISPLAY3D_FLG aFlag) const
GetFlag - get a configuration status of a flag.
CPLASTICNORMAL m_plastic_normal_perturbator
SFVEC3F ConvertSRGBToLinear(const SFVEC3F &aSRGBcolor)
CBOARDNORMAL m_board_normal_perturbator
SFVEC3D m_SolderPasteColor
in realistic mode: solder paste color
static constexpr double IU_PER_MM
Mock up a conversion function.
SFVEC3D m_SolderMaskColorBot
in realistic mode: solder mask color ( bot )
CCOPPERNORMAL m_copper_normal_perturbator
CPLASTICSHINENORMAL m_plastic_shine_normal_perturbator
CMETALBRUSHEDNORMAL m_brushed_metal_normal_perturbator
SFVEC3D m_BgColorTop
background top color
Blinn Phong based material https://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model.
Definition: cmaterial.h:278
BOARD_ADAPTER & m_boardAdapter
settings refrence in use for this render
SFVEC3D m_SolderMaskColorTop
in realistic mode: solder mask color ( top )
SFVEC3D m_SilkScreenColorTop
in realistic mode: SilkScreen color ( top )
CSOLDERMASKNORMAL m_solder_mask_normal_perturbator
struct C3D_RENDER_RAYTRACING::@3 m_materials
glm::vec3 SFVEC3F
Definition: xv3d_types.h:47
SFVEC3D m_CopperColor
in realistic mode: copper color

References BOARD_ADAPTER::BiuTo3Dunits(), ConvertSRGBToLinear(), FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES, BOARD_ADAPTER::GetFlag(), IU_PER_MM, BOARD_ADAPTER::m_BgColorTop, m_board_normal_perturbator, C3D_RENDER_BASE::m_boardAdapter, m_brushed_metal_normal_perturbator, m_copper_normal_perturbator, BOARD_ADAPTER::m_CopperColor, m_materials, m_plastic_normal_perturbator, m_plastic_shine_normal_perturbator, BOARD_ADAPTER::m_SilkScreenColorTop, m_solder_mask_normal_perturbator, BOARD_ADAPTER::m_SolderMaskColorBot, BOARD_ADAPTER::m_SolderMaskColorTop, and BOARD_ADAPTER::m_SolderPasteColor.

Referenced by reload().

◆ shadeHit()

SFVEC3F C3D_RENDER_RAYTRACING::shadeHit ( const SFVEC3F aBgColor,
const RAY aRay,
HITINFO aHitInfo,
bool  aIsInsideObject,
unsigned int  aRecursiveLevel,
bool  is_testShadow 
) const
private

Definition at line 1654 of file c3d_render_raytracing.cpp.

1660 {
1661  if( aRecursiveLevel > 2 )
1662  return SFVEC3F( 0.0f );
1663 
1664  SFVEC3F hitPoint = aHitInfo.m_HitPoint;
1665 
1666  if( !m_isPreview )
1667  hitPoint += aHitInfo.m_HitNormal * m_boardAdapter.GetNonCopperLayerThickness3DU() * 0.6f;
1668 
1669  const CMATERIAL *objMaterial = aHitInfo.pHitObject->GetMaterial();
1670  wxASSERT( objMaterial != NULL );
1671 
1672  const SFVEC3F diffuseColorObj = aHitInfo.pHitObject->GetDiffuseColor( aHitInfo );
1673 
1674  SFVEC3F outColor = objMaterial->GetEmissiveColor();
1675 
1676  const LIST_LIGHT &lightList = m_lights.GetList();
1677 
1678 #if USE_EXPERIMENTAL_SOFT_SHADOWS
1679  const bool is_aa_enabled = m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_ANTI_ALIASING ) &&
1680  (!m_isPreview);
1681 #endif
1682 
1683  float shadow_att_factor_sum = 0.0f;
1684 
1685  unsigned int nr_lights_that_can_cast_shadows = 0;
1686 
1687  for( LIST_LIGHT::const_iterator ii = lightList.begin();
1688  ii != lightList.end();
1689  ++ii )
1690  {
1691  const CLIGHT *light = (CLIGHT *)*ii;
1692 
1693  SFVEC3F vectorToLight;
1694  SFVEC3F colorOfLight;
1695  float distToLight;
1696 
1697  light->GetLightParameters( hitPoint, vectorToLight, colorOfLight, distToLight );
1698 
1699  if( m_isPreview )
1700  colorOfLight = SFVEC3F( 1.0f );
1701 
1702  /*
1703  if( (!m_isPreview) &&
1704  // Little hack to make randomness to the shading and shadows
1705  m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING ) )
1706  vectorToLight = glm::normalize( vectorToLight +
1707  UniformRandomHemisphereDirection() * 0.1f );
1708  */
1709 
1710  const float NdotL = glm::dot( aHitInfo.m_HitNormal, vectorToLight );
1711 
1712  // Only calc shade if the normal is facing the direction of light,
1713  // otherwise it is in the shadow
1714  if( NdotL >= FLT_EPSILON )
1715  {
1716  float shadow_att_factor_light = 1.0f;
1717 
1718  if( is_testShadow && light->GetCastShadows() )
1719  {
1720  nr_lights_that_can_cast_shadows++;
1721 #if USE_EXPERIMENTAL_SOFT_SHADOWS
1722  if( (!is_aa_enabled) ||
1723 
1724  // For rays that are recursive, just calculate one hit shadow
1725  (aRecursiveLevel > 0) ||
1726 
1727  // Only use soft shadows if using post processing
1729  )
1730  {
1731 #endif
1732  RAY rayToLight;
1733  rayToLight.Init( hitPoint, vectorToLight );
1734 
1735  // Test if point is not in the shadow.
1736  // Test for any hit from the point in the direction of light
1737  if( m_accelerator->IntersectP( rayToLight, distToLight ) )
1738  shadow_att_factor_light = 0.0f;
1739 
1740 #if USE_EXPERIMENTAL_SOFT_SHADOWS
1741  }
1742 
1743  // Experimental softshadow calculation
1744  else
1745  {
1746 
1747  const unsigned int shadow_number_of_samples = 3;
1748  const float shadow_inc_factor = 1.0f / (float)(shadow_number_of_samples);
1749 
1750  for( unsigned int i = 0; i < shadow_number_of_samples; ++i )
1751  {
1752  const SFVEC3F unifVector = UniformRandomHemisphereDirection();
1753  const SFVEC3F disturbed_vector_to_light = glm::normalize( vectorToLight +
1754  unifVector *
1755  0.05f );
1756 
1757  RAY rayToLight;
1758  rayToLight.Init( hitPoint, disturbed_vector_to_light );
1759 
1760  // !TODO: there are multiple ways that this tests can be
1761  // optimized. Eg: by packing rays or to test against the
1762  // latest hit object.
1763 
1764  if( m_accelerator->IntersectP( rayToLight, distToLight ) )
1765  {
1766  shadow_att_factor_light -= shadow_inc_factor;
1767  }
1768  }
1769  }
1770 #endif
1771  shadow_att_factor_sum += shadow_att_factor_light;
1772  }
1773 
1775  {
1776  outColor += objMaterial->Shade( aRay,
1777  aHitInfo,
1778  NdotL,
1779  diffuseColorObj,
1780  vectorToLight,
1781  colorOfLight,
1782  shadow_att_factor_light );
1783  }
1784  else
1785  {
1786  // This is a render hack in order to compensate for the lack of
1787  // ambient and too much darkness when using post process shader
1788  // It will calculate as it was not in shadow
1789  outColor += objMaterial->Shade( aRay,
1790  aHitInfo,
1791  NdotL,
1792  diffuseColorObj,
1793  vectorToLight,
1794  colorOfLight,
1795  // The sampled point will be darkshaded by the post
1796  // processing, so here it compensates to not shadow
1797  // so much
1798  glm::mix( 0.75f, 1.0f, shadow_att_factor_light )
1799  );
1800  }
1801  }
1802  else
1803  {
1804  outColor += objMaterial->GetAmbientColor();
1805  }
1806 
1807  // Only use the headlight for preview
1808  if( m_isPreview )
1809  break;
1810  }
1811 
1812  // Improvement: this is not taking in account the lightcolor
1813  if( nr_lights_that_can_cast_shadows > 0 )
1814  {
1815  aHitInfo.m_ShadowFactor = glm::max( shadow_att_factor_sum /
1816  (float)(nr_lights_that_can_cast_shadows * 1.0f), 0.0f );
1817  }
1818  else
1819  {
1820  aHitInfo.m_ShadowFactor = 1.0f;
1821  }
1822 
1823  // Clamp color to not be brighter than 1.0f
1824  outColor = glm::min( outColor, SFVEC3F( 1.0f ) );
1825 
1826  if( !m_isPreview )
1827  {
1828  // Reflections
1829  // /////////////////////////////////////////////////////////////////////
1830 
1831  if( !aIsInsideObject &&
1832  (objMaterial->GetReflection() > 0.0f) &&
1834  {
1835  const unsigned int reflection_number_of_samples = objMaterial->GetNrReflectionsSamples();
1836 
1837  SFVEC3F sum_color = SFVEC3F(0.0f);
1838 
1839  const SFVEC3F reflectVector = aRay.m_Dir -
1840  2.0f * glm::dot( aRay.m_Dir, aHitInfo.m_HitNormal ) *
1841  aHitInfo.m_HitNormal;
1842 
1843  for( unsigned int i = 0; i < reflection_number_of_samples; ++i )
1844  {
1845  // Apply some randomize to the reflected vector
1846  const SFVEC3F random_reflectVector =
1847  glm::normalize( reflectVector +
1849  0.025f );
1850 
1851  RAY reflectedRay;
1852  reflectedRay.Init( hitPoint, random_reflectVector );
1853 
1854  HITINFO reflectedHit;
1855  reflectedHit.m_tHit = std::numeric_limits<float>::infinity();
1856 
1857  if( m_accelerator->Intersect( reflectedRay, reflectedHit ) )
1858  {
1859  sum_color += ( diffuseColorObj + objMaterial->GetSpecularColor() ) *
1860  shadeHit( aBgColor,
1861  reflectedRay,
1862  reflectedHit,
1863  false,
1864  aRecursiveLevel + 1,
1865  is_testShadow ) *
1866  SFVEC3F( objMaterial->GetReflection() *
1867  // Falloff factor
1868  (1.0f / ( 1.0f + 0.75f * reflectedHit.m_tHit *
1869  reflectedHit.m_tHit) ) );
1870  }
1871  }
1872 
1873  outColor += (sum_color / SFVEC3F( (float)reflection_number_of_samples) );
1874  }
1875 
1876 
1877  // Refractions
1878  // /////////////////////////////////////////////////////////////////////
1879 
1880  const float objTransparency = aHitInfo.pHitObject->GetModelTransparency();
1881 
1882  if( ( objTransparency > 0.0f ) &&
1884  {
1885  const float airIndex = 1.000293f;
1886  const float glassIndex = 1.49f;
1887  const float air_over_glass = airIndex / glassIndex;
1888  const float glass_over_air = glassIndex / airIndex;
1889 
1890  const float refractionRatio = aIsInsideObject?glass_over_air:air_over_glass;
1891 
1892  SFVEC3F refractedVector;
1893 
1894  if( Refract( aRay.m_Dir,
1895  aHitInfo.m_HitNormal,
1896  refractionRatio,
1897  refractedVector ) )
1898  {
1899  // This increase the start point by a "fixed" factor so it will work the
1900  // same for all distances
1901  const SFVEC3F startPoint = aRay.at( NextFloatUp(
1902  NextFloatUp(
1903  NextFloatUp( aHitInfo.m_tHit ) ) ) );
1904 
1905  const unsigned int refractions_number_of_samples = objMaterial->GetNrRefractionsSamples();
1906 
1907  SFVEC3F sum_color = SFVEC3F(0.0f);
1908 
1909  for( unsigned int i = 0; i < refractions_number_of_samples; ++i )
1910  {
1911  RAY refractedRay;
1912 
1913  if( refractions_number_of_samples > 1 )
1914  {
1915  // apply some randomize to the refracted vector
1916  const SFVEC3F randomizeRefractedVector = glm::normalize( refractedVector +
1918  0.15f *
1919  (1.0f - objTransparency) );
1920 
1921  refractedRay.Init( startPoint, randomizeRefractedVector );
1922  }
1923  else
1924  {
1925  refractedRay.Init( startPoint, refractedVector );
1926  }
1927 
1928  HITINFO refractedHit;
1929  refractedHit.m_tHit = std::numeric_limits<float>::infinity();
1930 
1931  SFVEC3F refractedColor = objMaterial->GetAmbientColor();
1932 
1933  if( m_accelerator->Intersect( refractedRay, refractedHit ) )
1934  {
1935  refractedColor = shadeHit( aBgColor,
1936  refractedRay,
1937  refractedHit,
1938  true,
1939  aRecursiveLevel + 1,
1940  false );
1941 
1942  const SFVEC3F absorbance = ( SFVEC3F(1.0f) - diffuseColorObj ) *
1943  (1.0f - objTransparency ) *
1944  objMaterial->GetAbsorvance() * // Adjust falloff factor
1945  -refractedHit.m_tHit;
1946 
1947  const SFVEC3F transparency = SFVEC3F( expf( absorbance.r ),
1948  expf( absorbance.g ),
1949  expf( absorbance.b ) );
1950 
1951  sum_color += refractedColor * transparency * objTransparency;
1952  }
1953  else
1954  {
1955  sum_color += refractedColor * objTransparency;
1956  }
1957  }
1958 
1959  outColor = outColor * (1.0f - objTransparency) +
1960  (sum_color / SFVEC3F( (float)refractions_number_of_samples) );
1961  }
1962  }
1963  }
1964 
1965  //outColor += glm::max( -glm::dot( aHitInfo.m_HitNormal, aRay.m_Dir ), 0.0f ) *
1966  // objMaterial->GetAmbientColor();
1967 
1968  return outColor;
1969 }
const SFVEC3F & GetEmissiveColor() const
Definition: cmaterial.h:209
float m_ShadowFactor
( 4) Shadow attenuation (1.0 no shadow, 0.0f darkness)
Definition: hitinfo.h:50
bool GetFlag(DISPLAY3D_FLG aFlag) const
GetFlag - get a configuration status of a flag.
A base material class that can be used to derive a material implementation.
Definition: cmaterial.h:195
void Init(const SFVEC3F &o, const SFVEC3F &d)
Definition: ray.cpp:40
virtual bool IntersectP(const RAY &aRay, float aMaxDistance) const =0
const SFVEC3F & GetSpecularColor() const
Definition: cmaterial.h:210
Definition: ray.h:67
float m_tHit
( 4) distance
Definition: hitinfo.h:43
const SFVEC3F & GetAmbientColor() const
Definition: cmaterial.h:208
unsigned int GetNrRefractionsSamples() const
Definition: cmaterial.h:216
SFVEC3F at(float t) const
Definition: ray.h:89
bool Refract(const SFVEC3F &aInVector, const SFVEC3F &aNormal, float aRin_over_Rout, SFVEC3F &aOutVector)
Refract Based on: https://github.com/mmp/pbrt-v3/blob/master/src/core/reflection.h See also: http://w...
Definition: 3d_math.h:113
virtual SFVEC3F Shade(const RAY &aRay, const HITINF