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 *aStatusTextReporter, REPORTER *aWarningTextReporter) 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 *aStatusTextReporter, REPORTER *aWarningTextReporter)
 
void restart_render_state ()
 
void rt_render_tracing (GLubyte *ptrPBO, REPORTER *aStatusTextReporter)
 
void rt_render_post_process_shade (GLubyte *ptrPBO, REPORTER *aStatusTextReporter)
 
void rt_render_post_process_blur_finish (GLubyte *ptrPBO, REPORTER *aStatusTextReporter)
 
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 *aStatusTextReporter)
 
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 1386 of file c3d_render_createscene.cpp.

1389 {
1390 
1391  // Validate a3DModel pointers
1392  wxASSERT( a3DModel != NULL );
1393 
1394  if( a3DModel == NULL )
1395  return;
1396 
1397  wxASSERT( a3DModel->m_Materials != NULL );
1398  wxASSERT( a3DModel->m_Meshes != NULL );
1399  wxASSERT( a3DModel->m_MaterialsSize > 0 );
1400  wxASSERT( a3DModel->m_MeshesSize > 0 );
1401  wxASSERT( aModuleOpacity > 0.0f );
1402  wxASSERT( aModuleOpacity <= 1.0f );
1403 
1404  if( aModuleOpacity > 1.0f )
1405  {
1406  aModuleOpacity = 1.0f;
1407  }
1408 
1409  if( (a3DModel->m_Materials != NULL) && (a3DModel->m_Meshes != NULL) &&
1410  (a3DModel->m_MaterialsSize > 0) && (a3DModel->m_MeshesSize > 0) )
1411  {
1412 
1413  MODEL_MATERIALS *materialVector;
1414 
1415  // Try find if the materials already exists in the map list
1416  if( m_model_materials.find( a3DModel ) != m_model_materials.end() )
1417  {
1418  // Found it, so get the pointer
1419  materialVector = &m_model_materials[a3DModel];
1420  }
1421  else
1422  {
1423  // Materials was not found in the map, so it will create a new for
1424  // this model.
1425 
1426  m_model_materials[a3DModel] = MODEL_MATERIALS();
1427  materialVector = &m_model_materials[a3DModel];
1428 
1429  materialVector->resize( a3DModel->m_MaterialsSize );
1430 
1431  for( unsigned int imat = 0;
1432  imat < a3DModel->m_MaterialsSize;
1433  ++imat )
1434  {
1436  {
1437  const SMATERIAL &material = a3DModel->m_Materials[imat];
1438 
1439  // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiJtaW4oc3FydCh4LTAuMzUpKjAuNDAtMC4wNSwxLjApIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiMC4wNzA3NzM2NzMyMzY1OTAxMiIsIjEuNTY5NTcxNjI5MjI1NDY5OCIsIi0wLjI3NDYzNTMyMTc1OTkyOTMiLCIwLjY0NzcwMTg4MTkyNTUzNjIiXSwic2l6ZSI6WzY0NCwzOTRdfV0-
1440 
1441  float reflectionFactor = 0.0f;
1442 
1443  if( (material.m_Shininess - 0.35f) > FLT_EPSILON )
1444  {
1445  reflectionFactor = glm::clamp( glm::sqrt( (material.m_Shininess - 0.35f) ) *
1446  0.40f - 0.05f,
1447  0.0f,
1448  0.5f );
1449  }
1450 
1451  CBLINN_PHONG_MATERIAL &blinnMaterial = (*materialVector)[imat];
1452 
1453  SFVEC3F ambient;
1454 
1456  {
1457  // apply a gain to the (dark) ambient colors
1458 
1459  // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoKHgrMC4yMCleKDEvMi4wMCkpLTAuMzUiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjAsImVxIjoieCIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0xLjI0OTUwNTMzOTIyMzYyIiwiMS42Nzc4MzQ0MTg1NjcxODQzIiwiLTAuNDM1NTA0NjQyODEwOTMwMjYiLCIxLjM2NTkzNTIwODEzNzI1OCJdLCJzaXplIjpbNjQ5LDM5OV19XQ--
1460  // ambient = glm::max( (glm::pow((material.m_Ambient + 0.20f), SFVEC3F(1.0f / 2.00f)) - SFVEC3F(0.35f)), material.m_Ambient );
1461 
1462  // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoKHgrMC4yMCleKDEvMS41OCkpLTAuMzUiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjAsImVxIjoieCIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0xLjI0OTUwNTMzOTIyMzYyIiwiMS42Nzc4MzQ0MTg1NjcxODQzIiwiLTAuNDM1NTA0NjQyODEwOTMwMjYiLCIxLjM2NTkzNTIwODEzNzI1OCJdLCJzaXplIjpbNjQ5LDM5OV19XQ--
1463  //ambient = glm::max( (glm::pow((material.m_Ambient + 0.20f), SFVEC3F(1.0f / 1.58f)) - SFVEC3F(0.35f)), material.m_Ambient );
1464 
1465  // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoKHgrMC4yMCleKDEvMS41NCkpLTAuMzQiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjAsImVxIjoieCIsImNvbG9yIjoiIzAwMDAwMCJ9LHsidHlwZSI6MTAwMCwid2luZG93IjpbIi0yLjcyMTA5NTg0MjA1MDYwNSIsIjEuODUyODcyNTI5NDk3NTIyMyIsIi0xLjQyMTM3NjAxOTkyOTA4MDYiLCIxLjM5MzM3Mzc0NzE3NzQ2MTIiXSwic2l6ZSI6WzY0OSwzOTldfV0-
1466  ambient = ConvertSRGBToLinear(
1467  glm::pow((material.m_Ambient + 0.30f), SFVEC3F(1.0f / 1.54f)) - SFVEC3F(0.34f) );
1468  }
1469  else
1470  {
1471  ambient = ConvertSRGBToLinear( material.m_Ambient );
1472  }
1473 
1474 
1475  blinnMaterial = CBLINN_PHONG_MATERIAL(
1476  ambient,
1477  ConvertSRGBToLinear( material.m_Emissive ),
1478  ConvertSRGBToLinear( material.m_Specular ),
1479  material.m_Shininess * 180.0f,
1480  material.m_Transparency,
1481  reflectionFactor );
1482 
1484  {
1485  // Guess material type and apply a normal perturbator
1486 
1487  if( ( RGBtoGray(material.m_Diffuse) < 0.3f ) &&
1488  ( material.m_Shininess < 0.36f ) &&
1489  ( material.m_Transparency == 0.0f ) &&
1490  ( (glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) < 0.15f) &&
1491  (glm::abs( material.m_Diffuse.b - material.m_Diffuse.g ) < 0.15f) &&
1492  (glm::abs( material.m_Diffuse.r - material.m_Diffuse.b ) < 0.15f) ) )
1493  {
1494  // This may be a black plastic..
1495 
1496  if( material.m_Shininess < 0.26f )
1498  else
1500  }
1501  else
1502  {
1503  if( ( RGBtoGray(material.m_Diffuse) > 0.3f ) &&
1504  ( material.m_Shininess < 0.30f ) &&
1505  ( material.m_Transparency == 0.0f ) &&
1506  ( (glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) > 0.25f) ||
1507  (glm::abs( material.m_Diffuse.b - material.m_Diffuse.g ) > 0.25f) ||
1508  (glm::abs( material.m_Diffuse.r - material.m_Diffuse.b ) > 0.25f) ) )
1509  {
1510  // This may be a color plastic ...
1512  }
1513  else
1514  {
1515  if( ( RGBtoGray(material.m_Diffuse) > 0.6f ) &&
1516  ( material.m_Shininess > 0.35f ) &&
1517  ( material.m_Transparency == 0.0f ) &&
1518  ( (glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) < 0.40f) &&
1519  (glm::abs( material.m_Diffuse.b - material.m_Diffuse.g ) < 0.40f) &&
1520  (glm::abs( material.m_Diffuse.r - material.m_Diffuse.b ) < 0.40f) ) )
1521  {
1522  // This may be a brushed metal
1524  }
1525  }
1526  }
1527  }
1528  }
1529  else
1530  {
1531  (*materialVector)[imat] = CBLINN_PHONG_MATERIAL( SFVEC3F( 0.2f ),
1532  SFVEC3F( 0.0f ),
1533  SFVEC3F( 0.0f ),
1534  0.0f,
1535  0.0f,
1536  0.0f );
1537  }
1538  }
1539  }
1540 
1541  const glm::mat3 normalMatrix = glm::transpose( glm::inverse( glm::mat3( aModelMatrix ) ) );
1542 
1543  for( unsigned int mesh_i = 0;
1544  mesh_i < a3DModel->m_MeshesSize;
1545  ++mesh_i )
1546  {
1547  const SMESH &mesh = a3DModel->m_Meshes[mesh_i];
1548 
1549  // Validate the mesh pointers
1550  wxASSERT( mesh.m_Positions != NULL );
1551  wxASSERT( mesh.m_FaceIdx != NULL );
1552  wxASSERT( mesh.m_Normals != NULL );
1553  wxASSERT( mesh.m_FaceIdxSize > 0 );
1554  wxASSERT( (mesh.m_FaceIdxSize % 3) == 0 );
1555 
1556 
1557  if( (mesh.m_Positions != NULL) &&
1558  (mesh.m_Normals != NULL) &&
1559  (mesh.m_FaceIdx != NULL) &&
1560  (mesh.m_FaceIdxSize > 0) &&
1561  (mesh.m_VertexSize > 0) &&
1562  ((mesh.m_FaceIdxSize % 3) == 0) &&
1563  (mesh.m_MaterialIdx < a3DModel->m_MaterialsSize) )
1564  {
1565  const CBLINN_PHONG_MATERIAL &blinn_material = (*materialVector)[mesh.m_MaterialIdx];
1566 
1567  const float moduleTransparency = 1.0f - ( ( 1.0f - blinn_material.GetTransparency() ) * aModuleOpacity );
1568 
1569  // Add all face triangles
1570  for( unsigned int faceIdx = 0;
1571  faceIdx < mesh.m_FaceIdxSize;
1572  faceIdx += 3 )
1573  {
1574  const unsigned int idx0 = mesh.m_FaceIdx[faceIdx + 0];
1575  const unsigned int idx1 = mesh.m_FaceIdx[faceIdx + 1];
1576  const unsigned int idx2 = mesh.m_FaceIdx[faceIdx + 2];
1577 
1578  wxASSERT( idx0 < mesh.m_VertexSize );
1579  wxASSERT( idx1 < mesh.m_VertexSize );
1580  wxASSERT( idx2 < mesh.m_VertexSize );
1581 
1582  if( ( idx0 < mesh.m_VertexSize ) &&
1583  ( idx1 < mesh.m_VertexSize ) &&
1584  ( idx2 < mesh.m_VertexSize ) )
1585  {
1586  const SFVEC3F &v0 = mesh.m_Positions[idx0];
1587  const SFVEC3F &v1 = mesh.m_Positions[idx1];
1588  const SFVEC3F &v2 = mesh.m_Positions[idx2];
1589 
1590  const SFVEC3F &n0 = mesh.m_Normals[idx0];
1591  const SFVEC3F &n1 = mesh.m_Normals[idx1];
1592  const SFVEC3F &n2 = mesh.m_Normals[idx2];
1593 
1594  // Transform vertex with the model matrix
1595  const SFVEC3F vt0 = SFVEC3F( aModelMatrix * glm::vec4( v0, 1.0f) );
1596  const SFVEC3F vt1 = SFVEC3F( aModelMatrix * glm::vec4( v1, 1.0f) );
1597  const SFVEC3F vt2 = SFVEC3F( aModelMatrix * glm::vec4( v2, 1.0f) );
1598 
1599  const SFVEC3F nt0 = glm::normalize( SFVEC3F( normalMatrix * n0 ) );
1600  const SFVEC3F nt1 = glm::normalize( SFVEC3F( normalMatrix * n1 ) );
1601  const SFVEC3F nt2 = glm::normalize( SFVEC3F( normalMatrix * n2 ) );
1602 
1603  CTRIANGLE *newTriangle = new CTRIANGLE( vt0, vt2, vt1,
1604  nt0, nt2, nt1 );
1605 
1606  m_object_container.Add( newTriangle );
1607  newTriangle->SetMaterial( (const CMATERIAL *)&blinn_material );
1608 
1609  newTriangle->SetModelTransparency( moduleTransparency );
1610 
1611  if( mesh.m_Color == NULL )
1612  {
1613  const SFVEC3F diffuseColor =
1614  a3DModel->m_Materials[mesh.m_MaterialIdx].m_Diffuse;
1615 
1617  newTriangle->SetColor( ConvertSRGBToLinear( MaterialDiffuseToColorCAD( diffuseColor ) ) );
1618  else
1619  newTriangle->SetColor( ConvertSRGBToLinear( diffuseColor ) );
1620  }
1621  else
1622  {
1624  newTriangle->SetColor( ConvertSRGBToLinear( MaterialDiffuseToColorCAD( mesh.m_Color[idx0] ) ),
1627  else
1628  newTriangle->SetColor( ConvertSRGBToLinear( mesh.m_Color[idx0] ),
1629  ConvertSRGBToLinear( mesh.m_Color[idx1] ),
1630  ConvertSRGBToLinear( mesh.m_Color[idx2] ) );
1631  }
1632  }
1633  }
1634  }
1635  }
1636  }
1637 }
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 1257 of file c3d_render_createscene.cpp.

1258 {
1259  // Insert plated vertical holes inside the board
1260  // /////////////////////////////////////////////////////////////////////////
1261 
1262  // Insert vias holes (vertical cylinders)
1263  for( auto track : m_boardAdapter.GetBoard()->Tracks() )
1264  {
1265  if( track->Type() == PCB_VIA_T )
1266  {
1267  const VIA *via = static_cast<const VIA*>(track);
1268  insert3DViaHole( via );
1269  }
1270  }
1271 
1272  // Insert pads holes (vertical cylinders)
1273  for( auto module : m_boardAdapter.GetBoard()->Modules() )
1274  {
1275  for( auto pad : module->Pads() )
1276  if( pad->GetAttribute () != PAD_ATTRIB_HOLE_NOT_PLATED )
1277  {
1278  insert3DPadHole( pad );
1279  }
1280  }
1281 }
like PAD_STANDARD, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:66
void insert3DViaHole(const VIA *aVia)
MODULES & Modules()
Definition: class_board.h:256
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:247

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 2079 of file c3d_render_raytracing.cpp.

2080 {
2081 
2082  m_realBufferSize = SFVEC2UI( 0 );
2083 
2084  // Calc block positions for fast preview mode
2085  // /////////////////////////////////////////////////////////////////////
2086  m_blockPositionsFast.clear();
2087 
2088  unsigned int i = 0;
2089 
2090  while(1)
2091  {
2092  const unsigned int mX = DecodeMorton2X(i);
2093  const unsigned int mY = DecodeMorton2Y(i);
2094 
2095  i++;
2096 
2097  const SFVEC2UI blockPos( mX * 4 * RAYPACKET_DIM - mX * 4,
2098  mY * 4 * RAYPACKET_DIM - mY * 4);
2099 
2100  if( ( blockPos.x >= ( (unsigned int)m_windowSize.x - ( 4 * RAYPACKET_DIM + 4 ) ) ) &&
2101  ( blockPos.y >= ( (unsigned int)m_windowSize.y - ( 4 * RAYPACKET_DIM + 4 ) ) ) )
2102  break;
2103 
2104  if( ( blockPos.x < ( (unsigned int)m_windowSize.x - ( 4 * RAYPACKET_DIM + 4) ) ) &&
2105  ( blockPos.y < ( (unsigned int)m_windowSize.y - ( 4 * RAYPACKET_DIM + 4) ) ) )
2106  {
2107  m_blockPositionsFast.push_back( blockPos );
2108 
2109  if( blockPos.x > m_realBufferSize.x )
2110  m_realBufferSize.x = blockPos.x;
2111 
2112  if( blockPos.y > m_realBufferSize.y )
2113  m_realBufferSize.y = blockPos.y;
2114  }
2115  }
2116 
2118 
2121 
2122  m_xoffset = (m_windowSize.x - m_realBufferSize.x) / 2;
2123  m_yoffset = (m_windowSize.y - m_realBufferSize.y) / 2;
2124 
2126 
2127 
2128  // Calc block positions for regular rendering. Choose an 'inside out'
2129  // style of rendering
2130  // /////////////////////////////////////////////////////////////////////
2131  m_blockPositions.clear();
2132  const int blocks_x = m_realBufferSize.x / RAYPACKET_DIM;
2133  const int blocks_y = m_realBufferSize.y / RAYPACKET_DIM;
2134  m_blockPositions.reserve( blocks_x * blocks_y );
2135 
2136  for( int x = 0; x < blocks_x; ++x )
2137  for( int y = 0; y < blocks_y; ++y )
2138  m_blockPositions.emplace_back( x * RAYPACKET_DIM, y * RAYPACKET_DIM );
2139 
2140  const SFVEC2UI center( m_realBufferSize.x / 2, m_realBufferSize.y / 2 );
2141  std::sort( m_blockPositions.begin(), m_blockPositions.end(),
2142  [&]( const SFVEC2UI& a, const SFVEC2UI& b ) {
2143  // Sort order: inside out.
2144  return distance( a, center ) < distance( b, center );
2145  } );
2146 
2147  // Create m_shader buffer
2148  delete[] m_shaderBuffer;
2150 
2151  opengl_init_pbo();
2152 }
#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 2029 of file c3d_render_raytracing.cpp.

2030 {
2031  opengl_init_pbo();
2032 }

References opengl_init_pbo().

Referenced by SetCurWindowSize().

◆ initializeOpenGL()

bool C3D_RENDER_RAYTRACING::initializeOpenGL ( )
private

Definition at line 2064 of file c3d_render_raytracing.cpp.

2065 {
2066  m_is_opengl_initialized = true;
2067 
2068  return true;
2069 }
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 1100 of file c3d_render_createscene.cpp.

1101 {
1102  const COBJECT2D *object2d_A = NULL;
1103 
1104  SFVEC3F objColor;
1105 
1107  objColor = (SFVEC3F)m_boardAdapter.m_CopperColor;
1108  else
1110 
1111  const wxSize drillsize = aPad->GetDrillSize();
1112  const bool hasHole = drillsize.x && drillsize.y;
1113 
1114  if( !hasHole )
1115  return;
1116 
1117  const float topZ = m_boardAdapter.GetLayerBottomZpos3DU( F_Cu ) +
1119 
1120  const float botZ = m_boardAdapter.GetLayerBottomZpos3DU( B_Cu ) -
1122 
1123  if( drillsize.x == drillsize.y ) // usual round hole
1124  {
1125  SFVEC2F center = SFVEC2F( aPad->GetPosition().x * m_boardAdapter.BiuTo3Dunits(),
1126  -aPad->GetPosition().y * m_boardAdapter.BiuTo3Dunits() );
1127 
1128  CRING2D *ring = new CRING2D( center,
1129  ( drillsize.x / 2 ) * m_boardAdapter.BiuTo3Dunits(),
1130  (( drillsize.x / 2 ) +
1133  *aPad );
1134 
1136 
1137  object2d_A = ring;
1138  }
1139  else // Oblong hole
1140  {
1141  wxPoint ends_offset;
1142  int width;
1143 
1144  if( drillsize.x > drillsize.y ) // Horizontal oval
1145  {
1146  ends_offset.x = ( drillsize.x - drillsize.y ) / 2;
1147  width = drillsize.y;
1148  }
1149  else // Vertical oval
1150  {
1151  ends_offset.y = ( drillsize.y - drillsize.x ) / 2;
1152  width = drillsize.x;
1153  }
1154 
1155  RotatePoint( &ends_offset, aPad->GetOrientation() );
1156 
1157  wxPoint start = aPad->GetPosition() + ends_offset;
1158  wxPoint end = aPad->GetPosition() - ends_offset;
1159 
1160  CROUNDSEGMENT2D *innerSeg = new CROUNDSEGMENT2D(
1161  SFVEC2F( start.x * m_boardAdapter.BiuTo3Dunits(),
1162  -start.y * m_boardAdapter.BiuTo3Dunits() ),
1164  -end.y * m_boardAdapter.BiuTo3Dunits() ),
1165  width * m_boardAdapter.BiuTo3Dunits(),
1166  *aPad );
1167 
1168  CROUNDSEGMENT2D *outerSeg = 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.GetCopperThicknessBIU() * 2 ) *
1175  *aPad );
1176 
1177  // NOTE: the round segment width is the "diameter", so we double the thickness
1178 
1179  std::vector<const COBJECT2D *> *object2d_B = new std::vector<const COBJECT2D *>();
1180  object2d_B->push_back( innerSeg );
1181 
1182  CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( outerSeg,
1183  object2d_B,
1184  CSGITEM_FULL,
1185  *aPad );
1186 
1187  m_containerWithObjectsToDelete.Add( itemCSG2d );
1188  m_containerWithObjectsToDelete.Add( innerSeg );
1189  m_containerWithObjectsToDelete.Add( outerSeg );
1190 
1191  object2d_A = itemCSG2d;
1192  }
1193 
1194 
1195  if( object2d_A )
1196  {
1197  std::vector<const COBJECT2D *> *object2d_B = new std::vector<const COBJECT2D *>();
1198 
1199  // Check if there are any other THT that intersects this hole
1200  // It will use the non inflated holes
1201  if( !m_boardAdapter.GetThroughHole_Inner().GetList().empty() )
1202  {
1203 
1204  CONST_LIST_OBJECT2D intersectionList;
1206  intersectionList );
1207 
1208  if( !intersectionList.empty() )
1209  {
1210  for( CONST_LIST_OBJECT2D::const_iterator hole = intersectionList.begin();
1211  hole != intersectionList.end();
1212  ++hole )
1213  {
1214  const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*hole);
1215 
1216  if( object2d_A->Intersects( hole2d->GetBBox() ) )
1217  //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) )
1218  object2d_B->push_back( hole2d );
1219  }
1220  }
1221  }
1222 
1223  if( object2d_B->empty() )
1224  {
1225  delete object2d_B;
1226  object2d_B = CSGITEM_EMPTY;
1227  }
1228 
1229  if( object2d_B == CSGITEM_EMPTY )
1230  {
1231  CLAYERITEM *objPtr = new CLAYERITEM( object2d_A, topZ, botZ );
1232 
1233  objPtr->SetMaterial( &m_materials.m_Copper );
1234  objPtr->SetColor( ConvertSRGBToLinear( objColor ) );
1235  m_object_container.Add( objPtr );
1236  }
1237  else
1238  {
1239  CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( object2d_A,
1240  object2d_B,
1241  CSGITEM_FULL,
1242  (const BOARD_ITEM &)*aPad );
1243 
1244  m_containerWithObjectsToDelete.Add( itemCSG2d );
1245 
1246  CLAYERITEM *objPtr = new CLAYERITEM( itemCSG2d, topZ, botZ );
1247 
1248  objPtr->SetMaterial( &m_materials.m_Copper );
1249  objPtr->SetColor( ConvertSRGBToLinear( objColor ) );
1250 
1251  m_object_container.Add( objPtr );
1252  }
1253  }
1254 }
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,...
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:411
SFVEC3F GetItemColor(int aItemId) const
GetItemColor - get the technical color of a layer.
const wxSize & GetDrillSize() const
Definition: class_pad.h:291
SFVEC3D m_CopperColor
in realistic mode: copper color
const CBBOX2D & GetBBox() const
Definition: cobject2d.h:121
const wxPoint GetPosition() const override
Definition: class_pad.h:226
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 1059 of file c3d_render_createscene.cpp.

1060 {
1061  PCB_LAYER_ID top_layer, bottom_layer;
1062  int radiusBUI = (aVia->GetDrillValue() / 2);
1063 
1064  aVia->LayerPair( &top_layer, &bottom_layer );
1065 
1066  float topZ = m_boardAdapter.GetLayerBottomZpos3DU( top_layer ) +
1068 
1069  float botZ = m_boardAdapter.GetLayerBottomZpos3DU( bottom_layer ) -
1071 
1072  const SFVEC2F center = SFVEC2F( aVia->GetStart().x * m_boardAdapter.BiuTo3Dunits(),
1073  -aVia->GetStart().y * m_boardAdapter.BiuTo3Dunits() );
1074 
1075  CRING2D *ring = new CRING2D( center,
1076  radiusBUI * m_boardAdapter.BiuTo3Dunits(),
1077  ( radiusBUI + m_boardAdapter.GetCopperThicknessBIU() ) *
1079  *aVia );
1080 
1082 
1083 
1084  CLAYERITEM *objPtr = new CLAYERITEM( ring, topZ, botZ );
1085 
1086  objPtr->SetMaterial( &m_materials.m_Copper );
1087 
1090  else
1091  objPtr->SetColor( ConvertSRGBToLinear(
1092  m_boardAdapter.GetItemColor( LAYER_VIAS + static_cast<int>( aVia->GetViaType() ) ) ) );
1093 
1094  m_object_container.Add( objPtr );
1095 }
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:366

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 1284 of file c3d_render_createscene.cpp.

1285 {
1286  // Go for all modules
1287  for( auto module : m_boardAdapter.GetBoard()->Modules() )
1288  {
1289  if((!module->Models().empty() ) &&
1290  m_boardAdapter.ShouldModuleBeDisplayed((MODULE_ATTR_T)module->GetAttributes() ) )
1291  {
1292  double zpos = m_boardAdapter.GetModulesZcoord3DIU( module->IsFlipped() );
1293 
1294  wxPoint pos = module->GetPosition();
1295 
1296  glm::mat4 moduleMatrix = glm::mat4( 1.0f );
1297 
1298  moduleMatrix = glm::translate( moduleMatrix,
1300  -pos.y * m_boardAdapter.BiuTo3Dunits(),
1301  zpos ) );
1302 
1303  if( module->GetOrientation() )
1304  {
1305  moduleMatrix = glm::rotate( moduleMatrix,
1306  ( (float)(module->GetOrientation() / 10.0f) / 180.0f ) *
1307  glm::pi<float>(),
1308  SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1309  }
1310 
1311 
1312  if( module->IsFlipped() )
1313  {
1314  moduleMatrix = glm::rotate( moduleMatrix,
1315  glm::pi<float>(),
1316  SFVEC3F( 0.0f, 1.0f, 0.0f ) );
1317 
1318  moduleMatrix = glm::rotate( moduleMatrix,
1319  glm::pi<float>(),
1320  SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1321  }
1322 
1323  const double modelunit_to_3d_units_factor = m_boardAdapter.BiuTo3Dunits() *
1325 
1326  moduleMatrix = glm::scale( moduleMatrix,
1327  SFVEC3F( modelunit_to_3d_units_factor,
1328  modelunit_to_3d_units_factor,
1329  modelunit_to_3d_units_factor ) );
1330 
1331 
1332  // Get the list of model files for this model
1334  auto sM = module->Models().begin();
1335  auto eM = module->Models().end();
1336 
1337  while( sM != eM )
1338  {
1339  if( ( static_cast<float>( sM->m_Opacity ) > FLT_EPSILON ) &&
1340  ( sM->m_Show && !sM->m_Filename.empty() ) )
1341  {
1342  // get it from cache
1343  const S3DMODEL *modelPtr = cacheMgr->GetModel( sM->m_Filename );
1344 
1345  // only add it if the return is not NULL
1346  if( modelPtr )
1347  {
1348  glm::mat4 modelMatrix = moduleMatrix;
1349 
1350  modelMatrix = glm::translate( modelMatrix,
1351  SFVEC3F( sM->m_Offset.x,
1352  sM->m_Offset.y,
1353  sM->m_Offset.z ) );
1354 
1355  modelMatrix = glm::rotate( modelMatrix,
1356  (float)-( sM->m_Rotation.z / 180.0f ) *
1357  glm::pi<float>(),
1358  SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1359 
1360  modelMatrix = glm::rotate( modelMatrix,
1361  (float)-( sM->m_Rotation.y / 180.0f ) *
1362  glm::pi<float>(),
1363  SFVEC3F( 0.0f, 1.0f, 0.0f ) );
1364 
1365  modelMatrix = glm::rotate( modelMatrix,
1366  (float)-( sM->m_Rotation.x / 180.0f ) *
1367  glm::pi<float>(),
1368  SFVEC3F( 1.0f, 0.0f, 0.0f ) );
1369 
1370  modelMatrix = glm::scale( modelMatrix,
1371  SFVEC3F( sM->m_Scale.x,
1372  sM->m_Scale.y,
1373  sM->m_Scale.z ) );
1374 
1375  add_3D_models( modelPtr, modelMatrix, (float)sM->m_Opacity );
1376  }
1377  }
1378 
1379  ++sM;
1380  }
1381  }
1382  }
1383 }
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:256
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 2035 of file c3d_render_raytracing.cpp.

2036 {
2037  if( GLEW_ARB_pixel_buffer_object )
2038  {
2040 
2041  // Try to delete vbo if it was already initialized
2043 
2044  // Learn about Pixel buffer objects at:
2045  // http://www.songho.ca/opengl/gl_pbo.html
2046  // http://web.eecs.umich.edu/~sugih/courses/eecs487/lectures/25-PBO+Mipmapping.pdf
2047  // "create 2 pixel buffer objects, you need to delete them when program exits.
2048  // glBufferDataARB with NULL pointer reserves only memory space."
2049 
2050  // This sets the number of RGBA pixels
2052 
2053  glGenBuffersARB( 1, &m_pboId );
2054  glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboId );
2055  glBufferDataARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboDataSize, 0, GL_STREAM_DRAW_ARB );
2056  glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, 0 );
2057 
2058  wxLogTrace( m_logTrace,
2059  wxT( "C3D_RENDER_RAYTRACING:: GLEW_ARB_pixel_buffer_object is supported" ) );
2060  }
2061 }
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 aStatusTextReporter,
REPORTER aWarningTextReporter 
)
overridevirtual

Redraw - Ask to redraw the view.

Parameters
aIsMovingif the user is moving the scene, it should be render in preview mode
aStatusTextReportera 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( aStatusTextReporter )
178  aStatusTextReporter->Report( _( "Loading..." ) );
179 
180  //aIsMoving = true;
181  requestRedraw = true;
182  reload( aStatusTextReporter, aWarningTextReporter );
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, aStatusTextReporter );
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 }
void reload(REPORTER *aStatusTextReporter, REPORTER *aWarningTextReporter)
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
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 render_preview(GLubyte *ptrPBO)
void render(GLubyte *ptrPBO, REPORTER *aStatusTextReporter)
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 aStatusTextReporter,
REPORTER aWarningTextReporter 
)
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( aStatusTextReporter, aWarningTextReporter );
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  if( !m_boardAdapter.GetThroughHole_Outer().GetList().empty() )
586  {
587  CONST_LIST_OBJECT2D intersectionList;
588 
590  object2d_A->GetBBox(),
591  intersectionList );
592 
593  if( !intersectionList.empty() )
594  {
595  for( CONST_LIST_OBJECT2D::const_iterator hole = intersectionList.begin();
596  hole != intersectionList.end();
597  ++hole )
598  {
599  const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*hole);
600 
601  //if( object2d_A->Intersects( hole2d->GetBBox() ) )
602  //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) )
603  object2d_B->push_back( hole2d );
604  }
605  }
606  }
607  }
608 
609 
610  const MAP_CONTAINER_2D& mapLayers = m_boardAdapter.GetMapLayers();
611 
613  ( ( ( layer_id == B_SilkS ) &&
614  ( mapLayers.find( B_Mask ) != mapLayers.end() ) ) ||
615  ( ( layer_id == F_SilkS ) &&
616  ( mapLayers.find( F_Mask ) != mapLayers.end() ) ) ) )
617  {
618  const PCB_LAYER_ID layerMask_id = ( layer_id == B_SilkS ) ? B_Mask : F_Mask;
619 
620  const CBVHCONTAINER2D *containerMaskLayer2d =
621  static_cast<const CBVHCONTAINER2D*>( mapLayers.at( layerMask_id ) );
622 
623  CONST_LIST_OBJECT2D intersectionList;
624 
625  if( containerMaskLayer2d ) // can be null if B_Mask or F_Mask is not shown
626  containerMaskLayer2d->GetListObjectsIntersects( object2d_A->GetBBox(),
627  intersectionList );
628 
629  if( !intersectionList.empty() )
630  {
631  for( CONST_LIST_OBJECT2D::const_iterator objOnLayer =
632  intersectionList.begin();
633  objOnLayer != intersectionList.end();
634  ++objOnLayer )
635  {
636  const COBJECT2D* obj2d = static_cast<const COBJECT2D*>( *objOnLayer );
637 
638  object2d_B->push_back( obj2d );
639  }
640  }
641  }
642 
643  if( object2d_B->empty() )
644  {
645  delete object2d_B;
646  object2d_B = CSGITEM_EMPTY;
647  }
648 
649  if( (object2d_B == CSGITEM_EMPTY) &&
650  (object2d_C == CSGITEM_FULL) )
651  {
652 #if 0
654  object2d_A,
657  materialLayer,
658  layerColor );
659 #else
660  CLAYERITEM *objPtr = new CLAYERITEM( object2d_A,
662  m_boardAdapter.GetLayerTopZpos3DU( layer_id ) );
663  objPtr->SetMaterial( materialLayer );
664  objPtr->SetColor( ConvertSRGBToLinear( layerColor ) );
665  m_object_container.Add( objPtr );
666 #endif
667  }
668  else
669  {
670 #if 1
671  CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( object2d_A,
672  object2d_B,
673  object2d_C,
674  object2d_A->GetBoardItem() );
675  m_containerWithObjectsToDelete.Add( itemCSG2d );
676 
677  CLAYERITEM *objPtr = new CLAYERITEM( itemCSG2d,
679  m_boardAdapter.GetLayerTopZpos3DU( layer_id ) );
680 
681  objPtr->SetMaterial( materialLayer );
682  objPtr->SetColor( ConvertSRGBToLinear( layerColor ) );
683 
684  m_object_container.Add( objPtr );
685 #endif
686  }
687  }
688  }// for each layer on map
689 
690 
691 
692  // Add Mask layer
693  // Solder mask layers are "negative" layers so the elements that we have
694  // (in the container) should remove the board outline.
695  // We will check for all objects in the outline if it intersects any object
696  // in the layer container and also any hole.
697  // /////////////////////////////////////////////////////////////////////////
699  (m_outlineBoard2dObjects->GetList().size() >= 1) )
700  {
701  const CMATERIAL *materialLayer = &m_materials.m_SolderMask;
702 
703  for( MAP_CONTAINER_2D::const_iterator ii = m_boardAdapter.GetMapLayers().begin();
704  ii != m_boardAdapter.GetMapLayers().end();
705  ++ii )
706  {
707  PCB_LAYER_ID layer_id = static_cast<PCB_LAYER_ID>(ii->first);
708 
709  const CBVHCONTAINER2D *containerLayer2d =
710  static_cast<const CBVHCONTAINER2D *>(ii->second);
711 
712  // Only get the Solder mask layers
713  if( !((layer_id == B_Mask) || (layer_id == F_Mask)) )
714  continue;
715 
716  SFVEC3F layerColor;
718  {
719  if( layer_id == B_Mask )
721  else
723  }
724  else
725  layerColor = m_boardAdapter.GetLayerColor( layer_id );
726 
727  const float zLayerMin = m_boardAdapter.GetLayerBottomZpos3DU( layer_id );
728  const float zLayerMax = m_boardAdapter.GetLayerTopZpos3DU( layer_id );
729 
730  // Get the outline board objects
731  const LIST_OBJECT2D &listObjects = m_outlineBoard2dObjects->GetList();
732 
733  for( LIST_OBJECT2D::const_iterator object2d_iterator = listObjects.begin();
734  object2d_iterator != listObjects.end();
735  ++object2d_iterator )
736  {
737  const COBJECT2D *object2d_A = static_cast<const COBJECT2D *>(*object2d_iterator);
738 
739  std::vector<const COBJECT2D *> *object2d_B = new std::vector<const COBJECT2D *>();
740 
741  // Check if there are any THT that intersects this outline object part
742  if( !m_boardAdapter.GetThroughHole_Outer().GetList().empty() )
743  {
744 
745  CONST_LIST_OBJECT2D intersectionList;
746 
748  object2d_A->GetBBox(),
749  intersectionList );
750 
751  if( !intersectionList.empty() )
752  {
753  for( CONST_LIST_OBJECT2D::const_iterator hole = intersectionList.begin();
754  hole != intersectionList.end();
755  ++hole )
756  {
757  const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*hole);
758 
759  if( object2d_A->Intersects( hole2d->GetBBox() ) )
760  //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) )
761  object2d_B->push_back( hole2d );
762  }
763  }
764  }
765 
766  // Check if there are any objects in the layer to subtract with the
767  // corrent object
768  if( !containerLayer2d->GetList().empty() )
769  {
770  CONST_LIST_OBJECT2D intersectionList;
771 
772  containerLayer2d->GetListObjectsIntersects( object2d_A->GetBBox(),
773  intersectionList );
774 
775  if( !intersectionList.empty() )
776  {
777  for( CONST_LIST_OBJECT2D::const_iterator obj = intersectionList.begin();
778  obj != intersectionList.end();
779  ++obj )
780  {
781  const COBJECT2D *obj2d = static_cast<const COBJECT2D *>(*obj);
782 
783  //if( object2d_A->Intersects( obj2d->GetBBox() ) )
784  //if( object2d_A->GetBBox().Intersects( obj2d->GetBBox() ) )
785  object2d_B->push_back( obj2d );
786  }
787  }
788  }
789 
790  if( object2d_B->empty() )
791  {
792  delete object2d_B;
793  object2d_B = CSGITEM_EMPTY;
794  }
795 
796  if( object2d_B == CSGITEM_EMPTY )
797  {
798  #if 0
800  object2d_A,
801  zLayerMin,
802  zLayerMax,
803  materialLayer,
804  layerColor );
805  #else
806  CLAYERITEM *objPtr = new CLAYERITEM( object2d_A,
807  zLayerMin,
808  zLayerMax );
809 
810  objPtr->SetMaterial( materialLayer );
811  objPtr->SetColor( ConvertSRGBToLinear( layerColor ) );
812 
813  m_object_container.Add( objPtr );
814  #endif
815  }
816  else
817  {
818  CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( object2d_A,
819  object2d_B,
820  CSGITEM_FULL,
821  object2d_A->GetBoardItem() );
822 
823  m_containerWithObjectsToDelete.Add( itemCSG2d );
824 
825  CLAYERITEM *objPtr = new CLAYERITEM( itemCSG2d,
826  zLayerMin,
827  zLayerMax );
828  objPtr->SetMaterial( materialLayer );
829  objPtr->SetColor( ConvertSRGBToLinear( layerColor ) );
830 
831  m_object_container.Add( objPtr );
832  }
833  }
834  }
835  }
836 
838 
839 #ifdef PRINT_STATISTICS_3D_VIEWER
840  unsigned stats_endConvertTime = GetRunningMicroSecs();
841  unsigned stats_startLoad3DmodelsTime = stats_endConvertTime;
842 #endif
843 
844 
845  load_3D_models();
846 
847 
848 #ifdef PRINT_STATISTICS_3D_VIEWER
849  unsigned stats_endLoad3DmodelsTime = GetRunningMicroSecs();
850 #endif
851 
852  // Add floor
853  // /////////////////////////////////////////////////////////////////////////
855  {
856  CBBOX boardBBox = m_boardAdapter.GetBBox3DU();
857 
858  if( boardBBox.IsInitialized() )
859  {
860  boardBBox.Scale( 3.0f );
861 
862  if( m_object_container.GetList().size() > 0 )
863  {
864  CBBOX containerBBox = m_object_container.GetBBox();
865 
866  containerBBox.Scale( 1.3f );
867 
868  const SFVEC3F centerBBox = containerBBox.GetCenter();
869 
870  // Floor triangles
871  const float minZ = glm::min( containerBBox.Min().z,
872  boardBBox.Min().z );
873 
874  const SFVEC3F v1 = SFVEC3F( -RANGE_SCALE_3D * 4.0f,
875  -RANGE_SCALE_3D * 4.0f,
876  minZ ) +
877  SFVEC3F( centerBBox.x,
878  centerBBox.y,
879  0.0f );
880 
881  const SFVEC3F v3 = SFVEC3F( +RANGE_SCALE_3D * 4.0f,
882  +RANGE_SCALE_3D * 4.0f,
883  minZ ) +
884  SFVEC3F( centerBBox.x,
885  centerBBox.y,
886  0.0f );
887 
888  const SFVEC3F v2 = SFVEC3F( v1.x, v3.y, v1.z );
889  const SFVEC3F v4 = SFVEC3F( v3.x, v1.y, v1.z );
890 
891  SFVEC3F backgroundColor =
892  ConvertSRGBToLinear( static_cast<SFVEC3F>( m_boardAdapter.m_BgColorTop ) );
893 
894  CTRIANGLE *newTriangle1 = new CTRIANGLE( v1, v2, v3 );
895  CTRIANGLE *newTriangle2 = new CTRIANGLE( v3, v4, v1 );
896 
897  m_object_container.Add( newTriangle1 );
898  m_object_container.Add( newTriangle2 );
899 
900  newTriangle1->SetMaterial( (const CMATERIAL *)&m_materials.m_Floor );
901  newTriangle2->SetMaterial( (const CMATERIAL *)&m_materials.m_Floor );
902 
903  newTriangle1->SetColor( backgroundColor );
904  newTriangle2->SetColor( backgroundColor );
905 
906  // Ceiling triangles
907  const float maxZ = glm::max( containerBBox.Max().z,
908  boardBBox.Max().z );
909 
910  const SFVEC3F v5 = SFVEC3F( v1.x, v1.y, maxZ );
911  const SFVEC3F v6 = SFVEC3F( v2.x, v2.y, maxZ );
912  const SFVEC3F v7 = SFVEC3F( v3.x, v3.y, maxZ );
913  const SFVEC3F v8 = SFVEC3F( v4.x, v4.y, maxZ );
914 
915  CTRIANGLE *newTriangle3 = new CTRIANGLE( v7, v6, v5 );
916  CTRIANGLE *newTriangle4 = new CTRIANGLE( v5, v8, v7 );
917 
918  m_object_container.Add( newTriangle3 );
919  m_object_container.Add( newTriangle4 );
920 
921  newTriangle3->SetMaterial( (const CMATERIAL *)&m_materials.m_Floor );
922  newTriangle4->SetMaterial( (const CMATERIAL *)&m_materials.m_Floor );
923 
924  newTriangle3->SetColor( backgroundColor );
925  newTriangle4->SetColor( backgroundColor );
926  }
927  }
928  }
929 
930 
931  // Init initial lights
932  // /////////////////////////////////////////////////////////////////////////
933  m_lights.Clear();
934 
935  // This will work as the front camera light.
936  const float light_camera_intensity = 0.20f;
937  const float light_top_bottom = 0.25f;
938  const float light_directional_intensity = ( 1.0f - ( light_camera_intensity +
939  light_top_bottom * 0.5f ) ) / 4.0f;
940 
941  m_camera_light = new CDIRECTIONALLIGHT( SFVEC3F( 0.0f, 0.0f, 0.0f ),
942  SFVEC3F( light_camera_intensity ) );
943  m_camera_light->SetCastShadows( false );
945 
946  // Option 1 - using Point Lights
947 
948  const SFVEC3F &boarCenter = m_boardAdapter.GetBBox3DU().GetCenter();
949 
950  m_lights.Add( new CPOINTLIGHT( SFVEC3F( boarCenter.x, boarCenter.y, +RANGE_SCALE_3D * 2.0f ),
951  SFVEC3F( light_top_bottom ) ) );
952 
953  m_lights.Add( new CPOINTLIGHT( SFVEC3F( boarCenter.x, boarCenter.y, -RANGE_SCALE_3D * 2.0f ),
954  SFVEC3F( light_top_bottom ) ) );
955 
956 
957  // http://www.flashandmath.com/mathlets/multicalc/coords/shilmay23fin.html
958 
959  // Option 2 - Top/Bottom direction lights
960  /*
961  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 0.03f,
962  glm::pi<float>() * 0.25f ),
963  SFVEC3F( light_top_bottom ) ) );
964 
965  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 0.97f,
966  glm::pi<float>() * 1.25f ),
967  SFVEC3F( light_top_bottom ) ) );
968  */
969 
970  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 1.0f / 8.0f,
971  glm::pi<float>() * 1 / 4.0f ),
972  SFVEC3F( light_directional_intensity ) ) );
973  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 1.0f / 8.0f,
974  glm::pi<float>() * 3 / 4.0f ),
975  SFVEC3F( light_directional_intensity ) ) );
976  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 1.0f / 8.0f,
977  glm::pi<float>() * 5 / 4.0f ),
978  SFVEC3F( light_directional_intensity ) ) );
979  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 1.0f / 8.0f,
980  glm::pi<float>() * 7 / 4.0f ),
981  SFVEC3F( light_directional_intensity ) ) );
982 
983 
984  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 7.0f / 8.0f,
985  glm::pi<float>() * 1 / 4.0f ),
986  SFVEC3F( light_directional_intensity ) ) );
987  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 7.0f / 8.0f,
988  glm::pi<float>() * 3 / 4.0f ),
989  SFVEC3F( light_directional_intensity ) ) );
990  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 7.0f / 8.0f,
991  glm::pi<float>() * 5 / 4.0f ),
992  SFVEC3F( light_directional_intensity ) ) );
993  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * 7.0f / 8.0f,
994  glm::pi<float>() * 7 / 4.0f ),
995  SFVEC3F( light_directional_intensity ) ) );
996 
997 
998  // Create an accelerator
999  // /////////////////////////////////////////////////////////////////////////
1000 
1001 #ifdef PRINT_STATISTICS_3D_VIEWER
1002  unsigned stats_startAcceleratorTime = GetRunningMicroSecs();
1003 #endif
1004 
1005  if( m_accelerator )
1006  {
1007  delete m_accelerator;
1008  }
1009  m_accelerator = 0;
1010 
1012 
1013 #ifdef PRINT_STATISTICS_3D_VIEWER
1014  unsigned stats_endAcceleratorTime = GetRunningMicroSecs();
1015 #endif
1016 
1017 #ifdef PRINT_STATISTICS_3D_VIEWER
1018  printf( "C3D_RENDER_RAYTRACING::reload times:\n" );
1019  printf( " Reload board: %.3f ms\n", (float)( stats_endReloadTime -
1020  stats_startReloadTime ) /
1021 
1022  1000.0f );
1023  printf( " Convert to 3D objects: %.3f ms\n", (float)( stats_endConvertTime -
1024  stats_startConvertTime ) /
1025  1000.0f );
1026  printf( " Accelerator construction: %.3f ms\n", (float)( stats_endAcceleratorTime -
1027  stats_startAcceleratorTime ) /
1028  1000.0f );
1029  printf( " Load and add 3D models: %.3f ms\n", (float)( stats_endLoad3DmodelsTime -
1030  stats_startLoad3DmodelsTime ) /
1031  1000.0f );
1032  printf( "Optimizations\n" );
1033 
1034  printf( " m_stats_converted_dummy_to_plane: %u\n",
1036 
1037  printf( " m_stats_converted_roundsegment2d_to_roundsegment: %u\n",
1039 
1042 #endif
1043 
1044  if( aStatusTextReporter )
1045  {
1046  // Calculation time in seconds
1047  const double calculation_time = (double)( GetRunningMicroSecs() -
1048  stats_startReloadTime ) / 1e6;
1049 
1050  aStatusTextReporter->Report( wxString::Format( _( "Reload time %.3f s" ),
1051  calculation_time ) );
1052  }
1053 }
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 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 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 )
void InitSettings(REPORTER *aStatusTextReporter, REPORTER *aWarningTextReporter)
InitSettings - Function to be called by the render when it need to reload the settings for the board.
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_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::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 aStatusTextReporter 
)
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, aStatusTextReporter );
336  break;
337 
339  rt_render_post_process_shade( ptrPBO, aStatusTextReporter );
340  break;
341 
343  rt_render_post_process_blur_finish( ptrPBO, aStatusTextReporter );
344  break;
345 
346  default:
347  wxASSERT_MSG( false, "Invalid state on m_rt_render_state");
349  break;
350  }
351 
352  if( aStatusTextReporter && (m_rt_render_state == RT_RENDER_STATE_FINISH) )
353  {
354  // Calculation time in seconds
355  const double calculation_time = (double)( GetRunningMicroSecs() -
357 
358  aStatusTextReporter->Report( wxString::Format( _( "Rendering time %.3f s" ),
359  calculation_time ) );
360  }
361 }
SFVEC3F ConvertSRGBToLinear(const SFVEC3F &aSRGBcolor)
void rt_render_post_process_shade(GLubyte *ptrPBO, REPORTER *aStatusTextReporter)
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.
void rt_render_tracing(GLubyte *ptrPBO, REPORTER *aStatusTextReporter)
void rt_render_post_process_blur_finish(GLubyte *ptrPBO, REPORTER *aStatusTextReporter)
CDIRECTIONALLIGHT * m_camera_light
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
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.

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 1079 of file c3d_render_raytracing.cpp.

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

Definition at line 960 of file c3d_render_raytracing.cpp.

962 {
963  (void)aStatusTextReporter; //unused
964 
966  {
967  // Now blurs the shader result and compute the final color
968  std::atomic<size_t> nextBlock( 0 );
969  std::atomic<size_t> threadsFinished( 0 );
970 
971  size_t parallelThreadCount = std::max<size_t>( std::thread::hardware_concurrency(), 2 );
972  for( size_t ii = 0; ii < parallelThreadCount; ++ii )
973  {
974  std::thread t = std::thread( [&]()
975  {
976  for( size_t y = nextBlock.fetch_add( 1 );
977  y < m_realBufferSize.y;
978  y = nextBlock.fetch_add( 1 ) )
979  {
980  GLubyte *ptr = &ptrPBO[ y * m_realBufferSize.x * 4 ];
981 
982  const SFVEC3F *ptrShaderY0 =
983  &m_shaderBuffer[ glm::max((int)y - 2, 0) * m_realBufferSize.x ];
984  const SFVEC3F *ptrShaderY1 =
985  &m_shaderBuffer[ glm::max((int)y - 1, 0) * m_realBufferSize.x ];
986  const SFVEC3F *ptrShaderY2 =
988  const SFVEC3F *ptrShaderY3 =
989  &m_shaderBuffer[ glm::min((int)y + 1, (int)(m_realBufferSize.y - 1)) *
990  m_realBufferSize.x ];
991  const SFVEC3F *ptrShaderY4 =
992  &m_shaderBuffer[ glm::min((int)y + 2, (int)(m_realBufferSize.y - 1)) *
993  m_realBufferSize.x ];
994 
995  for( signed int x = 0; x < (int)m_realBufferSize.x; ++x )
996  {
997  // This #if should be 1, it is here that can be used for debug proposes during development
998  #if 1
999  int idx = x > 1 ? -2 : 0;
1000  SFVEC3F bluredShadeColor = ptrShaderY0[idx] * 1.0f / 273.0f +
1001  ptrShaderY1[idx] * 4.0f / 273.0f +
1002  ptrShaderY2[idx] * 7.0f / 273.0f +
1003  ptrShaderY3[idx] * 4.0f / 273.0f +
1004  ptrShaderY4[idx] * 1.0f / 273.0f;
1005 
1006  idx = x > 0 ? -1 : 0;
1007  bluredShadeColor += ptrShaderY0[idx] * 4.0f / 273.0f +
1008  ptrShaderY1[idx] * 16.0f / 273.0f +
1009  ptrShaderY2[idx] * 26.0f / 273.0f +
1010  ptrShaderY3[idx] * 16.0f / 273.0f +
1011  ptrShaderY4[idx] * 4.0f / 273.0f;
1012 
1013  bluredShadeColor += (*ptrShaderY0) * 7.0f / 273.0f +
1014  (*ptrShaderY1) * 26.0f / 273.0f +
1015  (*ptrShaderY2) * 41.0f / 273.0f +
1016  (*ptrShaderY3) * 26.0f / 273.0f +
1017  (*ptrShaderY4) * 7.0f / 273.0f;
1018 
1019  idx = (x < (int)m_realBufferSize.x - 1) ? 1 : 0;
1020  bluredShadeColor += ptrShaderY0[idx] * 4.0f / 273.0f +
1021  ptrShaderY1[idx] *16.0f / 273.0f +
1022  ptrShaderY2[idx] *26.0f / 273.0f +
1023  ptrShaderY3[idx] *16.0f / 273.0f +
1024  ptrShaderY4[idx] * 4.0f / 273.0f;
1025 
1026  idx = (x < (int)m_realBufferSize.x - 2) ? 2 : 0;
1027  bluredShadeColor += ptrShaderY0[idx] * 1.0f / 273.0f +
1028  ptrShaderY1[idx] * 4.0f / 273.0f +
1029  ptrShaderY2[idx] * 7.0f / 273.0f +
1030  ptrShaderY3[idx] * 4.0f / 273.0f +
1031  ptrShaderY4[idx] * 1.0f / 273.0f;
1032 
1033  // process next pixel
1034  ++ptrShaderY0;
1035  ++ptrShaderY1;
1036  ++ptrShaderY2;
1037  ++ptrShaderY3;
1038  ++ptrShaderY4;
1039 
1040  #ifdef USE_SRGB_SPACE
1042  #else
1043  const SFVEC3F originColor = m_postshader_ssao.GetColorAtNotProtected( SFVEC2I( x,y ) );
1044  #endif
1045 
1046  const SFVEC3F shadedColor = m_postshader_ssao.ApplyShadeColor( SFVEC2I( x,y ), originColor, bluredShadeColor );
1047  #else
1048  // Debug code
1049  //const SFVEC3F shadedColor = SFVEC3F( 1.0f ) -
1050  // m_shaderBuffer[ y * m_realBufferSize.x + x];
1051  const SFVEC3F shadedColor = m_shaderBuffer[ y * m_realBufferSize.x + x ];
1052  #endif
1053 
1054  rt_final_color( ptr, shadedColor, false );
1055 
1056  ptr += 4;
1057  }
1058  }
1059 
1060  threadsFinished++;
1061  } );
1062 
1063  t.detach();
1064  }
1065 
1066  while( threadsFinished < parallelThreadCount )
1067  std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
1068 
1069 
1070  // Debug code
1071  //m_postshader_ssao.DebugBuffersOutputAsImages();
1072  }
1073 
1074  // End rendering
1076 }
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.
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(), 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, m_shaderBuffer, 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 aStatusTextReporter 
)
private

Definition at line 909 of file c3d_render_raytracing.cpp.

911 {
912  (void)ptrPBO; // unused
913 
915  {
916  if( aStatusTextReporter )
917  aStatusTextReporter->Report( _("Rendering: Post processing shader") );
918 
919  std::atomic<size_t> nextBlock( 0 );
920  std::atomic<size_t> threadsFinished( 0 );
921 
922  size_t parallelThreadCount = std::max<size_t>( std::thread::hardware_concurrency(), 2 );
923  for( size_t ii = 0; ii < parallelThreadCount; ++ii )
924  {
925  std::thread t = std::thread( [&]()
926  {
927  for( size_t y = nextBlock.fetch_add( 1 );
928  y < m_realBufferSize.y;
929  y = nextBlock.fetch_add( 1 ) )
930  {
931  SFVEC3F *ptr = &m_shaderBuffer[ y * m_realBufferSize.x ];
932 
933  for( signed int x = 0; x < (int)m_realBufferSize.x; ++x )
934  {
935  *ptr = m_postshader_ssao.Shade( SFVEC2I( x, y ) );
936  ptr++;
937  }
938  }
939 
940  threadsFinished++;
941  } );
942 
943  t.detach();
944  }
945 
946  while( threadsFinished < parallelThreadCount )
947  std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
948 
949  // Set next state
951  }
952  else
953  {
954  // As this was an invalid state, set to finish
956  }
957 }
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.
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

References _, FL_RENDER_RAYTRACING_POST_PROCESSING, 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, 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 aStatusTextReporter 
)
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( aStatusTextReporter )
413  aStatusTextReporter->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
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(), 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 1711 of file c3d_render_raytracing.cpp.

1717 {
1718  if( aRecursiveLevel > 2 )
1719  return SFVEC3F( 0.0f );
1720 
1721  SFVEC3F hitPoint = aHitInfo.m_HitPoint;
1722 
1723  if( !m_isPreview )
1724  hitPoint += aHitInfo.m_HitNormal * m_boardAdapter.GetNonCopperLayerThickness3DU() * 1.2f;
1725 
1726  const CMATERIAL *objMaterial = aHitInfo.pHitObject->GetMaterial();
1727  wxASSERT( objMaterial != NULL );
1728 
1729  const SFVEC3F diffuseColorObj = aHitInfo.pHitObject->GetDiffuseColor( aHitInfo );
1730 
1731  SFVEC3F outColor = objMaterial->GetEmissiveColor();
1732 
1733  const LIST_LIGHT &lightList = m_lights.GetList();
1734 
1735 #if USE_EXPERIMENTAL_SOFT_SHADOWS
1736  const bool is_aa_enabled = m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_ANTI_ALIASING ) &&
1737  (!m_isPreview);
1738 #endif
1739 
1740  float shadow_att_factor_sum = 0.0f;
1741 
1742  unsigned int nr_lights_that_can_cast_shadows = 0;
1743 
1744  for( LIST_LIGHT::const_iterator ii = lightList.begin();
1745  ii != lightList.end();
1746  ++ii )
1747  {
1748  const CLIGHT *light = (CLIGHT *)*ii;
1749 
1750  SFVEC3F vectorToLight;
1751  SFVEC3F colorOfLight;
1752  float distToLight;
1753 
1754  light->GetLightParameters( hitPoint, vectorToLight, colorOfLight, distToLight );
1755 
1756  if( m_isPreview )
1757  colorOfLight = SFVEC3F( 1.0f );
1758 
1759  /*
1760  if( (!m_isPreview) &&
1761  // Little hack to make randomness to the shading and shadows
1762  m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING ) )
1763  vectorToLight = glm::normalize( vectorToLight +
1764  UniformRandomHemisphereDirection() * 0.1f );
1765  */
1766 
1767  const float NdotL = glm::dot( aHitInfo.m_HitNormal, vectorToLight );
1768 
1769  // Only calc shade if the normal is facing the direction of light,
1770  // otherwise it is in the shadow
1771  if( NdotL >= FLT_EPSILON )
1772  {
1773  float shadow_att_factor_light = 1.0f;
1774 
1775  if( is_testShadow && light->GetCastShadows() )
1776  {
1777  nr_lights_that_can_cast_shadows++;
1778 #if USE_EXPERIMENTAL_SOFT_SHADOWS
1779  if( (!is_aa_enabled) ||
1780 
1781  // For rays that are recursive, just calculate one hit shadow
1782  (aRecursiveLevel > 0) ||
1783 
1784  // Only use soft shadows if using post processing
1786  )
1787  {
1788 #endif
1789  RAY rayToLight;
1790  rayToLight.Init( hitPoint, vectorToLight );
1791 
1792  // Test if point is not in the shadow.
1793  // Test for any hit from the point in the direction of light
1794  if( m_accelerator->IntersectP( rayToLight, distToLight ) )
1795  shadow_att_factor_light = 0.0f;
1796 
1797 #if USE_EXPERIMENTAL_SOFT_SHADOWS
1798  }
1799 
1800  // Experimental softshadow calculation
1801  else
1802  {
1803 
1804  const unsigned int shadow_number_of_samples = 3;
1805  const float shadow_inc_factor = 1.0f / (float)(shadow_number_of_samples);
1806 
1807  for( unsigned int i = 0; i < shadow_number_of_samples; ++i )
1808  {
1809  const SFVEC3F unifVector = UniformRandomHemisphereDirection();
1810  const SFVEC3F disturbed_vector_to_light = glm::normalize( vectorToLight +
1811  unifVector *
1812  0.05f );
1813 
1814  RAY rayToLight;
1815  rayToLight.Init( hitPoint, disturbed_vector_to_light );
1816 
1817  // !TODO: there are multiple ways that this tests can be
1818  // optimized. Eg: by packing rays or to test against the
1819  // latest hit object.
1820 
1821  if( m_accelerator->IntersectP( rayToLight, distToLight ) )
1822  {
1823  shadow_att_factor_light -= shadow_inc_factor;
1824  }
1825  }
1826  }
1827 #endif
1828  shadow_att_factor_sum += shadow_att_factor_light;
1829  }
1830 
1832  {
1833  outColor += objMaterial->Shade( aRay,
1834  aHitInfo,
1835  NdotL,
1836  diffuseColorObj,
1837  vectorToLight,
1838  colorOfLight,
1839  shadow_att_factor_light );
1840  }
1841  else
1842  {
1843  // This is a render hack in order to compensate for the lack of
1844  // ambient and too much darkness when using post process shader
1845  // It will calculate as it was not in shadow
1846  outColor += objMaterial->Shade( aRay,
1847  aHitInfo,
1848  NdotL,
1849  diffuseColorObj,
1850  vectorToLight,
1851  colorOfLight,
1852  // The sampled point will be darkshaded by the post
1853  // processing, so here it compensates to not shadow
1854  // so much
1855  glm::min( shadow_att_factor_light + (3.0f / 6.0f), 1.0f )
1856  );
1857  }
1858  }
1859  else
1860  {
1861  outColor += objMaterial->GetAmbientColor();
1862  }
1863 
1864  // Only use the headlight for preview
1865  if( m_isPreview )
1866  break;
1867  }
1868 
1869  // Improvement: this is not taking in account the lightcolor
1870  if( nr_lights_that_can_cast_shadows > 0 )
1871  {
1872  aHitInfo.m_ShadowFactor = glm::max( shadow_att_factor_sum /
1873  (float)(nr_lights_that_can_cast_shadows * 1.0f), 0.0f );
1874  }
1875  else
1876  {
1877  aHitInfo.m_ShadowFactor = 1.0f;
1878  }
1879 
1880  // Clamp color to not be brighter than 1.0f
1881  outColor = glm::min( outColor, SFVEC3F( 1.0f ) );
1882 
1883  if( !m_isPreview )
1884  {
1885  // Reflections
1886  // /////////////////////////////////////////////////////////////////////
1887 
1888  if( !aIsInsideObject &&
1889  (objMaterial->GetReflection() > 0.0f) &&
1891  {
1892  const unsigned int reflection_number_of_samples = objMaterial->GetNrReflectionsSamples();
1893 
1894  SFVEC3F sum_color = SFVEC3F(0.0f);
1895 
1896  const SFVEC3F reflectVector = aRay.m_Dir -
1897  2.0f * glm::dot( aRay.m_Dir, aHitInfo.m_HitNormal ) *
1898  aHitInfo.m_HitNormal;
1899 
1900  for( unsigned int i = 0; i < reflection_number_of_samples; ++i )
1901  {
1902  // Apply some randomize to the reflected vector
1903  const SFVEC3F random_reflectVector =
1904  glm::normalize( reflectVector +
1906  0.025f );
1907 
1908  RAY reflectedRay;
1909  reflectedRay.Init( hitPoint, random_reflectVector );
1910 
1911  HITINFO reflectedHit;
1912  reflectedHit.m_tHit = std::numeric_limits<float>::infinity();
1913 
1914  if( m_accelerator->Intersect( reflectedRay, reflectedHit ) )
1915  {
1916  sum_color += ( diffuseColorObj + objMaterial->GetSpecularColor() ) *
1917  shadeHit( aBgColor,
1918  reflectedRay,
1919  reflectedHit,
1920  false,
1921  aRecursiveLevel + 1,
1922  is_testShadow ) *
1923  SFVEC3F( objMaterial->GetReflection() *
1924  // Falloff factor
1925  (1.0f / ( 1.0f + 0.75f * reflectedHit.m_tHit *
1926  reflectedHit.m_tHit) ) );
1927  }
1928  }
1929 
1930  outColor += (sum_color / SFVEC3F( (float)reflection_number_of_samples) );
1931  }
1932 
1933 
1934  // Refractions
1935  // /////////////////////////////////////////////////////////////////////
1936 
1937  const float objTransparency = aHitInfo.pHitObject->GetModelTransparency();
1938 
1939  if( ( objTransparency > 0.0f ) &&
1941  {
1942  const float airIndex = 1.000293f;
1943  const float glassIndex = 1.49f;
1944  const float air_over_glass = airIndex / glassIndex;
1945  const float glass_over_air = glassIndex / airIndex;
1946 
1947  const float refractionRatio = aIsInsideObject?glass_over_air:air_over_glass;
1948 
1949  SFVEC3F refractedVector;
1950 
1951  if( Refract( aRay.m_Dir,
1952  aHitInfo.m_HitNormal,
1953  refractionRatio,
1954  refractedVector ) )
1955  {
1956  // This increase the start point by a "fixed" factor so it will work the
1957  // same for all distances
1958  const SFVEC3F startPoint = aRay.at( NextFloatUp(
1959  NextFloatUp(
1960  NextFloatUp( aHitInfo.m_tHit ) ) ) );
1961 
1962  const unsigned int refractions_number_of_samples = objMaterial->GetNrRefractionsSamples();
1963 
1964  SFVEC3F sum_color = SFVEC3F(0.0f);
1965 
1966  for( unsigned int i = 0; i < refractions_number_of_samples; ++i )
1967  {
1968  RAY refractedRay;
1969 
1970  if( refractions_number_of_samples > 1 )
1971  {
1972  // apply some randomize to the refracted vector
1973  const SFVEC3F randomizeRefractedVector = glm::normalize( refractedVector +
1975  0.15f *
1976  (1.0f - objTransparency) );
1977 
1978  refractedRay.Init( startPoint, randomizeRefractedVector );
1979  }
1980  else
1981  {
1982  refractedRay.Init( startPoint, refractedVector );
1983  }
1984 
1985  HITINFO refractedHit;
1986  refractedHit.m_tHit = std::numeric_limits<float>::infinity();
1987 
1988  SFVEC3F refractedColor = objMaterial->GetAmbientColor();
1989 
1990  if( m_accelerator->Intersect( refractedRay, refractedHit ) )
1991  {
1992  refractedColor = shadeHit( aBgColor,
1993  refractedRay,
1994  refractedHit,
1995  true,
1996  aRecursiveLevel + 1,
1997  false );
1998 
1999  const SFVEC3F absorbance = ( SFVEC3F(1.0f) - diffuseColorObj ) *
2000  (1.0f - objTransparency ) *
2001  objMaterial->GetAbsorvance() * // Adjust falloff factor
2002  -refractedHit.m_tHit;
2003 
2004  const SFVEC3F transparency = SFVEC3F( expf( absorbance.r ),
2005  expf( absorbance.g ),
2006  expf( absorbance.b ) );
2007 
2008  sum_color += refractedColor * transparency * objTransparency;
2009  }
2010  else
2011  {
2012  sum_color += refractedColor * objTransparency;
2013  }
2014  }
2015 
2016  outColor = outColor * (1.0f - objTransparency) +
2017  (sum_color / SFVEC3F( (float)refractions_number_of_samples) );
2018  }
2019  }
2020  }
2021 
2022  //outColor += glm::max( -glm::dot( aHitInfo.m_HitNormal, aRay.m_Dir ), 0.0f ) *
2023  // objMaterial->GetAmbientColor();
2024 
2025  return outColor;
2026 }
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: