KiCad PCB EDA Suite
C3D_RENDER_RAYTRACING Class Reference

#include <c3d_render_raytracing.h>

Inheritance diagram for C3D_RENDER_RAYTRACING:
C3D_RENDER_BASE

Public Member Functions

 C3D_RENDER_RAYTRACING (BOARD_ADAPTER &aAdapter, CCAMERA &aCamera)
 
 ~C3D_RENDER_RAYTRACING ()
 
void SetCurWindowSize (const wxSize &aSize) override
 SetCurWindowSize - Before each render, the canvas will tell the render what is the size of its windows, so render can take actions if it changed. More...
 
bool Redraw (bool aIsMoving, REPORTER *aStatusReporter, REPORTER *aWarningReporter) override
 Redraw - Ask to redraw the view. More...
 
int GetWaitForEditingTimeOut () override
 GetWaitForEditingTimeOut - Give the interface the time (in ms) that it should wait for editing or movements before (this works for display preview mode) More...
 
void Reload (REPORTER *aStatusReporter, REPORTER *aWarningReporter, bool aOnlyLoadCopperAndShapes)
 
BOARD_ITEMIntersectBoardItem (const RAY &aRay)
 
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 createItemsFromContainer (const CBVHCONTAINER2D *aContainer2d, PCB_LAYER_ID aLayer_id, const CMATERIAL *aMaterialLayer, const SFVEC3F &aLayerColor, float aLayerZOffset)
 
void restart_render_state ()
 
void rt_render_tracing (GLubyte *ptrPBO, REPORTER *aStatusReporter)
 
void rt_render_post_process_shade (GLubyte *ptrPBO, REPORTER *aStatusReporter)
 
void rt_render_post_process_blur_finish (GLubyte *ptrPBO, REPORTER *aStatusReporter)
 
void rt_render_trace_block (GLubyte *ptrPBO, signed int iBlock)
 
void rt_final_color (GLubyte *ptrPBO, const SFVEC3F &rgbColor, bool applyColorSpaceConversion)
 
void rt_shades_packet (const SFVEC3F *bgColorY, const RAY *aRayPkt, HITINFO_PACKET *aHitPacket, bool is_testShadow, SFVEC3F *aOutHitColor)
 
void rt_trace_AA_packet (const SFVEC3F *aBgColorY, const HITINFO_PACKET *aHitPck_X0Y0, const HITINFO_PACKET *aHitPck_AA_X1Y1, const RAY *aRayPck, SFVEC3F *aOutHitColor)
 
void setupMaterials ()
 
SFVEC3F shadeHit (const SFVEC3F &aBgColor, const RAY &aRay, HITINFO &aHitInfo, bool aIsInsideObject, unsigned int aRecursiveLevel, bool is_testShadow) const
 
void create_3d_object_from (CCONTAINER &aDstContainer, const COBJECT2D *aObject2D, float aZMin, float aZMax, const CMATERIAL *aMaterial, const SFVEC3F &aObjColor)
 Function create_3d_object_from. More...
 
void add_3D_vias_and_pads_to_container ()
 
void insert3DViaHole (const VIA *aVia)
 
void insert3DPadHole (const D_PAD *aPad)
 
void load_3D_models (CCONTAINER &aDstContainer, bool aSkipMaterialInformation)
 
void add_3D_models (CCONTAINER &aDstContainer, const S3DMODEL *a3DModel, const glm::mat4 &aModelMatrix, float aModuleOpacity, bool aSkipMaterialInformation, BOARD_ITEM *aBoardItem)
 
MODEL_MATERIALSget_3D_model_material (const S3DMODEL *a3DModel)
 
void initialize_block_positions ()
 
void render (GLubyte *ptrPBO, REPORTER *aStatusReporter)
 
void render_preview (GLubyte *ptrPBO)
 

Private Attributes

struct {
   CBLINN_PHONG_MATERIAL   m_Paste
 
   CBLINN_PHONG_MATERIAL   m_SilkS
 
   CBLINN_PHONG_MATERIAL   m_SolderMask
 
   CBLINN_PHONG_MATERIAL   m_EpoxyBoard
 
   CBLINN_PHONG_MATERIAL   m_Copper
 
   CBLINN_PHONG_MATERIAL   m_NonPlatedCopper
 
   CBLINN_PHONG_MATERIAL   m_Floor
 
m_materials
 
CBOARDNORMAL m_board_normal_perturbator
 
CCOPPERNORMAL m_copper_normal_perturbator
 
CPLATEDCOPPERNORMAL m_platedcopper_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 ( CCONTAINER aDstContainer,
const S3DMODEL a3DModel,
const glm::mat4 &  aModelMatrix,
float  aModuleOpacity,
bool  aSkipMaterialInformation,
BOARD_ITEM aBoardItem 
)
private

Definition at line 1486 of file c3d_render_createscene.cpp.

1492 {
1493 
1494  // Validate a3DModel pointers
1495  wxASSERT( a3DModel != NULL );
1496 
1497  if( a3DModel == NULL )
1498  return;
1499 
1500  wxASSERT( a3DModel->m_Materials != NULL );
1501  wxASSERT( a3DModel->m_Meshes != NULL );
1502  wxASSERT( a3DModel->m_MaterialsSize > 0 );
1503  wxASSERT( a3DModel->m_MeshesSize > 0 );
1504  wxASSERT( aModuleOpacity > 0.0f );
1505  wxASSERT( aModuleOpacity <= 1.0f );
1506 
1507  if( aModuleOpacity > 1.0f )
1508  {
1509  aModuleOpacity = 1.0f;
1510  }
1511 
1512  if( (a3DModel->m_Materials != NULL) && (a3DModel->m_Meshes != NULL) &&
1513  (a3DModel->m_MaterialsSize > 0) && (a3DModel->m_MeshesSize > 0) )
1514  {
1515 
1516  MODEL_MATERIALS *materialVector = NULL;
1517 
1518  if( !aSkipMaterialInformation )
1519  {
1520  materialVector = get_3D_model_material( a3DModel );
1521  }
1522 
1523  const glm::mat3 normalMatrix = glm::transpose( glm::inverse( glm::mat3( aModelMatrix ) ) );
1524 
1525  for( unsigned int mesh_i = 0;
1526  mesh_i < a3DModel->m_MeshesSize;
1527  ++mesh_i )
1528  {
1529  const SMESH &mesh = a3DModel->m_Meshes[mesh_i];
1530 
1531  // Validate the mesh pointers
1532  wxASSERT( mesh.m_Positions != NULL );
1533  wxASSERT( mesh.m_FaceIdx != NULL );
1534  wxASSERT( mesh.m_Normals != NULL );
1535  wxASSERT( mesh.m_FaceIdxSize > 0 );
1536  wxASSERT( (mesh.m_FaceIdxSize % 3) == 0 );
1537 
1538 
1539  if( (mesh.m_Positions != NULL) &&
1540  (mesh.m_Normals != NULL) &&
1541  (mesh.m_FaceIdx != NULL) &&
1542  (mesh.m_FaceIdxSize > 0) &&
1543  (mesh.m_VertexSize > 0) &&
1544  ((mesh.m_FaceIdxSize % 3) == 0) &&
1545  (mesh.m_MaterialIdx < a3DModel->m_MaterialsSize) )
1546  {
1547  float moduleTransparency;
1548  const CBLINN_PHONG_MATERIAL *blinn_material;
1549 
1550  if( !aSkipMaterialInformation )
1551  {
1552  blinn_material = &(*materialVector)[mesh.m_MaterialIdx];
1553 
1554  moduleTransparency = 1.0f - ( ( 1.0f - blinn_material->GetTransparency() ) * aModuleOpacity );
1555  }
1556 
1557  // Add all face triangles
1558  for( unsigned int faceIdx = 0;
1559  faceIdx < mesh.m_FaceIdxSize;
1560  faceIdx += 3 )
1561  {
1562  const unsigned int idx0 = mesh.m_FaceIdx[faceIdx + 0];
1563  const unsigned int idx1 = mesh.m_FaceIdx[faceIdx + 1];
1564  const unsigned int idx2 = mesh.m_FaceIdx[faceIdx + 2];
1565 
1566  wxASSERT( idx0 < mesh.m_VertexSize );
1567  wxASSERT( idx1 < mesh.m_VertexSize );
1568  wxASSERT( idx2 < mesh.m_VertexSize );
1569 
1570  if( ( idx0 < mesh.m_VertexSize ) &&
1571  ( idx1 < mesh.m_VertexSize ) &&
1572  ( idx2 < mesh.m_VertexSize ) )
1573  {
1574  const SFVEC3F &v0 = mesh.m_Positions[idx0];
1575  const SFVEC3F &v1 = mesh.m_Positions[idx1];
1576  const SFVEC3F &v2 = mesh.m_Positions[idx2];
1577 
1578  const SFVEC3F &n0 = mesh.m_Normals[idx0];
1579  const SFVEC3F &n1 = mesh.m_Normals[idx1];
1580  const SFVEC3F &n2 = mesh.m_Normals[idx2];
1581 
1582  // Transform vertex with the model matrix
1583  const SFVEC3F vt0 = SFVEC3F( aModelMatrix * glm::vec4( v0, 1.0f) );
1584  const SFVEC3F vt1 = SFVEC3F( aModelMatrix * glm::vec4( v1, 1.0f) );
1585  const SFVEC3F vt2 = SFVEC3F( aModelMatrix * glm::vec4( v2, 1.0f) );
1586 
1587  const SFVEC3F nt0 = glm::normalize( SFVEC3F( normalMatrix * n0 ) );
1588  const SFVEC3F nt1 = glm::normalize( SFVEC3F( normalMatrix * n1 ) );
1589  const SFVEC3F nt2 = glm::normalize( SFVEC3F( normalMatrix * n2 ) );
1590 
1591  CTRIANGLE *newTriangle = new CTRIANGLE( vt0, vt2, vt1,
1592  nt0, nt2, nt1 );
1593 
1594  newTriangle->SetBoardItem( aBoardItem );
1595 
1596  aDstContainer.Add( newTriangle );
1597 
1598  if( !aSkipMaterialInformation )
1599  {
1600  newTriangle->SetMaterial( blinn_material );
1601  newTriangle->SetModelTransparency( moduleTransparency );
1602 
1603  if( mesh.m_Color == NULL )
1604  {
1605  const SFVEC3F diffuseColor =
1606  a3DModel->m_Materials[mesh.m_MaterialIdx].m_Diffuse;
1607 
1609  newTriangle->SetColor( ConvertSRGBToLinear( MaterialDiffuseToColorCAD( diffuseColor ) ) );
1610  else
1611  newTriangle->SetColor( ConvertSRGBToLinear( diffuseColor ) );
1612  }
1613  else
1614  {
1616  newTriangle->SetColor( ConvertSRGBToLinear( MaterialDiffuseToColorCAD( mesh.m_Color[idx0] ) ),
1619  else
1620  newTriangle->SetColor( ConvertSRGBToLinear( mesh.m_Color[idx0] ),
1621  ConvertSRGBToLinear( mesh.m_Color[idx1] ),
1622  ConvertSRGBToLinear( mesh.m_Color[idx2] ) );
1623  }
1624  }
1625  }
1626  }
1627  }
1628  }
1629  }
1630 }
Use a gray shading based on diffuse material.
SFVEC3F * m_Normals
Vertex normals array.
Definition: c3dmodel.h:80
SFVEC3F ConvertSRGBToLinear(const SFVEC3F &aSRGBcolor)
MODEL_MATERIALS * get_3D_model_material(const S3DMODEL *a3DModel)
void SetMaterial(const CMATERIAL *aMaterial)
Definition: cobject.h:72
SFVEC3F * m_Positions
Vertex position array.
Definition: c3dmodel.h:79
const void SetBoardItem(BOARD_ITEM *aBoardItem)
Definition: cobject.h:69
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
void SetModelTransparency(float aModelTransparency)
Definition: cobject.h:80
Blinn Phong based material https://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model.
Definition: cmaterial.h:318
SFVEC3F * m_Color
Vertex color array, can be NULL.
Definition: c3dmodel.h:82
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:247
SFVEC3F MaterialDiffuseToColorCAD(const SFVEC3F &aDiffuseColor)
Definition: 3d_math.h:154
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

References CGENERICCONTAINER::Add(), CAD_MODE, ConvertSRGBToLinear(), get_3D_model_material(), CMATERIAL::GetTransparency(), C3D_RENDER_BASE::m_boardAdapter, SMESH::m_Color, SMATERIAL::m_Diffuse, SMESH::m_FaceIdx, SMESH::m_FaceIdxSize, SMESH::m_MaterialIdx, S3DMODEL::m_Materials, S3DMODEL::m_MaterialsSize, S3DMODEL::m_Meshes, S3DMODEL::m_MeshesSize, SMESH::m_Normals, SMESH::m_Positions, SMESH::m_VertexSize, MaterialDiffuseToColorCAD(), BOARD_ADAPTER::MaterialModeGet(), NULL, COBJECT::SetBoardItem(), CTRIANGLE::SetColor(), COBJECT::SetMaterial(), and COBJECT::SetModelTransparency().

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

1242 {
1243  // Insert plated vertical holes inside the board
1244  // /////////////////////////////////////////////////////////////////////////
1245 
1246  // Insert vias holes (vertical cylinders)
1247  for( auto track : m_boardAdapter.GetBoard()->Tracks() )
1248  {
1249  if( track->Type() == PCB_VIA_T )
1250  {
1251  const VIA *via = static_cast<const VIA*>(track);
1252  insert3DViaHole( via );
1253  }
1254  }
1255 
1256  // Insert pads holes (vertical cylinders)
1257  for( auto module : m_boardAdapter.GetBoard()->Modules() )
1258  {
1259  for( auto pad : module->Pads() )
1260  if( pad->GetAttribute () != PAD_ATTRIB_NPTH )
1261  {
1262  insert3DPadHole( pad );
1263  }
1264  }
1265 }
void insert3DViaHole(const VIA *aVia)
like PAD_PTH, but not plated mechanical use only, no connection allowed
Definition: pad_shapes.h:85
MODULES & Modules()
Definition: class_board.h:284
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:281

References BOARD_ADAPTER::GetBoard(), insert3DPadHole(), insert3DViaHole(), C3D_RENDER_BASE::m_boardAdapter, BOARD::Modules(), PAD_ATTRIB_NPTH, 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 217 of file c3d_render_createscene.cpp.

220 {
221  switch( aObject2D->GetObjectType() )
222  {
224  {
226 #if 1
227  CXYPLANE* objPtr;
228  objPtr = new CXYPLANE( CBBOX(
229  SFVEC3F( aObject2D->GetBBox().Min().x, aObject2D->GetBBox().Min().y, aZMin ),
230  SFVEC3F( aObject2D->GetBBox().Max().x, aObject2D->GetBBox().Max().y, aZMin ) ) );
231  objPtr->SetMaterial( aMaterial );
232  objPtr->SetColor( ConvertSRGBToLinear( aObjColor ) );
233  aDstContainer.Add( objPtr );
234 
235  objPtr = new CXYPLANE( CBBOX(
236  SFVEC3F( aObject2D->GetBBox().Min().x, aObject2D->GetBBox().Min().y, aZMax ),
237  SFVEC3F( aObject2D->GetBBox().Max().x, aObject2D->GetBBox().Max().y, aZMax ) ) );
238  objPtr->SetMaterial( aMaterial );
239  objPtr->SetColor( ConvertSRGBToLinear( aObjColor ) );
240  aDstContainer.Add( objPtr );
241 #else
242  objPtr = new CDUMMYBLOCK( CBBOX(
243  SFVEC3F( aObject2D->GetBBox().Min().x, aObject2D->GetBBox().Min().y, aZMin ),
244  SFVEC3F( aObject2D->GetBBox().Max().x, aObject2D->GetBBox().Max().y, aZMax ) ) );
245  objPtr->SetMaterial( aMaterial );
246  aDstContainer.Add( objPtr );
247 #endif
248  }
249  break;
250 
252  {
254 
255  const CROUNDSEGMENT2D* aRoundSeg2D = static_cast<const CROUNDSEGMENT2D*>( aObject2D );
256  CROUNDSEG* objPtr = new CROUNDSEG( *aRoundSeg2D, aZMin, aZMax );
257  objPtr->SetMaterial( aMaterial );
258  objPtr->SetColor( ConvertSRGBToLinear( aObjColor ) );
259  aDstContainer.Add( objPtr );
260  }
261  break;
262 
263 
264  default:
265  {
266  CLAYERITEM* objPtr = new CLAYERITEM( aObject2D, aZMin, aZMax );
267  objPtr->SetMaterial( aMaterial );
268  objPtr->SetColor( ConvertSRGBToLinear( aObjColor ) );
269  aDstContainer.Add( objPtr );
270  }
271  break;
272  }
273 }
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:72
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:39

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().

◆ createItemsFromContainer()

void C3D_RENDER_RAYTRACING::createItemsFromContainer ( const CBVHCONTAINER2D aContainer2d,
PCB_LAYER_ID  aLayer_id,
const CMATERIAL aMaterialLayer,
const SFVEC3F aLayerColor,
float  aLayerZOffset 
)
private

Definition at line 275 of file c3d_render_createscene.cpp.

280 {
281  if( aContainer2d == nullptr )
282  return;
283 
284  const LIST_OBJECT2D &listObject2d = aContainer2d->GetList();
285 
286  if( listObject2d.size() == 0 )
287  return;
288 
289  for( LIST_OBJECT2D::const_iterator itemOnLayer = listObject2d.begin();
290  itemOnLayer != listObject2d.end();
291  ++itemOnLayer )
292  {
293  const COBJECT2D *object2d_A = static_cast<const COBJECT2D *>(*itemOnLayer);
294 
295  // not yet used / implemented (can be used in future to clip the objects in the board borders
296  COBJECT2D *object2d_C = CSGITEM_FULL;
297 
298  std::vector<const COBJECT2D *> *object2d_B = CSGITEM_EMPTY;
299 
300  object2d_B = new std::vector<const COBJECT2D*>();
301 
302  // Subtract holes but not in SolderPaste
303  // (can be added as an option in future)
304  if( !( ( aLayer_id == B_Paste ) || ( aLayer_id == F_Paste ) ) )
305  {
306  // Check if there are any layerhole that intersects this object
307  // Eg: a segment is cutted by a via hole or THT hole.
308  // /////////////////////////////////////////////////////////////
309  const MAP_CONTAINER_2D &layerHolesMap = m_boardAdapter.GetMapLayersHoles();
310 
311  if( layerHolesMap.find(aLayer_id) != layerHolesMap.end() )
312  {
313  MAP_CONTAINER_2D::const_iterator ii_hole = layerHolesMap.find(aLayer_id);
314 
315  const CBVHCONTAINER2D *containerLayerHoles2d =
316  static_cast<const CBVHCONTAINER2D *>(ii_hole->second);
317 
318  CONST_LIST_OBJECT2D intersectionList;
319  containerLayerHoles2d->GetListObjectsIntersects( object2d_A->GetBBox(),
320  intersectionList );
321 
322  if( !intersectionList.empty() )
323  {
324  for( CONST_LIST_OBJECT2D::const_iterator holeOnLayer =
325  intersectionList.begin();
326  holeOnLayer != intersectionList.end();
327  ++holeOnLayer )
328  {
329  const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*holeOnLayer);
330 
331  //if( object2d_A->Intersects( hole2d->GetBBox() ) )
332  //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) )
333  object2d_B->push_back( hole2d );
334  }
335  }
336  }
337 
338  // Check if there are any THT that intersects this object
339  // /////////////////////////////////////////////////////////////
340 
341  // If we're processing a silk screen layer and the flag is set, then
342  // clip the silk screening at the outer edge of the annular ring, rather
343  // than the at the outer edge of the copper plating.
344  const CBVHCONTAINER2D& throughHoleOuter =
346  && ( ( aLayer_id == B_SilkS ) || ( aLayer_id == F_SilkS ) ) ) ?
349 
350  if( !throughHoleOuter.GetList().empty() )
351  {
352  CONST_LIST_OBJECT2D intersectionList;
353 
354  throughHoleOuter.GetListObjectsIntersects(
355  object2d_A->GetBBox(), intersectionList );
356 
357  if( !intersectionList.empty() )
358  {
359  for( CONST_LIST_OBJECT2D::const_iterator hole = intersectionList.begin();
360  hole != intersectionList.end();
361  ++hole )
362  {
363  const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*hole);
364 
365  //if( object2d_A->Intersects( hole2d->GetBBox() ) )
366  //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) )
367  object2d_B->push_back( hole2d );
368  }
369  }
370  }
371  }
372 
373 
374  const MAP_CONTAINER_2D& mapLayers = m_boardAdapter.GetMapLayers();
375 
377  ( ( ( aLayer_id == B_SilkS ) &&
378  ( mapLayers.find( B_Mask ) != mapLayers.end() ) ) ||
379  ( ( aLayer_id == F_SilkS ) &&
380  ( mapLayers.find( F_Mask ) != mapLayers.end() ) ) ) )
381  {
382  const PCB_LAYER_ID layerMask_id = ( aLayer_id == B_SilkS ) ? B_Mask : F_Mask;
383 
384  const CBVHCONTAINER2D *containerMaskLayer2d =
385  static_cast<const CBVHCONTAINER2D*>( mapLayers.at( layerMask_id ) );
386 
387  CONST_LIST_OBJECT2D intersectionList;
388 
389  if( containerMaskLayer2d ) // can be null if B_Mask or F_Mask is not shown
390  containerMaskLayer2d->GetListObjectsIntersects( object2d_A->GetBBox(),
391  intersectionList );
392 
393  if( !intersectionList.empty() )
394  {
395  for( CONST_LIST_OBJECT2D::const_iterator objOnLayer =
396  intersectionList.begin();
397  objOnLayer != intersectionList.end();
398  ++objOnLayer )
399  {
400  const COBJECT2D* obj2d = static_cast<const COBJECT2D*>( *objOnLayer );
401 
402  object2d_B->push_back( obj2d );
403  }
404  }
405  }
406 
407  if( object2d_B->empty() )
408  {
409  delete object2d_B;
410  object2d_B = CSGITEM_EMPTY;
411  }
412 
413  if( (object2d_B == CSGITEM_EMPTY) &&
414  (object2d_C == CSGITEM_FULL) )
415  {
416  CLAYERITEM *objPtr = new CLAYERITEM( object2d_A,
417  m_boardAdapter.GetLayerBottomZpos3DU( aLayer_id ) - aLayerZOffset,
418  m_boardAdapter.GetLayerTopZpos3DU( aLayer_id ) + aLayerZOffset );
419  objPtr->SetMaterial( aMaterialLayer );
420  objPtr->SetColor( ConvertSRGBToLinear( aLayerColor ) );
421  m_object_container.Add( objPtr );
422  }
423  else
424  {
425  CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( object2d_A,
426  object2d_B,
427  object2d_C,
428  object2d_A->GetBoardItem() );
429  m_containerWithObjectsToDelete.Add( itemCSG2d );
430 
431  CLAYERITEM *objPtr = new CLAYERITEM( itemCSG2d,
432  m_boardAdapter.GetLayerBottomZpos3DU( aLayer_id ) - aLayerZOffset,
433  m_boardAdapter.GetLayerTopZpos3DU( aLayer_id ) + aLayerZOffset );
434 
435  objPtr->SetMaterial( aMaterialLayer );
436  objPtr->SetColor( ConvertSRGBToLinear( aLayerColor ) );
437 
438  m_object_container.Add( objPtr );
439  }
440  }
441 }
void GetListObjectsIntersects(const CBBOX2D &aBBox, CONST_LIST_OBJECT2D &aOutList) const override
GetListObjectsIntersects - Get a list of objects that intersects a bbox.
bool GetFlag(DISPLAY3D_FLG aFlag) const
GetFlag - get a configuration status of a flag.
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
SFVEC3F ConvertSRGBToLinear(const SFVEC3F &aSRGBcolor)
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
float GetLayerTopZpos3DU(PCB_LAYER_ID aLayerId) const noexcept
GetLayerTopZpos3DU - Get the top z position.
void SetMaterial(const CMATERIAL *aMaterial)
Definition: cobject.h:72
const MAP_CONTAINER_2D & GetMapLayers() const noexcept
GetMapLayers - Get the map of container that have the objects per layer.
#define CSGITEM_EMPTY
This class is used to make constructive solig geometry for items objects on layers.
const BOARD_ITEM & GetBoardItem() const
Definition: cobject2d.h:75
PCB_LAYER_ID
A quick note on layer IDs:
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.
CCONTAINER2D m_containerWithObjectsToDelete
This will store the list of created objects special for RT, that will be clear in the end.
#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
const CBVHCONTAINER2D & GetThroughHole_Outer_Ring() const noexcept
GetThroughHole_Outer_Ring - Get the ThroughHole container that include the width of the annular ring.
void Add(COBJECT2D *aObject)
Definition: ccontainer2d.h:52
std::list< COBJECT2D * > LIST_OBJECT2D
Definition: ccontainer2d.h:37
const CBBOX2D & GetBBox() const
Definition: cobject2d.h:121
const LIST_OBJECT2D & GetList() const
Definition: ccontainer2d.h:64

References CGENERICCONTAINER::Add(), CGENERICCONTAINER2D::Add(), B_Mask, B_Paste, B_SilkS, ConvertSRGBToLinear(), CSGITEM_EMPTY, CSGITEM_FULL, F_Mask, F_Paste, F_SilkS, FL_CLIP_SILK_ON_VIA_ANNULUS, FL_SUBTRACT_MASK_FROM_SILK, COBJECT2D::GetBBox(), COBJECT2D::GetBoardItem(), BOARD_ADAPTER::GetFlag(), BOARD_ADAPTER::GetLayerBottomZpos3DU(), BOARD_ADAPTER::GetLayerTopZpos3DU(), CGENERICCONTAINER2D::GetList(), CBVHCONTAINER2D::GetListObjectsIntersects(), BOARD_ADAPTER::GetMapLayers(), BOARD_ADAPTER::GetMapLayersHoles(), BOARD_ADAPTER::GetThroughHole_Outer(), BOARD_ADAPTER::GetThroughHole_Outer_Ring(), C3D_RENDER_BASE::m_boardAdapter, m_containerWithObjectsToDelete, m_object_container, CLAYERITEM::SetColor(), and COBJECT::SetMaterial().

Referenced by Reload().

◆ get_3D_model_material()

MODEL_MATERIALS * C3D_RENDER_RAYTRACING::get_3D_model_material ( const S3DMODEL a3DModel)
private

Definition at line 1375 of file c3d_render_createscene.cpp.

1376 {
1377  MODEL_MATERIALS *materialVector;
1378 
1379  // Try find if the materials already exists in the map list
1380  if( m_model_materials.find( a3DModel ) != m_model_materials.end() )
1381  {
1382  // Found it, so get the pointer
1383  materialVector = &m_model_materials[a3DModel];
1384  }
1385  else
1386  {
1387  // Materials was not found in the map, so it will create a new for
1388  // this model.
1389 
1390  m_model_materials[a3DModel] = MODEL_MATERIALS();
1391  materialVector = &m_model_materials[a3DModel];
1392 
1393  materialVector->resize( a3DModel->m_MaterialsSize );
1394 
1395  for( unsigned int imat = 0;
1396  imat < a3DModel->m_MaterialsSize;
1397  ++imat )
1398  {
1400  {
1401  const SMATERIAL &material = a3DModel->m_Materials[imat];
1402 
1403  // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiJtaW4oc3FydCh4LTAuMzUpKjAuNDAtMC4wNSwxLjApIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiMC4wNzA3NzM2NzMyMzY1OTAxMiIsIjEuNTY5NTcxNjI5MjI1NDY5OCIsIi0wLjI3NDYzNTMyMTc1OTkyOTMiLCIwLjY0NzcwMTg4MTkyNTUzNjIiXSwic2l6ZSI6WzY0NCwzOTRdfV0-
1404 
1405  float reflectionFactor = 0.0f;
1406 
1407  if( (material.m_Shininess - 0.35f) > FLT_EPSILON )
1408  {
1409  reflectionFactor = glm::clamp( glm::sqrt( (material.m_Shininess - 0.35f) ) *
1410  0.40f - 0.05f,
1411  0.0f,
1412  0.5f );
1413  }
1414 
1415  CBLINN_PHONG_MATERIAL &blinnMaterial = (*materialVector)[imat];
1416 
1417  blinnMaterial = CBLINN_PHONG_MATERIAL(
1418  ConvertSRGBToLinear( material.m_Ambient ),
1419  ConvertSRGBToLinear( material.m_Emissive ),
1420  ConvertSRGBToLinear( material.m_Specular ),
1421  material.m_Shininess * 180.0f,
1422  material.m_Transparency,
1423  reflectionFactor );
1424 
1426  {
1427  // Guess material type and apply a normal perturbator
1428 
1429  if( ( RGBtoGray( material.m_Diffuse ) < 0.3f ) &&
1430  ( material.m_Shininess < 0.36f ) &&
1431  ( material.m_Transparency == 0.0f ) &&
1432  ( ( glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) < 0.15f ) &&
1433  ( glm::abs( material.m_Diffuse.b - material.m_Diffuse.g ) < 0.15f ) &&
1434  ( glm::abs( material.m_Diffuse.r - material.m_Diffuse.b ) < 0.15f ) ) )
1435  {
1436  // This may be a black plastic..
1437 
1438  if( material.m_Shininess < 0.26f )
1440  else
1442  }
1443  else
1444  {
1445  if( ( RGBtoGray( material.m_Diffuse ) > 0.3f ) &&
1446  ( material.m_Shininess < 0.30f ) &&
1447  ( material.m_Transparency == 0.0f ) &&
1448  ( ( glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) > 0.25f ) ||
1449  ( glm::abs( material.m_Diffuse.b - material.m_Diffuse.g ) > 0.25f ) ||
1450  ( glm::abs( material.m_Diffuse.r - material.m_Diffuse.b ) > 0.25f ) ) )
1451  {
1452  // This may be a color plastic ...
1454  }
1455  else
1456  {
1457  if( ( RGBtoGray( material.m_Diffuse ) > 0.6f ) &&
1458  ( material.m_Shininess > 0.35f ) &&
1459  ( material.m_Transparency == 0.0f ) &&
1460  ( ( glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) < 0.40f ) &&
1461  ( glm::abs( material.m_Diffuse.b - material.m_Diffuse.g ) < 0.40f ) &&
1462  ( glm::abs( material.m_Diffuse.r - material.m_Diffuse.b ) < 0.40f ) ) )
1463  {
1464  // This may be a brushed metal
1466  }
1467  }
1468  }
1469  }
1470  }
1471  else
1472  {
1473  (*materialVector)[imat] = CBLINN_PHONG_MATERIAL( SFVEC3F( 0.2f ),
1474  SFVEC3F( 0.0f ),
1475  SFVEC3F( 0.0f ),
1476  0.0f,
1477  0.0f,
1478  0.0f );
1479  }
1480  }
1481  }
1482 
1483  return materialVector;
1484 }
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)
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:288
CMETALBRUSHEDNORMAL m_brushed_metal_normal_perturbator
std::vector< CBLINN_PHONG_MATERIAL > MODEL_MATERIALS
Vector of materials.
Use all material properties from model file.
Blinn Phong based material https://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model.
Definition: cmaterial.h:318
float m_Shininess
Definition: c3dmodel.h:43
unsigned int m_MaterialsSize
Number of materials in the material array.
Definition: c3dmodel.h:95
BOARD_ADAPTER & m_boardAdapter
settings refrence in use for this render
SFVEC3F m_Emissive
Definition: c3dmodel.h:41
glm::vec3 SFVEC3F
Definition: xv3d_types.h:47
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
MATERIAL_MODE MaterialModeGet() const noexcept
MaterialModeGet.
MAP_MODEL_MATERIALS m_model_materials
Stores materials of the 3D models.
SFVEC3F m_Specular
Definition: c3dmodel.h:42

References ConvertSRGBToLinear(), FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES, BOARD_ADAPTER::GetFlag(), SMATERIAL::m_Ambient, C3D_RENDER_BASE::m_boardAdapter, m_brushed_metal_normal_perturbator, SMATERIAL::m_Diffuse, SMATERIAL::m_Emissive, S3DMODEL::m_Materials, S3DMODEL::m_MaterialsSize, m_model_materials, m_plastic_normal_perturbator, m_plastic_shine_normal_perturbator, SMATERIAL::m_Shininess, SMATERIAL::m_Specular, SMATERIAL::m_Transparency, BOARD_ADAPTER::MaterialModeGet(), NORMAL, RGBtoGray(), and CMATERIAL::SetNormalPerturbator().

Referenced by add_3D_models().

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

2009 {
2010 
2011  m_realBufferSize = SFVEC2UI( 0 );
2012 
2013  // Calc block positions for fast preview mode
2014  // /////////////////////////////////////////////////////////////////////
2015  m_blockPositionsFast.clear();
2016 
2017  unsigned int i = 0;
2018 
2019  while(1)
2020  {
2021  const unsigned int mX = DecodeMorton2X(i);
2022  const unsigned int mY = DecodeMorton2Y(i);
2023 
2024  i++;
2025 
2026  const SFVEC2UI blockPos( mX * 4 * RAYPACKET_DIM - mX * 4,
2027  mY * 4 * RAYPACKET_DIM - mY * 4);
2028 
2029  if( ( blockPos.x >= ( (unsigned int)m_windowSize.x - ( 4 * RAYPACKET_DIM + 4 ) ) ) &&
2030  ( blockPos.y >= ( (unsigned int)m_windowSize.y - ( 4 * RAYPACKET_DIM + 4 ) ) ) )
2031  break;
2032 
2033  if( ( blockPos.x < ( (unsigned int)m_windowSize.x - ( 4 * RAYPACKET_DIM + 4) ) ) &&
2034  ( blockPos.y < ( (unsigned int)m_windowSize.y - ( 4 * RAYPACKET_DIM + 4) ) ) )
2035  {
2036  m_blockPositionsFast.push_back( blockPos );
2037 
2038  if( blockPos.x > m_realBufferSize.x )
2039  m_realBufferSize.x = blockPos.x;
2040 
2041  if( blockPos.y > m_realBufferSize.y )
2042  m_realBufferSize.y = blockPos.y;
2043  }
2044  }
2045 
2047 
2050 
2051  m_xoffset = (m_windowSize.x - m_realBufferSize.x) / 2;
2052  m_yoffset = (m_windowSize.y - m_realBufferSize.y) / 2;
2053 
2055 
2056 
2057  // Calc block positions for regular rendering. Choose an 'inside out'
2058  // style of rendering
2059  // /////////////////////////////////////////////////////////////////////
2060  m_blockPositions.clear();
2061  const int blocks_x = m_realBufferSize.x / RAYPACKET_DIM;
2062  const int blocks_y = m_realBufferSize.y / RAYPACKET_DIM;
2063  m_blockPositions.reserve( blocks_x * blocks_y );
2064 
2065  for( int x = 0; x < blocks_x; ++x )
2066  for( int y = 0; y < blocks_y; ++y )
2067  m_blockPositions.emplace_back( x * RAYPACKET_DIM, y * RAYPACKET_DIM );
2068 
2069  const SFVEC2UI center( m_realBufferSize.x / 2, m_realBufferSize.y / 2 );
2070  std::sort( m_blockPositions.begin(), m_blockPositions.end(),
2071  [&]( const SFVEC2UI& a, const SFVEC2UI& b ) {
2072  // Sort order: inside out.
2073  return distance( a, center ) < distance( b, center );
2074  } );
2075 
2076  // Create m_shader buffer
2077  delete[] m_shaderBuffer;
2079 
2080  opengl_init_pbo();
2081 }
#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 1958 of file c3d_render_raytracing.cpp.

1959 {
1960  opengl_init_pbo();
1961 }

References opengl_init_pbo().

Referenced by SetCurWindowSize().

◆ initializeOpenGL()

bool C3D_RENDER_RAYTRACING::initializeOpenGL ( )
private

Definition at line 1993 of file c3d_render_raytracing.cpp.

1994 {
1995  m_is_opengl_initialized = true;
1996 
1997  return true;
1998 }
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 1085 of file c3d_render_createscene.cpp.

1086 {
1087  const COBJECT2D *object2d_A = NULL;
1088 
1089  SFVEC3F objColor;
1090 
1092  objColor = (SFVEC3F)m_boardAdapter.m_CopperColor;
1093  else
1095 
1096  const wxSize drillsize = aPad->GetDrillSize();
1097  const bool hasHole = drillsize.x && drillsize.y;
1098 
1099  if( !hasHole )
1100  return;
1101 
1102  const float topZ = m_boardAdapter.GetLayerBottomZpos3DU( F_Cu ) +
1104 
1105  const float botZ = m_boardAdapter.GetLayerBottomZpos3DU( B_Cu ) -
1107 
1108  if( drillsize.x == drillsize.y ) // usual round hole
1109  {
1110  SFVEC2F center = SFVEC2F( aPad->GetPosition().x * m_boardAdapter.BiuTo3Dunits(),
1111  -aPad->GetPosition().y * m_boardAdapter.BiuTo3Dunits() );
1112 
1113  int innerRadius = drillsize.x / 2;
1114  int outerRadius = innerRadius + m_boardAdapter.GetHolePlatingThicknessBIU();
1115  CRING2D *ring = new CRING2D( center,
1116  innerRadius * m_boardAdapter.BiuTo3Dunits(),
1117  outerRadius * m_boardAdapter.BiuTo3Dunits(),
1118  *aPad );
1119 
1121 
1122  object2d_A = ring;
1123  }
1124  else // Oblong hole
1125  {
1126  wxPoint ends_offset;
1127  int width;
1128 
1129  if( drillsize.x > drillsize.y ) // Horizontal oval
1130  {
1131  ends_offset.x = ( drillsize.x - drillsize.y ) / 2;
1132  width = drillsize.y;
1133  }
1134  else // Vertical oval
1135  {
1136  ends_offset.y = ( drillsize.y - drillsize.x ) / 2;
1137  width = drillsize.x;
1138  }
1139 
1140  RotatePoint( &ends_offset, aPad->GetOrientation() );
1141 
1142  wxPoint start = aPad->GetPosition() + ends_offset;
1143  wxPoint end = aPad->GetPosition() - ends_offset;
1144 
1145  CROUNDSEGMENT2D *innerSeg = new CROUNDSEGMENT2D(
1146  SFVEC2F( start.x * m_boardAdapter.BiuTo3Dunits(),
1147  -start.y * m_boardAdapter.BiuTo3Dunits() ),
1148  SFVEC2F( end.x * m_boardAdapter.BiuTo3Dunits(),
1149  -end.y * m_boardAdapter.BiuTo3Dunits() ),
1150  width * m_boardAdapter.BiuTo3Dunits(),
1151  *aPad );
1152 
1153  CROUNDSEGMENT2D *outerSeg = new CROUNDSEGMENT2D(
1154  SFVEC2F( start.x * m_boardAdapter.BiuTo3Dunits(),
1155  -start.y * m_boardAdapter.BiuTo3Dunits() ),
1156  SFVEC2F( end.x * m_boardAdapter.BiuTo3Dunits(),
1157  -end.y * m_boardAdapter.BiuTo3Dunits() ),
1159  *aPad );
1160 
1161  // NOTE: the round segment width is the "diameter", so we double the thickness
1162 
1163  std::vector<const COBJECT2D *> *object2d_B = new std::vector<const COBJECT2D *>();
1164  object2d_B->push_back( innerSeg );
1165 
1166  CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( outerSeg,
1167  object2d_B,
1168  CSGITEM_FULL,
1169  *aPad );
1170 
1171  m_containerWithObjectsToDelete.Add( itemCSG2d );
1172  m_containerWithObjectsToDelete.Add( innerSeg );
1173  m_containerWithObjectsToDelete.Add( outerSeg );
1174 
1175  object2d_A = itemCSG2d;
1176  }
1177 
1178 
1179  if( object2d_A )
1180  {
1181  std::vector<const COBJECT2D *> *object2d_B = new std::vector<const COBJECT2D *>();
1182 
1183  // Check if there are any other THT that intersects this hole
1184  // It will use the non inflated holes
1185  if( !m_boardAdapter.GetThroughHole_Inner().GetList().empty() )
1186  {
1187 
1188  CONST_LIST_OBJECT2D intersectionList;
1190  intersectionList );
1191 
1192  if( !intersectionList.empty() )
1193  {
1194  for( CONST_LIST_OBJECT2D::const_iterator hole = intersectionList.begin();
1195  hole != intersectionList.end();
1196  ++hole )
1197  {
1198  const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*hole);
1199 
1200  if( object2d_A->Intersects( hole2d->GetBBox() ) )
1201  //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) )
1202  object2d_B->push_back( hole2d );
1203  }
1204  }
1205  }
1206 
1207  if( object2d_B->empty() )
1208  {
1209  delete object2d_B;
1210  object2d_B = CSGITEM_EMPTY;
1211  }
1212 
1213  if( object2d_B == CSGITEM_EMPTY )
1214  {
1215  CLAYERITEM *objPtr = new CLAYERITEM( object2d_A, topZ, botZ );
1216 
1217  objPtr->SetMaterial( &m_materials.m_Copper );
1218  objPtr->SetColor( ConvertSRGBToLinear( objColor ) );
1219  m_object_container.Add( objPtr );
1220  }
1221  else
1222  {
1223  CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( object2d_A,
1224  object2d_B,
1225  CSGITEM_FULL,
1226  (const BOARD_ITEM &)*aPad );
1227 
1228  m_containerWithObjectsToDelete.Add( itemCSG2d );
1229 
1230  CLAYERITEM *objPtr = new CLAYERITEM( itemCSG2d, topZ, botZ );
1231 
1232  objPtr->SetMaterial( &m_materials.m_Copper );
1233  objPtr->SetColor( ConvertSRGBToLinear( objColor ) );
1234 
1235  m_object_container.Add( objPtr );
1236  }
1237  }
1238 }
void GetListObjectsIntersects(const CBBOX2D &aBBox, CONST_LIST_OBJECT2D &aOutList) const override
GetListObjectsIntersects - Get a list of objects that intersects a bbox.
double BiuTo3Dunits() const noexcept
BiuTo3Dunits - Board integer units To 3D units.
bool GetFlag(DISPLAY3D_FLG aFlag) const
GetFlag - get a configuration status of a flag.
SFVEC3F ConvertSRGBToLinear(const SFVEC3F &aSRGBcolor)
multilayer pads, usually with holes
BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
wxPoint GetPosition() const override
Definition: class_pad.h:172
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:72
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 GetHolePlatingThicknessBIU() 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
SFVEC4F GetItemColor(int aItemId) const
GetItemColor - get the technical color of a layer.
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 a variety of units (the basic call r...
Definition: class_pad.h:338
SFVEC4F m_CopperColor
in realistic mode: copper color
const wxSize & GetDrillSize() const
Definition: class_pad.h:241
const CBBOX2D & GetBBox() const
Definition: cobject2d.h:121
const LIST_OBJECT2D & GetList() const
Definition: ccontainer2d.h:64
virtual bool Intersects(const CBBOX2D &aBBox) const =0
Function Intersects.

References CGENERICCONTAINER2D::Add(), CGENERICCONTAINER::Add(), B_Cu, BOARD_ADAPTER::BiuTo3Dunits(), ConvertSRGBToLinear(), CSGITEM_EMPTY, CSGITEM_FULL, F_Cu, FL_USE_REALISTIC_MODE, COBJECT2D::GetBBox(), BOARD_ADAPTER::GetCopperThickness3DU(), D_PAD::GetDrillSize(), BOARD_ADAPTER::GetFlag(), BOARD_ADAPTER::GetHolePlatingThicknessBIU(), 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(), and COBJECT::SetMaterial().

Referenced by add_3D_vias_and_pads_to_container().

◆ insert3DViaHole()

void C3D_RENDER_RAYTRACING::insert3DViaHole ( const VIA aVia)
private

Definition at line 1044 of file c3d_render_createscene.cpp.

1045 {
1046  PCB_LAYER_ID top_layer, bottom_layer;
1047  int radiusBUI = (aVia->GetDrillValue() / 2);
1048 
1049  aVia->LayerPair( &top_layer, &bottom_layer );
1050 
1051  float topZ = m_boardAdapter.GetLayerBottomZpos3DU( top_layer ) +
1053 
1054  float botZ = m_boardAdapter.GetLayerBottomZpos3DU( bottom_layer ) -
1056 
1057  const SFVEC2F center = SFVEC2F( aVia->GetStart().x * m_boardAdapter.BiuTo3Dunits(),
1058  -aVia->GetStart().y * m_boardAdapter.BiuTo3Dunits() );
1059 
1060  CRING2D *ring = new CRING2D( center,
1061  radiusBUI * m_boardAdapter.BiuTo3Dunits(),
1062  ( radiusBUI + m_boardAdapter.GetHolePlatingThicknessBIU() ) *
1064  *aVia );
1065 
1067 
1068 
1069  CLAYERITEM *objPtr = new CLAYERITEM( ring, topZ, botZ );
1070 
1071  objPtr->SetMaterial( &m_materials.m_Copper );
1072 
1075  else
1076  objPtr->SetColor( ConvertSRGBToLinear(
1077  m_boardAdapter.GetItemColor( LAYER_VIAS + static_cast<int>( aVia->GetViaType() ) ) ) );
1078 
1079  m_object_container.Add( objPtr );
1080 }
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:116
float GetCopperThickness3DU() const noexcept
GetCopperThickness3DU - Get the current copper layer thickness.
void SetMaterial(const CMATERIAL *aMaterial)
Definition: cobject.h:72
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 GetHolePlatingThicknessBIU() const noexcept
GetCopperThicknessBIU - Get the current copper layer thickness.
int GetDrillValue() const
Function GetDrillValue "calculates" the drill value for vias (m-Drill if > 0, or default drill value ...
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
SFVEC4F GetItemColor(int aItemId) const
GetItemColor - get the technical color of a layer.
BOARD_ADAPTER & m_boardAdapter
settings refrence in use for this render
void Add(COBJECT2D *aObject)
Definition: ccontainer2d.h:52
Meta control for all vias opacity/visibility.
struct C3D_RENDER_RAYTRACING::@3 m_materials
glm::vec3 SFVEC3F
Definition: xv3d_types.h:47
SFVEC4F m_CopperColor
in realistic mode: copper color
VIATYPE GetViaType() const
Definition: class_track.h:384

References CGENERICCONTAINER2D::Add(), CGENERICCONTAINER::Add(), BOARD_ADAPTER::BiuTo3Dunits(), ConvertSRGBToLinear(), FL_USE_REALISTIC_MODE, BOARD_ADAPTER::GetCopperThickness3DU(), VIA::GetDrillValue(), BOARD_ADAPTER::GetFlag(), BOARD_ADAPTER::GetHolePlatingThicknessBIU(), 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(), and COBJECT::SetMaterial().

Referenced by add_3D_vias_and_pads_to_container().

◆ IntersectBoardItem()

BOARD_ITEM * C3D_RENDER_RAYTRACING::IntersectBoardItem ( const RAY aRay)

Definition at line 2083 of file c3d_render_raytracing.cpp.

2084 {
2085  HITINFO hitInfo;
2086  hitInfo.m_tHit = std::numeric_limits<float>::infinity();
2087 
2088  if( m_accelerator )
2089  if( m_accelerator->Intersect( aRay, hitInfo ) )
2090  {
2091  if( hitInfo.pHitObject )
2092  return hitInfo.pHitObject->GetBoardItem();
2093  }
2094 
2095  return nullptr;
2096 }
float m_tHit
( 4) distance
Definition: hitinfo.h:43
CGENERICACCELERATOR * m_accelerator
BOARD_ITEM * GetBoardItem() const
Definition: cobject.h:70
virtual bool Intersect(const RAY &aRay, HITINFO &aHitInfo) const =0
const COBJECT * pHitObject
( 4) Object that was hitted
Definition: hitinfo.h:45
Stores the hit information of a ray with a point on the surface of a object.
Definition: hitinfo.h:40

References COBJECT::GetBoardItem(), CGENERICACCELERATOR::Intersect(), m_accelerator, HITINFO::m_tHit, and HITINFO::pHitObject.

Referenced by EDA_3D_CANVAS::OnLeftDown(), and EDA_3D_CANVAS::OnMouseMove().

◆ 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::DoRePaint(), and EDA_3D_CANVAS::IsReloadRequestPending().

◆ load_3D_models()

void C3D_RENDER_RAYTRACING::load_3D_models ( CCONTAINER aDstContainer,
bool  aSkipMaterialInformation 
)
private

Definition at line 1268 of file c3d_render_createscene.cpp.

1269 {
1270  // Go for all footprints
1271  for( auto module : m_boardAdapter.GetBoard()->Modules() )
1272  {
1273  if((!module->Models().empty() ) &&
1274  m_boardAdapter.ShouldModuleBeDisplayed((MODULE_ATTR_T)module->GetAttributes() ) )
1275  {
1276  double zpos = m_boardAdapter.GetModulesZcoord3DIU( module->IsFlipped() );
1277 
1278  wxPoint pos = module->GetPosition();
1279 
1280  glm::mat4 moduleMatrix = glm::mat4( 1.0f );
1281 
1282  moduleMatrix = glm::translate( moduleMatrix,
1283  SFVEC3F( pos.x * m_boardAdapter.BiuTo3Dunits(),
1284  -pos.y * m_boardAdapter.BiuTo3Dunits(),
1285  zpos ) );
1286 
1287  if( module->GetOrientation() )
1288  {
1289  moduleMatrix = glm::rotate( moduleMatrix,
1290  ( (float)(module->GetOrientation() / 10.0f) / 180.0f ) *
1291  glm::pi<float>(),
1292  SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1293  }
1294 
1295 
1296  if( module->IsFlipped() )
1297  {
1298  moduleMatrix = glm::rotate( moduleMatrix,
1299  glm::pi<float>(),
1300  SFVEC3F( 0.0f, 1.0f, 0.0f ) );
1301 
1302  moduleMatrix = glm::rotate( moduleMatrix,
1303  glm::pi<float>(),
1304  SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1305  }
1306 
1307  const double modelunit_to_3d_units_factor = m_boardAdapter.BiuTo3Dunits() *
1309 
1310  moduleMatrix = glm::scale( moduleMatrix,
1311  SFVEC3F( modelunit_to_3d_units_factor,
1312  modelunit_to_3d_units_factor,
1313  modelunit_to_3d_units_factor ) );
1314 
1315  BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( module );
1316 
1317  // Get the list of model files for this model
1319  auto sM = module->Models().begin();
1320  auto eM = module->Models().end();
1321 
1322  while( sM != eM )
1323  {
1324  if( ( static_cast<float>( sM->m_Opacity ) > FLT_EPSILON ) &&
1325  ( sM->m_Show && !sM->m_Filename.empty() ) )
1326  {
1327  // get it from cache
1328  const S3DMODEL *modelPtr = cacheMgr->GetModel( sM->m_Filename );
1329 
1330  // only add it if the return is not NULL
1331  if( modelPtr )
1332  {
1333  glm::mat4 modelMatrix = moduleMatrix;
1334 
1335  modelMatrix = glm::translate( modelMatrix,
1336  SFVEC3F( sM->m_Offset.x,
1337  sM->m_Offset.y,
1338  sM->m_Offset.z ) );
1339 
1340  modelMatrix = glm::rotate( modelMatrix,
1341  (float)-( sM->m_Rotation.z / 180.0f ) *
1342  glm::pi<float>(),
1343  SFVEC3F( 0.0f, 0.0f, 1.0f ) );
1344 
1345  modelMatrix = glm::rotate( modelMatrix,
1346  (float)-( sM->m_Rotation.y / 180.0f ) *
1347  glm::pi<float>(),
1348  SFVEC3F( 0.0f, 1.0f, 0.0f ) );
1349 
1350  modelMatrix = glm::rotate( modelMatrix,
1351  (float)-( sM->m_Rotation.x / 180.0f ) *
1352  glm::pi<float>(),
1353  SFVEC3F( 1.0f, 0.0f, 0.0f ) );
1354 
1355  modelMatrix = glm::scale( modelMatrix,
1356  SFVEC3F( sM->m_Scale.x,
1357  sM->m_Scale.y,
1358  sM->m_Scale.z ) );
1359 
1360  add_3D_models( aDstContainer,
1361  modelPtr,
1362  modelMatrix,
1363  (float)sM->m_Opacity,
1364  aSkipMaterialInformation,
1365  boardItem );
1366  }
1367  }
1368 
1369  ++sM;
1370  }
1371  }
1372  }
1373 }
double BiuTo3Dunits() const noexcept
BiuTo3Dunits - Board integer units To 3D units.
BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
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:664
void add_3D_models(CCONTAINER &aDstContainer, const S3DMODEL *a3DModel, const glm::mat4 &aModelMatrix, float aModuleOpacity, bool aSkipMaterialInformation, BOARD_ITEM *aBoardItem)
MODULES & Modules()
Definition: class_board.h:284
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:66
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
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(), and UNITS3D_TO_UNITSPCB.

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

1965 {
1966  if( GLEW_ARB_pixel_buffer_object )
1967  {
1969 
1970  // Try to delete vbo if it was already initialized
1972 
1973  // Learn about Pixel buffer objects at:
1974  // http://www.songho.ca/opengl/gl_pbo.html
1975  // http://web.eecs.umich.edu/~sugih/courses/eecs487/lectures/25-PBO+Mipmapping.pdf
1976  // "create 2 pixel buffer objects, you need to delete them when program exits.
1977  // glBufferDataARB with NULL pointer reserves only memory space."
1978 
1979  // This sets the number of RGBA pixels
1981 
1982  glGenBuffersARB( 1, &m_pboId );
1983  glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboId );
1984  glBufferDataARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboDataSize, 0, GL_STREAM_DRAW_ARB );
1985  glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, 0 );
1986 
1987  wxLogTrace( m_logTrace,
1988  wxT( "C3D_RENDER_RAYTRACING:: GLEW_ARB_pixel_buffer_object is supported" ) );
1989  }
1990 }
static const wxChar * m_logTrace
Trace mask used to enable or disable the trace output of this class.

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

Referenced by initialize_block_positions(), and initializeNewWindowSize().

◆ Redraw()

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

Redraw - Ask to redraw the view.

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

Implements C3D_RENDER_BASE.

Definition at line 150 of file c3d_render_raytracing.cpp.

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

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

◆ Reload()

void C3D_RENDER_RAYTRACING::Reload ( REPORTER aStatusReporter,
REPORTER aWarningReporter,
bool  aOnlyLoadCopperAndShapes 
)

Definition at line 443 of file c3d_render_createscene.cpp.

446 {
447  m_reloadRequested = false;
448 
449  m_model_materials.clear();
450 
453 
454  unsigned stats_startReloadTime = GetRunningMicroSecs();
455 
456  if( !aOnlyLoadCopperAndShapes )
457  {
458  m_boardAdapter.InitSettings( aStatusReporter, aWarningReporter );
459 
461  m_camera.SetBoardLookAtPos( camera_pos );
462  }
463 
466 
467  setupMaterials();
468 
469  // Create and add the outline board
470  // /////////////////////////////////////////////////////////////////////////
471 
473 
475 
476  if( !aOnlyLoadCopperAndShapes )
477  {
478  const int outlineCount = m_boardAdapter.GetBoardPoly().OutlineCount();
479 
480  if( outlineCount > 0 )
481  {
482  float divFactor = 0.0f;
483 
486  else
488  divFactor = m_boardAdapter.GetStats_Med_Hole_Diameter3DU() * 8.0f;
489 
490  SHAPE_POLY_SET boardPolyCopy = m_boardAdapter.GetBoardPoly();
491  boardPolyCopy.Fracture( SHAPE_POLY_SET::PM_FAST );
492 
493  for( int iOutlinePolyIdx = 0; iOutlinePolyIdx < outlineCount; iOutlinePolyIdx++ )
494  {
496  boardPolyCopy,
499  divFactor,
500  *dynamic_cast<const BOARD_ITEM*>( m_boardAdapter.GetBoard() ),
501  iOutlinePolyIdx );
502  }
503 
505  {
506  const LIST_OBJECT2D &listObjects = m_outlineBoard2dObjects->GetList();
507 
508  for( LIST_OBJECT2D::const_iterator object2d_iterator = listObjects.begin();
509  object2d_iterator != listObjects.end();
510  ++object2d_iterator )
511  {
512  const COBJECT2D *object2d_A = static_cast<const COBJECT2D *>(*object2d_iterator);
513 
514  std::vector<const COBJECT2D *> *object2d_B = new std::vector<const COBJECT2D *>();
515 
516  // Check if there are any THT that intersects this outline object part
517  if( !m_boardAdapter.GetThroughHole_Outer().GetList().empty() )
518  {
519 
520  CONST_LIST_OBJECT2D intersectionList;
522  object2d_A->GetBBox(),
523  intersectionList );
524 
525  if( !intersectionList.empty() )
526  {
527  for( CONST_LIST_OBJECT2D::const_iterator hole = intersectionList.begin();
528  hole != intersectionList.end();
529  ++hole )
530  {
531  const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*hole);
532 
533  if( object2d_A->Intersects( hole2d->GetBBox() ) )
534  //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) )
535  object2d_B->push_back( hole2d );
536  }
537  }
538  }
539 
540  if( object2d_B->empty() )
541  {
542  delete object2d_B;
543  object2d_B = CSGITEM_EMPTY;
544  }
545 
546  if( object2d_B == CSGITEM_EMPTY )
547  {
548  #if 0
552  &m_materials.m_EpoxyBoard,
553  g_epoxyColor );
554  #else
555 
556  CLAYERITEM *objPtr = new CLAYERITEM( object2d_A,
559 
560  objPtr->SetMaterial( &m_materials.m_EpoxyBoard );
562  m_object_container.Add( objPtr );
563  #endif
564  }
565  else
566  {
567 
568  CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D(
569  object2d_A,
570  object2d_B,
571  CSGITEM_FULL,
572  (const BOARD_ITEM &)*m_boardAdapter.GetBoard() );
573 
574  m_containerWithObjectsToDelete.Add( itemCSG2d );
575 
576  CLAYERITEM *objPtr = new CLAYERITEM( itemCSG2d,
579 
580  objPtr->SetMaterial( &m_materials.m_EpoxyBoard );
582  m_object_container.Add( objPtr );
583 
584  }
585  }
586 
587  // Add cylinders of the board body to container
588  // Note: This is actually a workarround for the holes in the board.
589  // The issue is because if a hole is in a border of a divided polygon ( ex
590  // a polygon or dummyblock) it will cut also the render of the hole.
591  // So this will add a full hole.
592  // In fact, that is not need if the hole have copper.
593  // /////////////////////////////////////////////////////////////////////////
594  if( !m_boardAdapter.GetThroughHole_Outer().GetList().empty() )
595  {
597 
598  for( LIST_OBJECT2D::const_iterator hole = holeList.begin();
599  hole != holeList.end();
600  ++hole )
601  {
602  const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*hole);
603 
604  switch( hole2d->GetObjectType() )
605  {
607  {
608  const float radius = hole2d->GetBBox().GetExtent().x * 0.5f * 0.999f;
609 
610  CVCYLINDER *objPtr = new CVCYLINDER(
611  hole2d->GetCentroid(),
614  radius );
615 
616  objPtr->SetMaterial( &m_materials.m_EpoxyBoard );
618 
619  m_object_container.Add( objPtr );
620  }
621  break;
622 
623  default:
624  break;
625  }
626  }
627  }
628  }
629  }
630  }
631 
632 
633  // Add layers maps (except B_Mask and F_Mask)
634  // /////////////////////////////////////////////////////////////////////////
635 
636  for( MAP_CONTAINER_2D::const_iterator ii = m_boardAdapter.GetMapLayers().begin();
637  ii != m_boardAdapter.GetMapLayers().end();
638  ++ii )
639  {
640  PCB_LAYER_ID layer_id = static_cast<PCB_LAYER_ID>(ii->first);
641 
642  if( aOnlyLoadCopperAndShapes && !IsCopperLayer( layer_id ) )
643  continue;
644 
645  // Mask kayers are not processed here because they are a special case
646  if( (layer_id == B_Mask) || (layer_id == F_Mask) )
647  continue;
648 
649  CMATERIAL *materialLayer = &m_materials.m_SilkS;
650  SFVEC3F layerColor = SFVEC3F( 0.0f, 0.0f, 0.0f );
651 
652  switch( layer_id )
653  {
654  case B_Adhes:
655  case F_Adhes:
656  break;
657 
658  case B_Paste:
659  case F_Paste:
660  materialLayer = &m_materials.m_Paste;
661 
663  layerColor = m_boardAdapter.m_SolderPasteColor;
664  else
665  layerColor = m_boardAdapter.GetLayerColor( layer_id );
666  break;
667 
668  case B_SilkS:
669  materialLayer = &m_materials.m_SilkS;
670 
673  else
674  layerColor = m_boardAdapter.GetLayerColor( layer_id );
675  break;
676  case F_SilkS:
677  materialLayer = &m_materials.m_SilkS;
678 
681  else
682  layerColor = m_boardAdapter.GetLayerColor( layer_id );
683  break;
684 
685  case Dwgs_User:
686  case Cmts_User:
687  case Eco1_User:
688  case Eco2_User:
689  case Edge_Cuts:
690  case Margin:
691  break;
692 
693  case B_CrtYd:
694  case F_CrtYd:
695  break;
696 
697  case B_Fab:
698  case F_Fab:
699  break;
700 
701  default:
702  layerColor = m_boardAdapter.GetLayerColor( layer_id );
703 
705  layerColor = SFVEC3F( 184.0f / 255.0f, 115.0f / 255.0f, 50.0f / 255.0f );
706 
707  materialLayer = &m_materials.m_NonPlatedCopper;
708  break;
709  }
710 
711  const CBVHCONTAINER2D* container2d = static_cast<const CBVHCONTAINER2D*>(ii->second);
712 
713  createItemsFromContainer( container2d, layer_id, materialLayer, layerColor, 0.0f );
714  }// for each layer on map
715 
716  // Create plated copper
718  {
719  SFVEC3F layerColor_F_Cu = m_boardAdapter.GetLayerColor( F_Cu );
720  SFVEC3F layerColor_B_Cu = m_boardAdapter.GetLayerColor( B_Cu );
721 
723  {
724  layerColor_F_Cu = m_boardAdapter.m_CopperColor;
725  layerColor_B_Cu = layerColor_F_Cu;
726  }
727 
730  }
731 
732  if( !aOnlyLoadCopperAndShapes )
733  {
734  // Add Mask layer
735  // Solder mask layers are "negative" layers so the elements that we have
736  // (in the container) should remove the board outline.
737  // We will check for all objects in the outline if it intersects any object
738  // in the layer container and also any hole.
739  // /////////////////////////////////////////////////////////////////////////
741  (m_outlineBoard2dObjects->GetList().size() >= 1) )
742  {
743  const CMATERIAL *materialLayer = &m_materials.m_SolderMask;
744 
745  for( MAP_CONTAINER_2D::const_iterator ii = m_boardAdapter.GetMapLayers().begin();
746  ii != m_boardAdapter.GetMapLayers().end();
747  ++ii )
748  {
749  PCB_LAYER_ID layer_id = static_cast<PCB_LAYER_ID>(ii->first);
750 
751  const CBVHCONTAINER2D *containerLayer2d =
752  static_cast<const CBVHCONTAINER2D *>(ii->second);
753 
754  // Only get the Solder mask layers
755  if( !((layer_id == B_Mask) || (layer_id == F_Mask)) )
756  continue;
757 
758  SFVEC3F layerColor;
760  {
761  if( layer_id == B_Mask )
763  else
765  }
766  else
767  layerColor = m_boardAdapter.GetLayerColor( layer_id );
768 
769  const float zLayerMin = m_boardAdapter.GetLayerBottomZpos3DU( layer_id );
770  const float zLayerMax = m_boardAdapter.GetLayerTopZpos3DU( layer_id );
771 
772  // Get the outline board objects
773  const LIST_OBJECT2D &listObjects = m_outlineBoard2dObjects->GetList();
774 
775  for( LIST_OBJECT2D::const_iterator object2d_iterator = listObjects.begin();
776  object2d_iterator != listObjects.end();
777  ++object2d_iterator )
778  {
779  const COBJECT2D *object2d_A = static_cast<const COBJECT2D *>(*object2d_iterator);
780 
781  std::vector<const COBJECT2D *> *object2d_B = new std::vector<const COBJECT2D *>();
782 
783  // Check if there are any THT that intersects this outline object part
784  if( !m_boardAdapter.GetThroughHole_Outer().GetList().empty() )
785  {
786 
787  CONST_LIST_OBJECT2D intersectionList;
788 
790  object2d_A->GetBBox(),
791  intersectionList );
792 
793  if( !intersectionList.empty() )
794  {
795  for( CONST_LIST_OBJECT2D::const_iterator hole = intersectionList.begin();
796  hole != intersectionList.end();
797  ++hole )
798  {
799  const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*hole);
800 
801  if( object2d_A->Intersects( hole2d->GetBBox() ) )
802  //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) )
803  object2d_B->push_back( hole2d );
804  }
805  }
806  }
807 
808  // Check if there are any objects in the layer to subtract with the
809  // corrent object
810  if( !containerLayer2d->GetList().empty() )
811  {
812  CONST_LIST_OBJECT2D intersectionList;
813 
814  containerLayer2d->GetListObjectsIntersects( object2d_A->GetBBox(),
815  intersectionList );
816 
817  if( !intersectionList.empty() )
818  {
819  for( CONST_LIST_OBJECT2D::const_iterator obj = intersectionList.begin();
820  obj != intersectionList.end();
821  ++obj )
822  {
823  const COBJECT2D *obj2d = static_cast<const COBJECT2D *>(*obj);
824 
825  //if( object2d_A->Intersects( obj2d->GetBBox() ) )
826  //if( object2d_A->GetBBox().Intersects( obj2d->GetBBox() ) )
827  object2d_B->push_back( obj2d );
828  }
829  }
830  }
831 
832  if( object2d_B->empty() )
833  {
834  delete object2d_B;
835  object2d_B = CSGITEM_EMPTY;
836  }
837 
838  if( object2d_B == CSGITEM_EMPTY )
839  {
840  #if 0
842  object2d_A,
843  zLayerMin,
844  zLayerMax,
845  materialLayer,
846  layerColor );
847  #else
848  CLAYERITEM *objPtr = new CLAYERITEM( object2d_A,
849  zLayerMin,
850  zLayerMax );
851 
852  objPtr->SetMaterial( materialLayer );
853  objPtr->SetColor( ConvertSRGBToLinear( layerColor ) );
854 
855  m_object_container.Add( objPtr );
856  #endif
857  }
858  else
859  {
860  CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( object2d_A,
861  object2d_B,
862  CSGITEM_FULL,
863  object2d_A->GetBoardItem() );
864 
865  m_containerWithObjectsToDelete.Add( itemCSG2d );
866 
867  CLAYERITEM *objPtr = new CLAYERITEM( itemCSG2d,
868  zLayerMin,
869  zLayerMax );
870  objPtr->SetMaterial( materialLayer );
871  objPtr->SetColor( ConvertSRGBToLinear( layerColor ) );
872 
873  m_object_container.Add( objPtr );
874  }
875  }
876  }
877  }
878 
880  }
881 
882 #ifdef PRINT_STATISTICS_3D_VIEWER
883  unsigned stats_endConvertTime = GetRunningMicroSecs();
884  unsigned stats_startLoad3DmodelsTime = stats_endConvertTime;
885 #endif
886 
887 
888  load_3D_models( m_object_container, aOnlyLoadCopperAndShapes );
889 
890 
891 #ifdef PRINT_STATISTICS_3D_VIEWER
892  unsigned stats_endLoad3DmodelsTime = GetRunningMicroSecs();
893 #endif
894 
895  if( !aOnlyLoadCopperAndShapes )
896  {
897  // Add floor
898  // /////////////////////////////////////////////////////////////////////////
900  {
901  CBBOX boardBBox = m_boardAdapter.GetBBox3DU();
902 
903  if( boardBBox.IsInitialized() )
904  {
905  boardBBox.Scale( 3.0f );
906 
907  if( m_object_container.GetList().size() > 0 )
908  {
909  CBBOX containerBBox = m_object_container.GetBBox();
910 
911  containerBBox.Scale( 1.3f );
912 
913  const SFVEC3F centerBBox = containerBBox.GetCenter();
914 
915  // Floor triangles
916  const float minZ = glm::min( containerBBox.Min().z,
917  boardBBox.Min().z );
918 
919  const SFVEC3F v1 = SFVEC3F( -RANGE_SCALE_3D * 4.0f,
920  -RANGE_SCALE_3D * 4.0f,
921  minZ ) +
922  SFVEC3F( centerBBox.x,
923  centerBBox.y,
924  0.0f );
925 
926  const SFVEC3F v3 = SFVEC3F( +RANGE_SCALE_3D * 4.0f,
927  +RANGE_SCALE_3D * 4.0f,
928  minZ ) +
929  SFVEC3F( centerBBox.x,
930  centerBBox.y,
931  0.0f );
932 
933  const SFVEC3F v2 = SFVEC3F( v1.x, v3.y, v1.z );
934  const SFVEC3F v4 = SFVEC3F( v3.x, v1.y, v1.z );
935 
936  SFVEC3F backgroundColor =
937  ConvertSRGBToLinear( static_cast<SFVEC3F>( m_boardAdapter.m_BgColorTop ) );
938 
939  CTRIANGLE *newTriangle1 = new CTRIANGLE( v1, v2, v3 );
940  CTRIANGLE *newTriangle2 = new CTRIANGLE( v3, v4, v1 );
941 
942  m_object_container.Add( newTriangle1 );
943  m_object_container.Add( newTriangle2 );
944 
945  newTriangle1->SetMaterial( (const CMATERIAL *)&m_materials.m_Floor );
946  newTriangle2->SetMaterial( (const CMATERIAL *)&m_materials.m_Floor );
947 
948  newTriangle1->SetColor( backgroundColor );
949  newTriangle2->SetColor( backgroundColor );
950 
951  // Ceiling triangles
952  const float maxZ = glm::max( containerBBox.Max().z,
953  boardBBox.Max().z );
954 
955  const SFVEC3F v5 = SFVEC3F( v1.x, v1.y, maxZ );
956  const SFVEC3F v6 = SFVEC3F( v2.x, v2.y, maxZ );
957  const SFVEC3F v7 = SFVEC3F( v3.x, v3.y, maxZ );
958  const SFVEC3F v8 = SFVEC3F( v4.x, v4.y, maxZ );
959 
960  CTRIANGLE *newTriangle3 = new CTRIANGLE( v7, v6, v5 );
961  CTRIANGLE *newTriangle4 = new CTRIANGLE( v5, v8, v7 );
962 
963  m_object_container.Add( newTriangle3 );
964  m_object_container.Add( newTriangle4 );
965 
966  newTriangle3->SetMaterial( (const CMATERIAL *)&m_materials.m_Floor );
967  newTriangle4->SetMaterial( (const CMATERIAL *)&m_materials.m_Floor );
968 
969  newTriangle3->SetColor( backgroundColor );
970  newTriangle4->SetColor( backgroundColor );
971  }
972  }
973  }
974 
975 
976  // Init initial lights
977  // /////////////////////////////////////////////////////////////////////////
978  m_lights.Clear();
979 
980  auto IsColorZero = [] ( const SFVEC3F& aSource )
981  {
982  return ( ( aSource.r < ( 1.0f / 255.0f ) ) &&
983  ( aSource.g < ( 1.0f / 255.0f ) ) &&
984  ( aSource.b < ( 1.0f / 255.0f ) ) );
985  };
986 
987  m_camera_light = new CDIRECTIONALLIGHT( SFVEC3F( 0.0f, 0.0f, 0.0f ),
989  m_camera_light->SetCastShadows( false );
990 
991  if( !IsColorZero( m_boardAdapter.m_raytrace_lightColorCamera ) )
993 
994  const SFVEC3F& boardCenter = m_boardAdapter.GetBBox3DU().GetCenter();
995 
996  if( !IsColorZero( m_boardAdapter.m_raytrace_lightColorTop ) )
997  m_lights.Add( new CPOINTLIGHT( SFVEC3F( boardCenter.x, boardCenter.y, +RANGE_SCALE_3D * 2.0f ),
999 
1000  if( !IsColorZero( m_boardAdapter.m_raytrace_lightColorBottom ) )
1001  m_lights.Add( new CPOINTLIGHT( SFVEC3F( boardCenter.x, boardCenter.y, -RANGE_SCALE_3D * 2.0f ),
1003 
1004  wxASSERT( m_boardAdapter.m_raytrace_lightColor.size()
1006 
1007  for( size_t i = 0; i < m_boardAdapter.m_raytrace_lightColor.size(); ++i )
1008  {
1009  if( !IsColorZero( m_boardAdapter.m_raytrace_lightColor[i] ) )
1010  {
1012 
1013  m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi<float>() * sc.x,
1014  glm::pi<float>() * sc.y ),
1016  }
1017  }
1018  }
1019 
1020  // Create an accelerator
1021  // /////////////////////////////////////////////////////////////////////////
1022  if( m_accelerator )
1023  {
1024  delete m_accelerator;
1025  }
1026  m_accelerator = 0;
1027 
1029 
1030  if( aStatusReporter )
1031  {
1032  // Calculation time in seconds
1033  const double calculation_time = (double)( GetRunningMicroSecs() -
1034  stats_startReloadTime ) / 1e6;
1035 
1036  aStatusReporter->Report( wxString::Format( _( "Reload time %.3f s" ), calculation_time ) );
1037  }
1038 }
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.
std::vector< SFVEC3F > m_raytrace_lightColor
SFVEC3F m_raytrace_lightColorBottom
SFVEC3F m_raytrace_lightColorCamera
const CBBOX & GetBBox() const
Definition: ccontainer.h:67
const SFVEC3F & Max() const
Function Max return the maximum vertex pointer.
Definition: cbbox.h:211
int OutlineCount() const
Returns the number of outlines in the set
SFVEC4F m_SilkScreenColorBot
in realistic mode: SilkScreen color ( bot )
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
BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
std::vector< SFVEC2F > m_raytrace_lightSphericalCoords
A base material class that can be used to derive a material implementation.
Definition: cmaterial.h:216
float GetStats_Med_Hole_Diameter3DU() const noexcept
GetStats_Med_Hole_Diameter3DU - Average diameter of holes.
SFVEC4F m_SolderMaskColorTop
in realistic mode: solder mask color ( top )
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.
std::list< const COBJECT2D * > CONST_LIST_OBJECT2D
Definition: ccontainer2d.h:38
SFVEC3F m_raytrace_lightColorTop
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.
float GetCopperThickness3DU() const noexcept
GetCopperThickness3DU - Get the current copper layer thickness.
void InitSettings(REPORTER *aStatusReporter, REPORTER *aWarningReporter)
InitSettings - Function to be called by the render when it need to reload the settings for the board.
void SetMaterial(const CMATERIAL *aMaterial)
Definition: cobject.h:72
SFVEC4F m_BoardBodyColor
in realistic mode: FR4 board color
SFVEC4F m_SolderPasteColor
in realistic mode: solder paste color
SFVEC4F m_SolderMaskColorBot
in realistic mode: solder mask color ( bot )
const CBVHCONTAINER2D * GetPlatedPads_Front() const noexcept
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.
#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:136
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:403
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.
SFVEC4F m_BgColorTop
background top color
float GetLayerBottomZpos3DU(PCB_LAYER_ID aLayerId) const noexcept
GetLayerBottomZpos3DU - Get the bottom z position.
glm::vec2 SFVEC2F
Definition: xv3d_types.h:45
const CBVHCONTAINER2D * GetPlatedPads_Back() const noexcept
void createItemsFromContainer(const CBVHCONTAINER2D *aContainer2d, PCB_LAYER_ID aLayer_id, const CMATERIAL *aMaterialLayer, const SFVEC3F &aLayerColor, float aLayerZOffset)
float NextFloatDown(float v)
Definition: 3d_fastmath.h:157
SHAPE_POLY_SET.
void load_3D_models(CCONTAINER &aDstContainer, bool aSkipMaterialInformation)
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
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
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:195
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:204
void ResetStats()
Definition: cobject.h:122
void Add(COBJECT2D *aObject)
Definition: ccontainer2d.h:52
SFVEC4F GetLayerColor(PCB_LAYER_ID aLayerId) const
GetLayerColor - get the technical color of a layer.
const SFVEC3F & GetBoardCenter3DU() const noexcept
GetBoardCenter - the board center position in 3d units.
SFVEC2F GetExtent() const
Function GetExtent.
Definition: cbbox2d.cpp:126
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:201
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.
SFVEC4F m_CopperColor
in realistic mode: copper 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:139
void SetCastShadows(bool aCastShadow)
Definition: clight.h:57
SFVEC3F SphericalToCartesian(float aInclination, float aAzimuth)
SphericalToCartesian.
Definition: 3d_math.h:43
void ResetStats()
Definition: cobject2d.h:135
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
CCONTAINER2D * m_outlineBoard2dObjects
const SFVEC2F & GetCentroid() const
Definition: cobject2d.h:123
SFVEC4F m_SilkScreenColorTop
in realistic mode: SilkScreen color ( top )
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:39
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:88

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(), createItemsFromContainer(), 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_PLATED_PADS_AS_PLATED, FL_RENDER_RAYTRACING_BACKFLOOR, FL_SHOW_BOARD_BODY, FL_SOLDERMASK, 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(), BOARD_ADAPTER::GetCopperThickness3DU(), CBBOX2D::GetExtent(), BOARD_ADAPTER::GetFlag(), BOARD_ADAPTER::GetLayerBottomZpos3DU(), BOARD_ADAPTER::GetLayerColor(), BOARD_ADAPTER::GetLayerTopZpos3DU(), CGENERICCONTAINER::GetList(), CGENERICCONTAINER2D::GetList(), CBVHCONTAINER2D::GetListObjectsIntersects(), BOARD_ADAPTER::GetMapLayers(), COBJECT2D::GetObjectType(), BOARD_ADAPTER::GetPlatedPads_Back(), BOARD_ADAPTER::GetPlatedPads_Front(), 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(), IsCopperLayer(), 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, BOARD_ADAPTER::m_raytrace_lightColor, BOARD_ADAPTER::m_raytrace_lightColorBottom, BOARD_ADAPTER::m_raytrace_lightColorCamera, BOARD_ADAPTER::m_raytrace_lightColorTop, BOARD_ADAPTER::m_raytrace_lightSphericalCoords, 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, Margin, CBBOX::Max(), MIDDLE, CBBOX::Min(), NextFloatDown(), NextFloatUp(), SHAPE_POLY_SET::OutlineCount(), SHAPE_POLY_SET::PM_FAST, 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 EDA_3D_CANVAS::DoRePaint(), and Redraw().

◆ ReloadRequest()

void C3D_RENDER_BASE::ReloadRequest ( )
inlineinherited

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

Definition at line 76 of file c3d_render_base.h.

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

References C3D_RENDER_BASE::m_reloadRequested.

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

◆ render()

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

Definition at line 302 of file c3d_render_raytracing.cpp.

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

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

Referenced by Redraw().

◆ render_preview()

void C3D_RENDER_RAYTRACING::render_preview ( GLubyte *  ptrPBO)
private

Definition at line 1022 of file c3d_render_raytracing.cpp.

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

References color, and convertLinearToSRGB().

Referenced by rt_render_post_process_blur_finish(), and rt_render_trace_block().

◆ rt_render_post_process_blur_finish()

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

Definition at line 964 of file c3d_render_raytracing.cpp.

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

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

Referenced by render().

◆ rt_render_post_process_shade()

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

Definition at line 909 of file c3d_render_raytracing.cpp.

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

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

Referenced by render().

◆ rt_render_trace_block()

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

Definition at line 656 of file c3d_render_raytracing.cpp.

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

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

Referenced by rt_render_tracing().

◆ rt_render_tracing()

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

Definition at line 364 of file c3d_render_raytracing.cpp.

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

76 {
79 
82 
83  double mmTo3Dunits = IU_PER_MM * m_boardAdapter.BiuTo3Dunits();
84 
86  {
87  m_board_normal_perturbator = CBOARDNORMAL( 0.40f * mmTo3Dunits );
88 
89  m_copper_normal_perturbator = CCOPPERNORMAL( 4.0f * mmTo3Dunits,
91 
93 
95 
96  m_plastic_normal_perturbator = CPLASTICNORMAL( 0.15f * mmTo3Dunits );
97 
99 
101  }
102 
103  // http://devernay.free.fr/cours/opengl/materials.html
104 
105  // Copper
106  const SFVEC3F copperSpecularLinear = ConvertSRGBToLinear(
107  glm::clamp( (SFVEC3F)m_boardAdapter.m_CopperColor * 0.5f + 0.25f,
108  SFVEC3F( 0.0f ),
109  SFVEC3F( 1.0f ) ) );
110 
112  SFVEC3F( 0.0f ), // emissive
113  copperSpecularLinear, // specular
114  0.4f * 128.0f, // shiness
115  0.0f, // transparency
116  0.0f );
117 
119  m_materials.m_Copper.SetNormalPerturbator( &m_platedcopper_normal_perturbator );
120 
121  m_materials.m_NonPlatedCopper = CBLINN_PHONG_MATERIAL(
122  ConvertSRGBToLinear( SFVEC3F( 0.191f, 0.073f, 0.022f ) ),// ambient
123  SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
124  SFVEC3F( 0.256f, 0.137f, 0.086f ), // specular
125  0.15f * 128.0f, // shiness
126  0.0f, // transparency
127  0.0f );
128 
130  m_materials.m_NonPlatedCopper.SetNormalPerturbator( &m_copper_normal_perturbator );
131 
135  SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
138  0.10f * 128.0f, // shiness
139  0.0f, // transparency
140  0.0f );
141 
142  m_materials.m_SilkS = CBLINN_PHONG_MATERIAL( ConvertSRGBToLinear( SFVEC3F( 0.11f ) ), // ambient
143  SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
144  glm::clamp(
145  ( ( SFVEC3F )( 1.0f )
147  SFVEC3F( 0.0f ),
148  SFVEC3F( 0.10f ) ), // specular
149  0.078125f * 128.0f, // shiness
150  0.0f, // transparency
151  0.0f );
152 
153  // Assume that SolderMaskTop == SolderMaskBot
154  const float solderMask_gray =
157  / 3.0f;
158 
159  const float solderMask_transparency = TransparencyControl( solderMask_gray,
160  1.0f - m_boardAdapter.m_SolderMaskColorTop.a ); // opacity to transparency
161 
162  m_materials.m_SolderMask = CBLINN_PHONG_MATERIAL(
164  SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
165  SFVEC3F( glm::clamp( solderMask_gray * 2.0f, 0.25f, 1.0f ) ), // specular
166  0.85f * 128.0f, // shiness
167  solderMask_transparency, // transparency
168  0.16f ); // reflection
169 
170  m_materials.m_SolderMask.SetCastShadows( true );
171  m_materials.m_SolderMask.SetNrRefractionsSamples( 1 );
172 
174  m_materials.m_SolderMask.SetNormalPerturbator( &m_solder_mask_normal_perturbator );
175 
176  m_materials.m_EpoxyBoard = CBLINN_PHONG_MATERIAL(
177  ConvertSRGBToLinear( SFVEC3F( 16.0f / 255.0f,
178  14.0f / 255.0f,
179  10.0f / 255.0f ) ), // ambient
180  SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
181  ConvertSRGBToLinear( SFVEC3F( 10.0f / 255.0f,
182  8.0f / 255.0f,
183  10.0f / 255.0f ) ), // specular
184  0.1f * 128.0f, // shiness
185  1.0f - m_boardAdapter.m_BoardBodyColor.a, // opacity to transparency
186  0.0f ); // reflection
187 
188  m_materials.m_EpoxyBoard.SetAbsorvance( 10.0f );
189 
191  m_materials.m_EpoxyBoard.SetNormalPerturbator( &m_board_normal_perturbator );
192 
194  //SFVEC3F bgBot = (SFVEC3F)m_boardAdapter.m_BgColorBot;
195 
197  bgTop * 0.125f, // ambient
198  SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive
199  (SFVEC3F(1.0f) - bgTop) / 3.0f, // specular
200  0.10f * 128.0f, // shiness
201  0.0f, // transparency
202  0.50f ); // reflection
203  m_materials.m_Floor.SetCastShadows( false );
204  m_materials.m_Floor.SetReflectionsRecursiveLevel( 1 );
205 }
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
int m_raytrace_nrsamples_refractions
static constexpr double IU_PER_MM
Mock up a conversion function.
static void SetDefaultNrRefractionsSamples(unsigned int aNrRefractions)
Definition: cmaterial.h:219
CCOPPERNORMAL m_copper_normal_perturbator
SFVEC4F m_SolderMaskColorTop
in realistic mode: solder mask color ( top )
SFVEC4F m_BoardBodyColor
in realistic mode: FR4 board color
SFVEC4F m_SolderPasteColor
in realistic mode: solder paste color
static void SetDefaultRefractionsLevel(unsigned int aRefractionLevel)
Definition: cmaterial.h:222
CPLASTICSHINENORMAL m_plastic_shine_normal_perturbator
CMETALBRUSHEDNORMAL m_brushed_metal_normal_perturbator
SFVEC4F m_BgColorTop
background top color
Blinn Phong based material https://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model.
Definition: cmaterial.h:318
CPLATEDCOPPERNORMAL m_platedcopper_normal_perturbator
int m_raytrace_recursivelevel_reflections
BOARD_ADAPTER & m_boardAdapter
settings refrence in use for this render
static void SetDefaultNrReflectionsSamples(unsigned int aNrReflections)
Definition: cmaterial.h:220
CSOLDERMASKNORMAL m_solder_mask_normal_perturbator
struct C3D_RENDER_RAYTRACING::@3 m_materials
glm::vec3 SFVEC3F
Definition: xv3d_types.h:47
SFVEC4F m_CopperColor
in realistic mode: copper color
static void SetDefaultReflectionsLevel(unsigned int aReflectionLevel)
Definition: cmaterial.h:223
static float TransparencyControl(float aGrayColorValue, float aTransparency)
TransparencyAlphaControl Perform an interpolation step to easy control the transparency based on the ...
SFVEC4F m_SilkScreenColorTop
in realistic mode: SilkScreen color ( top )
int m_raytrace_recursivelevel_refractions
int m_raytrace_nrsamples_reflections

References BOARD_ADAPTER::BiuTo3Dunits(), ConvertSRGBToLinear(), FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES, BOARD_ADAPTER::GetFlag(), IU_PER_MM, BOARD_ADAPTER::m_BgColorTop, m_board_normal_perturbator, C3D_RENDER_BASE::m_boardAdapter, BOARD_ADAPTER::m_BoardBodyColor, m_brushed_metal_normal_perturbator, m_copper_normal_perturbator, BOARD_ADAPTER::m_CopperColor, m_materials, m_plastic_normal_perturbator, m_plastic_shine_normal_perturbator, m_platedcopper_normal_perturbator, BOARD_ADAPTER::m_raytrace_nrsamples_reflections, BOARD_ADAPTER::m_raytrace_nrsamples_refractions, BOARD_ADAPTER::m_raytrace_recursivelevel_reflections, BOARD_ADAPTER::m_raytrace_recursivelevel_refractions, BOARD_ADAPTER::m_SilkScreenColorTop, m_solder_mask_normal_perturbator, BOARD_ADAPTER::m_SolderMaskColorTop, BOARD_ADAPTER::m_SolderPasteColor, CMATERIAL::SetDefaultNrReflectionsSamples(), CMATERIAL::SetDefaultNrRefractionsSamples(), CMATERIAL::SetDefaultReflectionsLevel(), CMATERIAL::SetDefaultRefractionsLevel(), and TransparencyControl().

Referenced by Reload().

◆ shadeHit()

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

Definition at line 1654 of file c3d_render_raytracing.cpp.

1660 {
1661  const CMATERIAL *objMaterial = aHitInfo.pHitObject->GetMaterial();
1662  wxASSERT( objMaterial != NULL );
1663 
1664  SFVEC3F outColor = objMaterial->GetEmissiveColor() + objMaterial->GetAmbientColor();
1665 
1666  if( aRecursiveLevel > 7 )
1667  return outColor;
1668 
1669  SFVEC3F hitPoint = aHitInfo.m_HitPoint;
1670 
1671  hitPoint += aHitInfo.m_HitNormal * m_boardAdapter.GetNonCopperLayerThickness3DU() * 0.6f;
1672 
1673  const SFVEC3F diffuseColorObj = aHitInfo.pHitObject->GetDiffuseColor( aHitInfo );
1674 
1675  const LIST_LIGHT &lightList = m_lights.GetList();
1676 
1677 #if USE_EXPERIMENTAL_SOFT_SHADOWS
1678  const bool is_aa_enabled = m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_ANTI_ALIASING ) &&
1679  (!m_isPreview);
1680 #endif
1681 
1682  float shadow_att_factor_sum = 0.0f;
1683 
1684  unsigned int nr_lights_that_can_cast_shadows = 0;
1685 
1686  for( LIST_LIGHT::const_iterator ii = lightList.begin();
1687  ii != lightList.end();
1688  ++ii )
1689  {
1690  const CLIGHT *light = (CLIGHT *)*ii;
1691 
1692  SFVEC3F vectorToLight;
1693  SFVEC3F colorOfLight;
1694  float distToLight;
1695 
1696  light->GetLightParameters( hitPoint, vectorToLight, colorOfLight, distToLight );
1697 
1698  if( m_isPreview )
1699  colorOfLight = SFVEC3F( 1.0f );
1700 
1701  /*
1702  if( (!m_isPreview) &&
1703  // Little hack to make randomness to the shading and shadows
1704  m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING ) )
1705  vectorToLight = glm::normalize( vectorToLight +
1706  UniformRandomHemisphereDirection() * 0.1f );
1707  */
1708 
1709  const float NdotL = glm::dot( aHitInfo.m_HitNormal, vectorToLight );
1710 
1711  // Only calc shade if the normal is facing the direction of light,
1712  // otherwise it is in the shadow
1713  if( NdotL >= FLT_EPSILON )
1714  {
1715  float shadow_att_factor_light = 1.0f;
1716 
1717  if( is_testShadow && light->GetCastShadows() )
1718  {
1719  nr_lights_that_can_cast_shadows++;
1720 #if USE_EXPERIMENTAL_SOFT_SHADOWS
1721  // For rays that are recursive, just calculate one hit shadow
1722  if( aRecursiveLevel > 0 )
1723  {
1724 #endif
1725  RAY rayToLight;
1726  rayToLight.Init( hitPoint, vectorToLight );
1727 
1728  // Test if point is not in the shadow.
1729  // Test for any hit from the point in the direction of light
1730  if( m_accelerator->IntersectP( rayToLight, distToLight ) )
1731  shadow_att_factor_light = 0.0f;
1732 
1733 #if USE_EXPERIMENTAL_SOFT_SHADOWS
1734  }
1735 
1736  // Experimental softshadow calculation
1737  else
1738  {
1739 
1740  const unsigned int shadow_number_of_samples = m_boardAdapter.m_raytrace_nrsamples_shadows;
1741  const float shadow_inc_factor = 1.0f / (float)(shadow_number_of_samples);
1742 
1743  for( unsigned int i = 0; i < shadow_number_of_samples; ++i )
1744  {
1745  RAY rayToLight;
1746 
1747  if( i == 0 )
1748  {
1749  rayToLight.Init( hitPoint, vectorToLight );
1750  }
1751  else
1752  {
1753  const SFVEC3F unifVector = UniformRandomHemisphereDirection();
1754  const SFVEC3F disturbed_vector_to_light = glm::normalize( vectorToLight +
1755  unifVector *
1757 
1758  rayToLight.Init( hitPoint, disturbed_vector_to_light );
1759  }
1760 
1761  // !TODO: there are multiple ways that this tests can be
1762  // optimized. Eg: by packing rays or to test against the
1763  // latest hit object.
1764 
1765  if( m_accelerator->IntersectP( rayToLight, distToLight ) )
1766  {
1767  shadow_att_factor_light -= shadow_inc_factor;
1768  }
1769  }
1770  }
1771 #endif
1772  shadow_att_factor_sum += shadow_att_factor_light;
1773  }
1774 
1775  outColor += objMaterial->Shade( aRay,
1776  aHitInfo,
1777  NdotL,
1778  diffuseColorObj,
1779  vectorToLight,
1780  colorOfLight,
1781  shadow_att_factor_light );
1782  }
1783 
1784  // Only use the headlight for preview
1785  if( m_isPreview )
1786  break;
1787  }
1788 
1789  // Improvement: this is not taking in account the lightcolor
1790  if( nr_lights_that_can_cast_shadows > 0 )
1791  {
1792  aHitInfo.m_ShadowFactor = glm::max( shadow_att_factor_sum /
1793  (float)(nr_lights_that_can_cast_shadows * 1.0f), 0.0f );
1794  }
1795  else
1796  {
1797  aHitInfo.m_ShadowFactor = 1.0f;
1798  }
1799 
1800  // Clamp color to not be brighter than 1.0f
1801  outColor = glm::min( outColor, SFVEC3F( 1.0f ) );
1802 
1803  if( !m_isPreview )
1804  {
1805  // Reflections
1806  // /////////////////////////////////////////////////////////////////////
1807 
1808  if( ( objMaterial->GetReflection() > 0.0f ) &&
1810  ( aRecursiveLevel < objMaterial->GetReflectionsRecursiveLevel() ) )
1811  {
1812  const unsigned int reflection_number_of_samples = objMaterial->GetNrReflectionsSamples();
1813 
1814  SFVEC3F sum_color = SFVEC3F(0.0f);
1815 
1816  const SFVEC3F reflectVector = aRay.m_Dir -
1817  2.0f * glm::dot( aRay.