From 1eba0c435bc0eebbc7b2d3e8ff186cf344ff3b47 Mon Sep 17 00:00:00 2001 From: Wayne Stambaugh Date: Sat, 12 Dec 2020 12:29:11 -0500 Subject: [PATCH] 3D viewer code cleaning round 2. --- .../3d_render_raytracing/PerlinNoise.cpp | 11 +- .../3d_render_raytracing/PerlinNoise.h | 18 +- .../accelerators/cbvh_packet_traversal.cpp | 43 +- .../accelerators/cbvh_pbrt.cpp | 130 +- .../accelerators/cbvh_pbrt.h | 7 +- .../accelerators/ccontainer.cpp | 20 +- .../accelerators/ccontainer.h | 17 +- .../accelerators/ccontainer2d.cpp | 42 +- .../accelerators/ccontainer2d.h | 51 +- .../c3d_render_createscene.cpp | 1066 ++++++++--------- .../c3d_render_raytracing.cpp | 333 +++-- .../c3d_render_raytracing.h | 85 +- .../3d_render_raytracing/clight.h | 47 +- .../3d_render_raytracing/cmaterial.cpp | 25 +- .../3d_render_raytracing/cmaterial.h | 210 ++-- .../3d_rendering/3d_render_raytracing/ray.cpp | 69 +- .../3d_rendering/3d_render_raytracing/ray.h | 5 +- .../3d_render_raytracing/raypacket.cpp | 28 +- 18 files changed, 1089 insertions(+), 1118 deletions(-) diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/PerlinNoise.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/PerlinNoise.cpp index 41ecde2cf7..052f3abeb2 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/PerlinNoise.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/PerlinNoise.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2016-2002 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -32,8 +32,8 @@ * Original copyright notice: * * Perlin_Noise - * Here you could find the code for "Perlin noise in C++11", for more informations visit the project webpage: - * http://solarianprogrammer.com/2012/07/18/perlin-noise-cpp-11/ + * Here you could find the code for "Perlin noise in C++11", for more information visit the + * project webpage at http://solarianprogrammer.com/2012/07/18/perlin-noise-cpp-11/ * You could use this program under the terms of GPL v3, for more details see: * http://www.gnu.org/copyleft/gpl.html * Copyright 2012 Sol from www.solarianprogrammer.com @@ -79,7 +79,7 @@ PerlinNoise::PerlinNoise() std::copy_n( p.begin(), oldsize, p.begin() + oldsize ); } -// Generate a new permutation vector based on the value of seed + PerlinNoise::PerlinNoise( unsigned int seed ) { p.resize( 256 ); @@ -90,7 +90,7 @@ PerlinNoise::PerlinNoise( unsigned int seed ) // Initialize a random engine with seed std::default_random_engine engine( seed ); - // Suffle using the above random engine + // Shuffle using the above random engine std::shuffle( p.begin(), p.end(), engine ); // Duplicate the permutation vector @@ -99,6 +99,7 @@ PerlinNoise::PerlinNoise( unsigned int seed ) std::copy_n( p.begin(), oldsize, p.begin() + oldsize ); } + float PerlinNoise::noise( float x, float y, float z ) const { // Find the unit cube that contains the point diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/PerlinNoise.h b/3d-viewer/3d_rendering/3d_render_raytracing/PerlinNoise.h index adfbbc58c2..614e587379 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/PerlinNoise.h +++ b/3d-viewer/3d_rendering/3d_render_raytracing/PerlinNoise.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2016-2020 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -33,7 +33,7 @@ * * Perlin_Noise * "Here you could find the code for "Perlin noise in C++11", - * for more informations visit the project webpage: + * for more information visit the project webpage: * http://solarianprogrammer.com/2012/07/18/perlin-noise-cpp-11/ * You could use this program under the terms of GPL v3, for more details see: * http://www.gnu.org/copyleft/gpl.html @@ -54,14 +54,15 @@ class PerlinNoise { - // The permutation vector - std::vector p; - public: - // Initialize with the reference values for the permutation vector + /** + * Initialize with the reference values for the permutation vector. + */ PerlinNoise(); - // Generate a new permutation vector based on the value of seed + /** + * Generate a new permutation vector based on the value of seed. + */ PerlinNoise( unsigned int seed ); // Returns between 0.0f and 1.0f @@ -73,6 +74,9 @@ private: float lerp( float t, float a, float b ) const; float grad( int hash, float x, float y, float z ) const; float grad( int hash, float x, float y ) const; + + // The permutation vector + std::vector p; }; #endif diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/cbvh_packet_traversal.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/cbvh_packet_traversal.cpp index 65e7b82c55..aa25d20f3b 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/cbvh_packet_traversal.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/cbvh_packet_traversal.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -52,18 +52,18 @@ static inline unsigned int getFirstHit( const RAYPACKET &aRayPacket, { float hitT; - if( aBBox.Intersect( aRayPacket.m_ray[ia], &hitT ) ) - if( hitT < aHitInfoPacket[ia].m_HitInfo.m_tHit ) - return ia; + if( aBBox.Intersect( aRayPacket.m_ray[ia], &hitT ) + && ( hitT < aHitInfoPacket[ia].m_HitInfo.m_tHit ) ) + return ia; if( !aRayPacket.m_Frustum.Intersect( aBBox ) ) return RAYPACKET_RAYS_PER_PACKET; for( unsigned int i = ia + 1; i < RAYPACKET_RAYS_PER_PACKET; ++i ) { - if( aBBox.Intersect( aRayPacket.m_ray[i], &hitT ) ) - if( hitT < aHitInfoPacket[i].m_HitInfo.m_tHit ) - return i; + if( aBBox.Intersect( aRayPacket.m_ray[i], &hitT ) + && ( hitT < aHitInfoPacket[i].m_HitInfo.m_tHit ) ) + return i; } return RAYPACKET_RAYS_PER_PACKET; @@ -81,9 +81,9 @@ static inline unsigned int getLastHit( const RAYPACKET &aRayPacket, { float hitT; - if( aBBox.Intersect( aRayPacket.m_ray[ie], &hitT ) ) - if( hitT < aHitInfoPacket[ie].m_HitInfo.m_tHit ) - return ie + 1; + if( aBBox.Intersect( aRayPacket.m_ray[ie], &hitT ) + && ( hitT < aHitInfoPacket[ie].m_HitInfo.m_tHit ) ) + return ie + 1; } return ia + 1; @@ -94,8 +94,7 @@ static inline unsigned int getLastHit( const RAYPACKET &aRayPacket, // http://cseweb.ucsd.edu/~ravir/whitted.pdf // Ranged Traversal -bool CBVH_PBRT::Intersect( const RAYPACKET &aRayPacket, - HITINFO_PACKET *aHitInfoPacket ) const +bool CBVH_PBRT::Intersect( const RAYPACKET &aRayPacket, HITINFO_PACKET *aHitInfoPacket ) const { if( m_nodes == NULL ) return false; @@ -185,9 +184,9 @@ static inline unsigned int getLastHit( const RAYPACKET &aRayPacket, { float hitT; - if( aBBox.Intersect( aRayPacket.m_ray[ aRayIndex[ie] ], &hitT ) ) - if( hitT < aHitInfoPacket[ aRayIndex[ie] ].m_HitInfo.m_tHit ) - return ie + 1; + if( aBBox.Intersect( aRayPacket.m_ray[ aRayIndex[ie] ], &hitT ) + && ( hitT < aHitInfoPacket[ aRayIndex[ie] ].m_HitInfo.m_tHit ) ) + return ie + 1; } return ia + 1; @@ -209,17 +208,16 @@ static inline unsigned int partRays( const RAYPACKET &aRayPacket, for( unsigned int i = 0; i < ia; ++i ) { float hitT; - if( aBBox.Intersect( aRayPacket.m_ray[ aRayIndex[i] ], &hitT ) ) - if( hitT < aHitInfoPacket[ aRayIndex[i] ].m_HitInfo.m_tHit ) - std::swap( aRayIndex[ie++], aRayIndex[i] ); + if( aBBox.Intersect( aRayPacket.m_ray[ aRayIndex[i] ], &hitT ) + && ( hitT < aHitInfoPacket[ aRayIndex[i] ].m_HitInfo.m_tHit ) ) + std::swap( aRayIndex[ie++], aRayIndex[i] ); } return ie; } -bool CBVH_PBRT::Intersect( const RAYPACKET &aRayPacket, - HITINFO_PACKET *aHitInfoPacket ) const +bool CBVH_PBRT::Intersect( const RAYPACKET &aRayPacket, HITINFO_PACKET *aHitInfoPacket ) const { bool anyHitted = false; int todoOffset = 0, nodeNum = 0; @@ -265,9 +263,8 @@ bool CBVH_PBRT::Intersect( const RAYPACKET &aRayPacket, { unsigned int idx = I[i]; - bool hitted = obj->Intersect( - aRayPacket.m_ray[idx], - aHitInfoPacket[idx].m_HitInfo ); + bool hitted = obj->Intersect( aRayPacket.m_ray[idx], + aHitInfoPacket[idx].m_HitInfo ); if( hitted ) { diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/cbvh_pbrt.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/cbvh_pbrt.cpp index 080bcc5a01..93262b61b8 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/cbvh_pbrt.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/cbvh_pbrt.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -27,14 +27,14 @@ * @brief This BVH implementation is based on the source code implementation * from the book "Physically Based Rendering" (v2 and v3) * - * Adaptions performed for kicad: + * Adaptions performed for KiCad: * - Types and class types adapted to KiCad project * - Convert some source to build in the C++ specification of KiCad * - Code style to match KiCad * - Asserts converted * - Use compare functions/structures for std::partition and std::nth_element * - * The original source code has the following licence: + * The original source code has the following license: * * "pbrt source code is Copyright(c) 1998-2015 * Matt Pharr, Greg Humphreys, and Wenzel Jakob. @@ -252,13 +252,11 @@ CBVH_PBRT::CBVH_PBRT( const CGENERICCONTAINER &aObjectContainer, } // Convert the objects list to vector of objects - // ///////////////////////////////////////////////////////////////////////// aObjectContainer.ConvertTo( m_primitives ); wxASSERT( aObjectContainer.GetList().size() == m_primitives.size() ); // Initialize _primitiveInfo_ array for primitives - // ///////////////////////////////////////////////////////////////////////// std::vector primitiveInfo( m_primitives.size() ); for( size_t i = 0; i < m_primitives.size(); ++i ) @@ -331,8 +329,7 @@ struct ComparePoints int dim; - bool operator()( const BVHPrimitiveInfo &a, - const BVHPrimitiveInfo &b ) const + bool operator()( const BVHPrimitiveInfo &a, const BVHPrimitiveInfo &b ) const { return a.centroid[dim] < b.centroid[dim]; } @@ -357,7 +354,10 @@ struct CompareToBucket { CompareToBucket( int split, int num, int d, const CBBOX &b ) : centroidBounds(b) - { splitBucket = split; nBuckets = num; dim = d; } + { + splitBucket = split; + nBuckets = num; dim = d; + } bool operator()(const BVHPrimitiveInfo &p) const; @@ -389,7 +389,10 @@ struct HLBVH_SAH_Evaluator { HLBVH_SAH_Evaluator( int split, int num, int d, const CBBOX &b ) : centroidBounds(b) - { minCostSplitBucket = split; nBuckets = num; dim = d; } + { + minCostSplitBucket = split; + nBuckets = num; dim = d; + } bool operator()(const BVHBuildNode *node) const; @@ -497,8 +500,7 @@ BVHBuildNode *CBVH_PBRT::recursiveBuild ( std::vector &primiti { int primitiveNr = primitiveInfo[i].primitiveNumber; - wxASSERT( (primitiveNr >= 0) && - (primitiveNr < (int)m_primitives.size()) ); + wxASSERT( ( primitiveNr >= 0 ) && ( primitiveNr < (int) m_primitives.size() ) ); const COBJECT *obj = static_cast( m_primitives[ primitiveNr ] ); @@ -524,8 +526,7 @@ BVHBuildNode *CBVH_PBRT::recursiveBuild ( std::vector &primiti CompareToMid( dim, pmid ) ); mid = midPtr - &primitiveInfo[0]; - wxASSERT( (mid >= start) && - (mid <= end) ); + wxASSERT( ( mid >= start ) && ( mid <= end ) ); if( (mid != start) && (mid != end) ) break; @@ -593,7 +594,7 @@ BVHBuildNode *CBVH_PBRT::recursiveBuild ( std::vector &primiti // Compute costs for splitting after each bucket float cost[nBuckets - 1]; - for( int i = 0; i < (nBuckets - 1); ++i ) + for( int i = 0; i < ( nBuckets - 1 ); ++i ) { CBBOX b0, b1; @@ -640,10 +641,8 @@ BVHBuildNode *CBVH_PBRT::recursiveBuild ( std::vector &primiti } } - // Either create leaf or split primitives at selected SAH - // bucket - if( (nPrimitives > m_maxPrimsInNode) || - (minCost < (float)nPrimitives) ) + // Either create leaf or split primitives at selected SAH bucket + if( ( nPrimitives > m_maxPrimsInNode ) || ( minCost < (float) nPrimitives ) ) { BVHPrimitiveInfo *pmid = std::partition( &primitiveInfo[start], @@ -654,8 +653,7 @@ BVHBuildNode *CBVH_PBRT::recursiveBuild ( std::vector &primiti centroidBounds ) ); mid = pmid - &primitiveInfo[0]; - wxASSERT( (mid >= start) && - (mid <= end) ); + wxASSERT( ( mid >= start ) && ( mid <= end ) ); } else { @@ -724,9 +722,9 @@ BVHBuildNode *CBVH_PBRT::HLBVHBuild( const std::vector &primit const SFVEC3F centroidOffset = bounds.Offset( primitiveInfo[i].centroid ); - wxASSERT( (centroidOffset.x >= 0.0f) && (centroidOffset.x <= 1.0f) ); - wxASSERT( (centroidOffset.y >= 0.0f) && (centroidOffset.y <= 1.0f) ); - wxASSERT( (centroidOffset.z >= 0.0f) && (centroidOffset.z <= 1.0f) ); + wxASSERT( ( centroidOffset.x >= 0.0f ) && ( centroidOffset.x <= 1.0f ) ); + wxASSERT( ( centroidOffset.y >= 0.0f ) && ( centroidOffset.y <= 1.0f ) ); + wxASSERT( ( centroidOffset.z >= 0.0f ) && ( centroidOffset.z <= 1.0f ) ); mortonPrims[i].mortonCode = EncodeMorton3( centroidOffset * SFVEC3F( (float)mortonScale ) ); @@ -744,9 +742,9 @@ BVHBuildNode *CBVH_PBRT::HLBVHBuild( const std::vector &primit { const uint32_t mask = 0b00111111111111000000000000000000; - if( (end == (int)mortonPrims.size()) || - ( (mortonPrims[start].mortonCode & mask) != - (mortonPrims[end].mortonCode & mask) ) ) + if( ( end == (int) mortonPrims.size() ) + || ( ( mortonPrims[start].mortonCode & mask ) + != ( mortonPrims[end].mortonCode & mask ) ) ) { // Add entry to _treeletsToBuild_ for this treelet const int numPrimitives = end - start; @@ -754,7 +752,7 @@ BVHBuildNode *CBVH_PBRT::HLBVHBuild( const std::vector &primit // !TODO: implement a memory arena BVHBuildNode *nodes = static_cast( malloc( maxBVHNodes * - sizeof( BVHBuildNode ) ) ); + sizeof( BVHBuildNode ) ) ); m_addresses_pointer_to_mm_free.push_back( nodes ); @@ -825,12 +823,11 @@ BVHBuildNode *CBVH_PBRT::HLBVHBuild( const std::vector &primit } -BVHBuildNode *CBVH_PBRT::emitLBVH( - BVHBuildNode *&buildNodes, - const std::vector &primitiveInfo, - MortonPrimitive *mortonPrims, int nPrimitives, int *totalNodes, - CONST_VECTOR_OBJECT &orderedPrims, - int *orderedPrimsOffset, int bit) +BVHBuildNode *CBVH_PBRT::emitLBVH( BVHBuildNode *&buildNodes, + const std::vector &primitiveInfo, + MortonPrimitive *mortonPrims, int nPrimitives, int *totalNodes, + CONST_VECTOR_OBJECT &orderedPrims, + int *orderedPrimsOffset, int bit ) { wxASSERT( nPrimitives > 0 ); wxASSERT( totalNodes != NULL ); @@ -838,7 +835,7 @@ BVHBuildNode *CBVH_PBRT::emitLBVH( wxASSERT( nPrimitives > 0 ); wxASSERT( mortonPrims != NULL ); - if( (bit == -1) || (nPrimitives < m_maxPrimsInNode) ) + if( ( bit == -1 ) || ( nPrimitives < m_maxPrimsInNode ) ) { // Create and return leaf node of LBVH treelet (*totalNodes)++; @@ -850,7 +847,7 @@ BVHBuildNode *CBVH_PBRT::emitLBVH( int firstPrimOffset = *orderedPrimsOffset; *orderedPrimsOffset += nPrimitives; - wxASSERT( (firstPrimOffset + (nPrimitives - 1)) < (int)orderedPrims.size() ); + wxASSERT( ( firstPrimOffset + ( nPrimitives - 1 ) ) < (int) orderedPrims.size() ); for( int i = 0; i < nPrimitives; ++i ) { @@ -871,11 +868,10 @@ BVHBuildNode *CBVH_PBRT::emitLBVH( int mask = 1 << bit; // Advance to next subtree level if there's no LBVH split for this bit - if( (mortonPrims[0].mortonCode & mask) == - (mortonPrims[nPrimitives - 1].mortonCode & mask) ) - return emitLBVH( buildNodes, primitiveInfo, mortonPrims, nPrimitives, - totalNodes, orderedPrims, orderedPrimsOffset, - bit - 1 ); + if( ( mortonPrims[0].mortonCode & mask ) == + ( mortonPrims[nPrimitives - 1].mortonCode & mask ) ) + return emitLBVH( buildNodes, primitiveInfo, mortonPrims, nPrimitives, totalNodes, + orderedPrims, orderedPrimsOffset, bit - 1 ); // Find LBVH split point for this dimension int searchStart = 0; @@ -887,13 +883,13 @@ BVHBuildNode *CBVH_PBRT::emitLBVH( const int mid = (searchStart + searchEnd) / 2; - if( (mortonPrims[searchStart].mortonCode & mask) == - (mortonPrims[mid].mortonCode & mask) ) + if( ( mortonPrims[searchStart].mortonCode & mask ) == + ( mortonPrims[mid].mortonCode & mask ) ) searchStart = mid; else { - wxASSERT( (mortonPrims[mid].mortonCode & mask) == - (mortonPrims[searchEnd].mortonCode & mask) ); + wxASSERT( ( mortonPrims[mid].mortonCode & mask ) == + ( mortonPrims[searchEnd].mortonCode & mask ) ); searchEnd = mid; } } @@ -911,11 +907,11 @@ BVHBuildNode *CBVH_PBRT::emitLBVH( BVHBuildNode *lbvh[2]; lbvh[0] = emitLBVH( buildNodes, primitiveInfo, mortonPrims, splitOffset, - totalNodes, orderedPrims, orderedPrimsOffset, bit - 1 ); + totalNodes, orderedPrims, orderedPrimsOffset, bit - 1 ); lbvh[1] = emitLBVH( buildNodes, primitiveInfo, &mortonPrims[splitOffset], - nPrimitives - splitOffset, totalNodes, orderedPrims, - orderedPrimsOffset, bit - 1 ); + nPrimitives - splitOffset, totalNodes, orderedPrims, + orderedPrimsOffset, bit - 1 ); const int axis = bit % 3; @@ -926,10 +922,8 @@ BVHBuildNode *CBVH_PBRT::emitLBVH( } -BVHBuildNode *CBVH_PBRT::buildUpperSAH( - std::vector &treeletRoots, - int start, int end, - int *totalNodes ) +BVHBuildNode *CBVH_PBRT::buildUpperSAH( std::vector &treeletRoots, + int start, int end, int *totalNodes ) { wxASSERT( totalNodes != NULL ); wxASSERT( start < end ); @@ -940,7 +934,6 @@ BVHBuildNode *CBVH_PBRT::buildUpperSAH( if( nNodes == 1 ) return treeletRoots[start]; - (*totalNodes)++; BVHBuildNode *node = static_cast( malloc( sizeof( BVHBuildNode ) ) ); @@ -997,14 +990,13 @@ BVHBuildNode *CBVH_PBRT::buildUpperSAH( const float centroid = ( treeletRoots[i]->bounds.Min()[dim] + treeletRoots[i]->bounds.Max()[dim] ) * 0.5f; - int b = - nBuckets * ( (centroid - centroidBounds.Min()[dim] ) / - (centroidBounds.Max()[dim] - centroidBounds.Min()[dim] ) ); + int b = nBuckets * ( (centroid - centroidBounds.Min()[dim] ) / + (centroidBounds.Max()[dim] - centroidBounds.Min()[dim] ) ); if( b == nBuckets ) b = nBuckets - 1; - wxASSERT( (b >= 0) && (b < nBuckets) ); + wxASSERT( ( b >= 0 ) && ( b < nBuckets ) ); buckets[b].count++; buckets[b].bounds.Union( treeletRoots[i]->bounds ); @@ -1095,7 +1087,7 @@ int CBVH_PBRT::flattenBVHTree( BVHBuildNode *node, uint32_t *offset ) } else { - // Creater interior flattened BVH node + // Create interior flattened BVH node linearNode->axis = node->splitAxis; linearNode->nPrimitives = 0; flattenBVHTree( node->children[0], offset ); @@ -1108,6 +1100,7 @@ int CBVH_PBRT::flattenBVHTree( BVHBuildNode *node, uint32_t *offset ) #define MAX_TODOS 64 + bool CBVH_PBRT::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const { if( !m_nodes ) @@ -1137,8 +1130,7 @@ bool CBVH_PBRT::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const // Intersect ray with primitives in leaf BVH node for( int i = 0; i < node->nPrimitives; ++i ) { - if( m_primitives[node->primitivesOffset + i]->Intersect( aRay, - aHitInfo ) ) + if( m_primitives[node->primitivesOffset + i]->Intersect( aRay, aHitInfo ) ) { aHitInfo.m_acc_node_info = nodeNum; hit = true; @@ -1172,10 +1164,9 @@ bool CBVH_PBRT::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const return hit; } -// !TODO: this may be optimized -bool CBVH_PBRT::Intersect( const RAY &aRay, - HITINFO &aHitInfo, - unsigned int aAccNodeInfo ) const + +/// @todo This may be optimized +bool CBVH_PBRT::Intersect( const RAY& aRay, HITINFO& aHitInfo, unsigned int aAccNodeInfo ) const { if( !m_nodes ) return false; @@ -1197,15 +1188,14 @@ bool CBVH_PBRT::Intersect( const RAY &aRay, const bool hitted = node->bounds.Intersect( aRay, &hitBox ); - if( hitted && (hitBox < aHitInfo.m_tHit) ) + if( hitted && ( hitBox < aHitInfo.m_tHit ) ) { if( node->nPrimitives > 0 ) { // Intersect ray with primitives in leaf BVH node for( int i = 0; i < node->nPrimitives; ++i ) { - if( m_primitives[node->primitivesOffset + i]->Intersect( aRay, - aHitInfo ) ) + if( m_primitives[node->primitivesOffset + i]->Intersect( aRay, aHitInfo ) ) { //aHitInfo.m_acc_node_info = nodeNum; hit = true; @@ -1260,7 +1250,7 @@ bool CBVH_PBRT::IntersectP( const RAY &aRay, float aMaxDistance ) const const bool hitted = node->bounds.Intersect( aRay, &hitBox ); - if( hitted && (hitBox < aMaxDistance) ) + if( hitted && ( hitBox < aMaxDistance ) ) { if( node->nPrimitives > 0 ) { @@ -1269,9 +1259,9 @@ bool CBVH_PBRT::IntersectP( const RAY &aRay, float aMaxDistance ) const { const COBJECT *obj = m_primitives[node->primitivesOffset + i]; - if( obj->GetMaterial()->GetCastShadows() ) - if( obj->IntersectP( aRay, aMaxDistance ) ) - return true; + if( obj->GetMaterial()->GetCastShadows() + && obj->IntersectP( aRay, aMaxDistance ) ) + return true; } } else diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/cbvh_pbrt.h b/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/cbvh_pbrt.h index e0d40c389b..bcfd6136cb 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/cbvh_pbrt.h +++ b/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/cbvh_pbrt.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -111,7 +111,7 @@ class CBVH_PBRT : public CGENERICACCELERATOR { public: CBVH_PBRT( const CGENERICCONTAINER& aObjectContainer, int aMaxPrimsInNode = 4, - SPLITMETHOD aSplitMethod = SPLITMETHOD::SAH ); + SPLITMETHOD aSplitMethod = SPLITMETHOD::SAH ); ~CBVH_PBRT(); @@ -148,8 +148,7 @@ private: int end, int *totalNodes ); - int flattenBVHTree( BVHBuildNode *node, - uint32_t *offset ); + int flattenBVHTree( BVHBuildNode *node, uint32_t *offset ); // BVH Private Data const int m_maxPrimsInNode; diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/ccontainer.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/ccontainer.cpp index d49c6b9ed2..e901032035 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/ccontainer.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/ccontainer.cpp @@ -36,13 +36,12 @@ CGENERICCONTAINER::CGENERICCONTAINER() m_bbox.Reset(); } + void CGENERICCONTAINER::Clear() { if( !m_objects.empty() ) { - for( LIST_OBJECT::iterator ii = m_objects.begin(); - ii != m_objects.end(); - ++ii ) + for( LIST_OBJECT::iterator ii = m_objects.begin(); ii != m_objects.end(); ++ii ) { delete *ii; *ii = NULL; @@ -69,9 +68,7 @@ void CGENERICCONTAINER::ConvertTo( CONST_VECTOR_OBJECT &aOutVector ) const { unsigned int i = 0; - for( LIST_OBJECT::const_iterator ii = m_objects.begin(); - ii != m_objects.end(); - ++ii ) + for( LIST_OBJECT::const_iterator ii = m_objects.begin(); ii != m_objects.end(); ++ii ) { wxASSERT( (*ii) != NULL ); @@ -89,11 +86,9 @@ bool CCONTAINER::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const bool hitted = false; - for( LIST_OBJECT::const_iterator ii = m_objects.begin(); - ii != m_objects.end(); - ++ii ) + for( LIST_OBJECT::const_iterator ii = m_objects.begin(); ii != m_objects.end(); ++ii ) { - const COBJECT *object = static_cast(*ii); + const COBJECT *object = static_cast( *ii ); if( object->Intersect( aRay, aHitInfo) ) hitted = true; @@ -105,14 +100,13 @@ bool CCONTAINER::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const bool CCONTAINER::IntersectP( const RAY &aRay, float aMaxDistance ) const { + /// @todo Determine what to do with this commented out code. /* if( !m_bbox.Inside( aRay.m_Origin ) ) if( !m_bbox.Intersect( aRay ) ) return false; */ - for( LIST_OBJECT::const_iterator ii = m_objects.begin(); - ii != m_objects.end(); - ++ii ) + for( LIST_OBJECT::const_iterator ii = m_objects.begin(); ii != m_objects.end(); ++ii ) { const COBJECT *object = static_cast(*ii); diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/ccontainer.h b/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/ccontainer.h index 59b5377223..f672662477 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/ccontainer.h +++ b/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/ccontainer.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -38,12 +38,9 @@ typedef std::list LIST_OBJECT; typedef std::vector VECTOR_OBJECT; typedef std::vector CONST_VECTOR_OBJECT; -class CGENERICCONTAINER -{ -protected: - CBBOX m_bbox; - LIST_OBJECT m_objects; +class CGENERICCONTAINER +{ public: CGENERICCONTAINER(); @@ -51,7 +48,7 @@ public: void Add( COBJECT *aObject ) { - if( aObject ) // Only add if it is a valid pointer + if( aObject ) { m_objects.push_back( aObject ); m_bbox.Union( aObject->GetBBox() ); @@ -69,11 +66,13 @@ public: virtual bool Intersect( const RAY &aRay, HITINFO &aHitInfo ) const = 0; virtual bool IntersectP( const RAY &aRay, float aMaxDistance ) const = 0; -private: +protected: + CBBOX m_bbox; + LIST_OBJECT m_objects; }; -class CCONTAINER : public CGENERICCONTAINER +class CCONTAINER : public CGENERICCONTAINER { public: bool Intersect( const RAY &aRay, HITINFO &aHitInfo ) const override; diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/ccontainer2d.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/ccontainer2d.cpp index c57044b013..6abdf4c07a 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/ccontainer2d.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/ccontainer2d.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -35,10 +35,6 @@ #include -// ///////////////////////////////////////////////////////////////////////////// -// CGENERICCONTAINER2 -// ///////////////////////////////////////////////////////////////////////////// - CGENERICCONTAINER2D::CGENERICCONTAINER2D( OBJECT2D_TYPE aObjType ) { m_bbox.Reset(); @@ -67,16 +63,13 @@ CGENERICCONTAINER2D::~CGENERICCONTAINER2D() } - - -// ///////////////////////////////////////////////////////////////////////////// -// CCONTAINER2D -// ///////////////////////////////////////////////////////////////////////////// - CCONTAINER2D::CCONTAINER2D() : CGENERICCONTAINER2D( OBJECT2D_TYPE::CONTAINER ) { } + + +/// @todo Determine what to do with this commented out code. /* bool CCONTAINER2D::Intersects( const CBBOX2D &aBBox ) const @@ -149,22 +142,17 @@ bool CCONTAINER2D::IsPointInside( const SFVEC2F &aPoint ) const void CCONTAINER2D::GetListObjectsIntersects( const CBBOX2D & aBBox, CONST_LIST_OBJECT2D &aOutList ) const { - // !TODO: + /// @todo Determine what to do with this code. } bool CCONTAINER2D::IntersectAny( const RAYSEG2D &aSegRay ) const { - // !TODO: + /// @todo Determine what what needs done because someone wrote TODO here. return false; } - -// ///////////////////////////////////////////////////////////////////////////// -// CBVHCONTAINER2D -// ///////////////////////////////////////////////////////////////////////////// - CBVHCONTAINER2D::CBVHCONTAINER2D() : CGENERICCONTAINER2D( OBJECT2D_TYPE::BVHCONTAINER ) { m_isInitialized = false; @@ -173,6 +161,8 @@ CBVHCONTAINER2D::CBVHCONTAINER2D() : CGENERICCONTAINER2D( OBJECT2D_TYPE::BVHCONT m_Tree = NULL; } + +/// @todo Determine what to do with this commented out code. /* bool CBVHCONTAINER2D::Intersects( const CBBOX2D &aBBox ) const { @@ -246,12 +236,14 @@ bool CBVHCONTAINER2D::IsPointInside( const SFVEC2F &aPoint ) const } */ + void CBVHCONTAINER2D::Clear() { CGENERICCONTAINER2D::Clear(); destroy(); } + void CBVHCONTAINER2D::destroy() { for( std::list::iterator ii = m_elements_to_delete.begin(); @@ -260,6 +252,7 @@ void CBVHCONTAINER2D::destroy() { delete *ii; } + m_elements_to_delete.clear(); m_Tree = nullptr; m_isInitialized = false; @@ -292,11 +285,9 @@ void CBVHCONTAINER2D::BuildBVH() m_elements_to_delete.push_back( m_Tree ); m_Tree->m_BBox = m_bbox; - for( LIST_OBJECT2D::const_iterator ii = m_objects.begin(); - ii != m_objects.end(); - ++ii ) + for( LIST_OBJECT2D::const_iterator ii = m_objects.begin(); ii != m_objects.end(); ++ii ) { - m_Tree->m_LeafList.push_back( static_cast(*ii) ); + m_Tree->m_LeafList.push_back( static_cast( *ii ) ); } recursiveBuild_MIDDLE_SPLIT( m_Tree ); @@ -310,22 +301,24 @@ void CBVHCONTAINER2D::BuildBVH() // "Split in the middle of the longest Axis" // "Creates a binary tree with Top-Down approach. // Fastest BVH building, but least [speed] accuracy." - static bool sortByCentroid_X( const COBJECT2D *a, const COBJECT2D *b ) { return a->GetCentroid()[0] < b->GetCentroid()[0]; } + static bool sortByCentroid_Y( const COBJECT2D *a, const COBJECT2D *b ) { return a->GetCentroid()[0] < b->GetCentroid()[0]; } + static bool sortByCentroid_Z( const COBJECT2D *a, const COBJECT2D *b ) { return a->GetCentroid()[0] < b->GetCentroid()[0]; } + void CBVHCONTAINER2D::recursiveBuild_MIDDLE_SPLIT( BVH_CONTAINER_NODE_2D *aNodeParent ) { wxASSERT( aNodeParent != NULL ); @@ -345,7 +338,7 @@ void CBVHCONTAINER2D::recursiveBuild_MIDDLE_SPLIT( BVH_CONTAINER_NODE_2D *aNodeP leftNode->m_LeafList.clear(); rightNode->m_LeafList.clear(); - // Decide wich axis to split + // Decide which axis to split const unsigned int axis_to_split = aNodeParent->m_BBox.MaxDimension(); // Divide the objects @@ -454,6 +447,7 @@ bool CBVHCONTAINER2D::recursiveIntersectAny( const BVH_CONTAINER_NODE_2D *aNode, return false; } + void CBVHCONTAINER2D::GetListObjectsIntersects( const CBBOX2D &aBBox, CONST_LIST_OBJECT2D &aOutList ) const { diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/ccontainer2d.h b/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/ccontainer2d.h index aa6d2edd0a..b4ed43ed26 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/ccontainer2d.h +++ b/3d-viewer/3d_rendering/3d_render_raytracing/accelerators/ccontainer2d.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2020 Mario Luzeiro - * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -38,12 +38,8 @@ typedef std::list LIST_OBJECT2D; typedef std::list CONST_LIST_OBJECT2D; -class CGENERICCONTAINER2D +class CGENERICCONTAINER2D { -protected: - CBBOX2D m_bbox; - LIST_OBJECT2D m_objects; - public: explicit CGENERICCONTAINER2D( OBJECT2D_TYPE aObjType ); @@ -51,7 +47,7 @@ public: void Add( COBJECT2D *aObject ) { - if( aObject ) // Only add if it is a valid pointer + if( aObject ) { std::lock_guard lock( m_lock ); m_objects.push_back( aObject ); @@ -69,26 +65,32 @@ public: const LIST_OBJECT2D &GetList() const { return m_objects; } /** - * @brief GetListObjectsIntersects - Get a list of objects that intersects a bbox - * @param aBBox - a bbox to make the query - * @param aOutList - A list of objects that intersects the bbox + * Get a list of objects that intersects a bounding box. + * + * @param aBBox The bounding box to test. + * @param aOutList The list of objects that intersects the bounding box. */ virtual void GetListObjectsIntersects( const CBBOX2D & aBBox, CONST_LIST_OBJECT2D &aOutList ) const = 0; /** - * @brief IntersectAny - Intersect and check if a segment ray hits a object or is inside it - * @param aSegRay - a segment to intersect with objects - * @return true - if it hits any of the objects or is inside any object + * Intersect and check if a segment ray hits a object or is inside it. + * + * @param aSegRay The segment to intersect with objects. + * @return true if it hits any of the objects or is inside any object. */ virtual bool IntersectAny( const RAYSEG2D &aSegRay ) const = 0; +protected: + CBBOX2D m_bbox; + LIST_OBJECT2D m_objects; + private: std::mutex m_lock; }; -class CCONTAINER2D : public CGENERICCONTAINER2D +class CCONTAINER2D : public CGENERICCONTAINER2D { public: CCONTAINER2D(); @@ -111,7 +113,7 @@ struct BVH_CONTAINER_NODE_2D }; -class CBVHCONTAINER2D : public CGENERICCONTAINER2D +class CBVHCONTAINER2D : public CGENERICCONTAINER2D { public: CBVHCONTAINER2D(); @@ -121,11 +123,13 @@ public: void Clear() override; -private: - bool m_isInitialized; - std::list m_elements_to_delete; - BVH_CONTAINER_NODE_2D *m_Tree; + // Imported from CGENERICCONTAINER2D + void GetListObjectsIntersects( const CBBOX2D & aBBox, + CONST_LIST_OBJECT2D &aOutList ) const override; + bool IntersectAny( const RAYSEG2D &aSegRay ) const override; + +private: void destroy(); void recursiveBuild_MIDDLE_SPLIT( BVH_CONTAINER_NODE_2D *aNodeParent ); void recursiveGetListObjectsIntersects( const BVH_CONTAINER_NODE_2D *aNode, @@ -134,13 +138,10 @@ private: bool recursiveIntersectAny( const BVH_CONTAINER_NODE_2D *aNode, const RAYSEG2D &aSegRay ) const; -public: + bool m_isInitialized; + std::list m_elements_to_delete; + BVH_CONTAINER_NODE_2D* m_Tree; - // Imported from CGENERICCONTAINER2D - void GetListObjectsIntersects( const CBBOX2D & aBBox, - CONST_LIST_OBJECT2D &aOutList ) const override; - - bool IntersectAny( const RAYSEG2D &aSegRay ) const override; }; #endif // _CCONTAINER2D_H_ diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp index 5dd4c40d02..70f138c7e0 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -49,9 +49,9 @@ #include // To use GetRunningMicroSecs or another profiling utility /** - * @brief TransparencyAlphaControl * Perform an interpolation step to easy control the transparency based on the - * gray color value and transparency + * gray color value and transparency. + * * @param aGrayColorValue - diffuse gray value * @param aTransparency - control * @return transparency to use in material @@ -62,15 +62,16 @@ static float TransparencyControl( float aGrayColorValue, float aTransparency ) // 1.00-1.05*(1.0-x)^3 float ca = 1.0f - aTransparency; - ca = 1.00f - 1.05f * ca * ca * ca; + ca = 1.00f - 1.05f * ca * ca * ca; return glm::max( glm::min( aGrayColorValue * ca + aaa, 1.0f ), 0.0f ); } /** - * Scale convertion from 3d model units to pcb units + * Scale conversion from 3d model units to pcb units */ -#define UNITS3D_TO_UNITSPCB (IU_PER_MM) +#define UNITS3D_TO_UNITSPCB ( IU_PER_MM ) + void C3D_RENDER_RAYTRACING::setupMaterials() { @@ -84,10 +85,10 @@ void C3D_RENDER_RAYTRACING::setupMaterials() if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) ) { - m_board_normal_perturbator = CBOARDNORMAL( 0.40f * mmTo3Dunits ); + m_board_normal_perturbator = CBOARDNORMAL( 0.40f * mmTo3Dunits ); - m_copper_normal_perturbator = CCOPPERNORMAL( 4.0f * mmTo3Dunits, - &m_board_normal_perturbator ); + m_copper_normal_perturbator = + CCOPPERNORMAL( 4.0f * mmTo3Dunits, &m_board_normal_perturbator ); m_platedcopper_normal_perturbator = CPLATEDCOPPERNORMAL( 0.5f * mmTo3Dunits ); @@ -105,47 +106,48 @@ void C3D_RENDER_RAYTRACING::setupMaterials() // http://devernay.free.fr/cours/opengl/materials.html // Copper - const SFVEC3F copperSpecularLinear = ConvertSRGBToLinear( - glm::clamp( (SFVEC3F)m_boardAdapter.m_CopperColor * 0.5f + 0.25f, - SFVEC3F( 0.0f ), - SFVEC3F( 1.0f ) ) ); + const SFVEC3F copperSpecularLinear = + ConvertSRGBToLinear( glm::clamp( (SFVEC3F) m_boardAdapter.m_CopperColor * 0.5f + 0.25f, + SFVEC3F( 0.0f ), SFVEC3F( 1.0f ) ) ); - m_materials.m_Copper = CBLINN_PHONG_MATERIAL( ConvertSRGBToLinear( (SFVEC3F)m_boardAdapter.m_CopperColor * 0.3f ), // ambient - SFVEC3F( 0.0f ), // emissive - copperSpecularLinear, // specular - 0.4f * 128.0f, // shiness - 0.0f, // transparency - 0.0f ); + m_materials.m_Copper = CBLINN_PHONG_MATERIAL( + ConvertSRGBToLinear( (SFVEC3F) m_boardAdapter.m_CopperColor * 0.3f ), // ambient + SFVEC3F( 0.0f ), // emissive + copperSpecularLinear, // specular + 0.4f * 128.0f, // shiness + 0.0f, // transparency + 0.0f ); if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) ) m_materials.m_Copper.SetNormalPerturbator( &m_platedcopper_normal_perturbator ); m_materials.m_NonPlatedCopper = CBLINN_PHONG_MATERIAL( - ConvertSRGBToLinear( SFVEC3F( 0.191f, 0.073f, 0.022f ) ),// ambient - SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive - SFVEC3F( 0.256f, 0.137f, 0.086f ), // specular - 0.15f * 128.0f, // shiness - 0.0f, // transparency - 0.0f ); + ConvertSRGBToLinear( SFVEC3F( 0.191f, 0.073f, 0.022f ) ), // ambient + SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive + SFVEC3F( 0.256f, 0.137f, 0.086f ), // specular + 0.15f * 128.0f, // shiness + 0.0f, // transparency + 0.0f ); if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) ) m_materials.m_NonPlatedCopper.SetNormalPerturbator( &m_copper_normal_perturbator ); m_materials.m_Paste = CBLINN_PHONG_MATERIAL( - ConvertSRGBToLinear( (SFVEC3F)m_boardAdapter.m_SolderPasteColor ) * - ConvertSRGBToLinear( (SFVEC3F)m_boardAdapter.m_SolderPasteColor ), // ambient - SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive - ConvertSRGBToLinear( (SFVEC3F)m_boardAdapter.m_SolderPasteColor ) * - ConvertSRGBToLinear( (SFVEC3F)m_boardAdapter.m_SolderPasteColor ), // specular - 0.10f * 128.0f, // shiness - 0.0f, // transparency - 0.0f ); + ConvertSRGBToLinear( (SFVEC3F) m_boardAdapter.m_SolderPasteColor ) + * ConvertSRGBToLinear( (SFVEC3F) m_boardAdapter.m_SolderPasteColor ), // ambient + SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive + ConvertSRGBToLinear( (SFVEC3F) m_boardAdapter.m_SolderPasteColor ) + * ConvertSRGBToLinear( + (SFVEC3F) m_boardAdapter.m_SolderPasteColor ), // specular + 0.10f * 128.0f, // shiness + 0.0f, // transparency + 0.0f ); m_materials.m_SilkS = CBLINN_PHONG_MATERIAL( ConvertSRGBToLinear( SFVEC3F( 0.11f ) ), // ambient SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive - glm::clamp( - ( ( SFVEC3F )( 1.0f ) - - ConvertSRGBToLinear( (SFVEC3F) m_boardAdapter.m_SilkScreenColorTop ) ), + glm::clamp( ( ( SFVEC3F )( 1.0f ) + - ConvertSRGBToLinear( + (SFVEC3F) m_boardAdapter.m_SilkScreenColorTop ) ), SFVEC3F( 0.0f ), SFVEC3F( 0.10f ) ), // specular 0.078125f * 128.0f, // shiness @@ -158,19 +160,19 @@ void C3D_RENDER_RAYTRACING::setupMaterials() // Assume that SolderMaskTop == SolderMaskBot const float solderMask_gray = ( m_boardAdapter.m_SolderMaskColorTop.r + m_boardAdapter.m_SolderMaskColorTop.g - + m_boardAdapter.m_SolderMaskColorTop.b ) + + m_boardAdapter.m_SolderMaskColorTop.b ) / 3.0f; const float solderMask_transparency = TransparencyControl( solderMask_gray, - 1.0f - m_boardAdapter.m_SolderMaskColorTop.a ); // opacity to transparency + 1.0f - m_boardAdapter.m_SolderMaskColorTop.a ); // opacity to transparency m_materials.m_SolderMask = CBLINN_PHONG_MATERIAL( ConvertSRGBToLinear( (SFVEC3F) m_boardAdapter.m_SolderMaskColorTop ) * 0.10f, // ambient - SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive - SFVEC3F( glm::clamp( solderMask_gray * 2.0f, 0.25f, 1.0f ) ), // specular - 0.85f * 128.0f, // shiness - solderMask_transparency, // transparency - 0.16f ); // reflection + SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive + SFVEC3F( glm::clamp( solderMask_gray * 2.0f, 0.25f, 1.0f ) ), // specular + 0.85f * 128.0f, // shiness + solderMask_transparency, // transparency + 0.16f ); // reflection m_materials.m_SolderMask.SetCastShadows( true ); m_materials.m_SolderMask.SetNrRefractionsSamples( 1 ); @@ -178,47 +180,35 @@ void C3D_RENDER_RAYTRACING::setupMaterials() if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) ) m_materials.m_SolderMask.SetNormalPerturbator( &m_solder_mask_normal_perturbator ); - m_materials.m_EpoxyBoard = CBLINN_PHONG_MATERIAL( - ConvertSRGBToLinear( SFVEC3F( 16.0f / 255.0f, - 14.0f / 255.0f, - 10.0f / 255.0f ) ), // ambient - SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive - ConvertSRGBToLinear( SFVEC3F( 10.0f / 255.0f, - 8.0f / 255.0f, - 10.0f / 255.0f ) ), // specular - 0.1f * 128.0f, // shiness - 1.0f - m_boardAdapter.m_BoardBodyColor.a, // opacity to transparency - 0.0f ); // reflection + m_materials.m_EpoxyBoard = + CBLINN_PHONG_MATERIAL( ConvertSRGBToLinear( SFVEC3F( 16.0f / 255.0f, 14.0f / 255.0f, + 10.0f / 255.0f ) ), // ambient + SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive + ConvertSRGBToLinear( SFVEC3F( 10.0f / 255.0f, 8.0f / 255.0f, + 10.0f / 255.0f ) ), // specular + 0.1f * 128.0f, // shiness + 1.0f - m_boardAdapter.m_BoardBodyColor.a, // opacity to transparency + 0.0f ); // reflection m_materials.m_EpoxyBoard.SetAbsorvance( 10.0f ); if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) ) m_materials.m_EpoxyBoard.SetNormalPerturbator( &m_board_normal_perturbator ); - SFVEC3F bgTop = ConvertSRGBToLinear( (SFVEC3F)m_boardAdapter.m_BgColorTop ); + SFVEC3F bgTop = ConvertSRGBToLinear( (SFVEC3F) m_boardAdapter.m_BgColorTop ); //SFVEC3F bgBot = (SFVEC3F)m_boardAdapter.m_BgColorBot; - m_materials.m_Floor = CBLINN_PHONG_MATERIAL( - bgTop * 0.125f, // ambient - SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive - (SFVEC3F(1.0f) - bgTop) / 3.0f, // specular - 0.10f * 128.0f, // shiness - 0.0f, // transparency - 0.50f ); // reflection + m_materials.m_Floor = CBLINN_PHONG_MATERIAL( bgTop * 0.125f, // ambient + SFVEC3F( 0.0f, 0.0f, 0.0f ), // emissive + ( SFVEC3F( 1.0f ) - bgTop ) / 3.0f, // specular + 0.10f * 128.0f, // shiness + 0.0f, // transparency + 0.50f ); // reflection m_materials.m_Floor.SetCastShadows( false ); m_materials.m_Floor.SetReflectionsRecursiveLevel( 1 ); } - -/** Function create_3d_object_from - * @brief 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. - * @param aObject2D - * @param aZMin - * @param aZMax - */ void C3D_RENDER_RAYTRACING::create_3d_object_from( CCONTAINER& aDstContainer, const COBJECT2D* aObject2D, float aZMin, float aZMax, const CMATERIAL* aMaterial, const SFVEC3F& aObjColor ) @@ -277,30 +267,28 @@ void C3D_RENDER_RAYTRACING::create_3d_object_from( CCONTAINER& aDstContainer, } } -void C3D_RENDER_RAYTRACING::createItemsFromContainer( const CBVHCONTAINER2D *aContainer2d, - PCB_LAYER_ID aLayer_id, - const CMATERIAL *aMaterialLayer, - const SFVEC3F &aLayerColor, - float aLayerZOffset ) +void C3D_RENDER_RAYTRACING::createItemsFromContainer( const CBVHCONTAINER2D* aContainer2d, + PCB_LAYER_ID aLayer_id, const CMATERIAL* aMaterialLayer, const SFVEC3F& aLayerColor, + float aLayerZOffset ) { if( aContainer2d == nullptr ) return; - const LIST_OBJECT2D &listObject2d = aContainer2d->GetList(); + const LIST_OBJECT2D& listObject2d = aContainer2d->GetList(); if( listObject2d.size() == 0 ) return; for( LIST_OBJECT2D::const_iterator itemOnLayer = listObject2d.begin(); - itemOnLayer != listObject2d.end(); - ++itemOnLayer ) + itemOnLayer != listObject2d.end(); ++itemOnLayer ) { - const COBJECT2D *object2d_A = static_cast(*itemOnLayer); + const COBJECT2D* object2d_A = static_cast( *itemOnLayer ); - // not yet used / implemented (can be used in future to clip the objects in the board borders - COBJECT2D *object2d_C = CSGITEM_FULL; + // not yet used / implemented (can be used in future to clip the objects in the + // board borders + COBJECT2D* object2d_C = CSGITEM_FULL; - std::vector *object2d_B = CSGITEM_EMPTY; + std::vector* object2d_B = CSGITEM_EMPTY; object2d_B = new std::vector(); @@ -309,33 +297,31 @@ void C3D_RENDER_RAYTRACING::createItemsFromContainer( const CBVHCONTAINER2D *aCo if( !( ( aLayer_id == B_Paste ) || ( aLayer_id == F_Paste ) ) ) { // Check if there are any layerhole that intersects this object - // Eg: a segment is cutted by a via hole or THT hole. + // Eg: a segment is cut by a via hole or THT hole. // ///////////////////////////////////////////////////////////// - const MAP_CONTAINER_2D &layerHolesMap = m_boardAdapter.GetMapLayersHoles(); + const MAP_CONTAINER_2D& layerHolesMap = m_boardAdapter.GetMapLayersHoles(); - if( layerHolesMap.find(aLayer_id) != layerHolesMap.end() ) + if( layerHolesMap.find( aLayer_id ) != layerHolesMap.end() ) { - MAP_CONTAINER_2D::const_iterator ii_hole = layerHolesMap.find(aLayer_id); + MAP_CONTAINER_2D::const_iterator ii_hole = layerHolesMap.find( aLayer_id ); - const CBVHCONTAINER2D *containerLayerHoles2d = - static_cast(ii_hole->second); + const CBVHCONTAINER2D* containerLayerHoles2d = + static_cast( ii_hole->second ); CONST_LIST_OBJECT2D intersectionList; - containerLayerHoles2d->GetListObjectsIntersects( object2d_A->GetBBox(), - intersectionList ); + containerLayerHoles2d->GetListObjectsIntersects( + object2d_A->GetBBox(), intersectionList ); if( !intersectionList.empty() ) { - for( CONST_LIST_OBJECT2D::const_iterator holeOnLayer = - intersectionList.begin(); - holeOnLayer != intersectionList.end(); - ++holeOnLayer ) + for( CONST_LIST_OBJECT2D::const_iterator holeOnLayer = intersectionList.begin(); + holeOnLayer != intersectionList.end(); ++holeOnLayer ) { - const COBJECT2D *hole2d = static_cast(*holeOnLayer); + const COBJECT2D* hole2d = static_cast( *holeOnLayer ); //if( object2d_A->Intersects( hole2d->GetBBox() ) ) - //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) ) - object2d_B->push_back( hole2d ); + //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) ) + object2d_B->push_back( hole2d ); } } } @@ -347,8 +333,8 @@ void C3D_RENDER_RAYTRACING::createItemsFromContainer( const CBVHCONTAINER2D *aCo // clip the silk screening at the outer edge of the annular ring, rather // than the at the outer edge of the copper plating. const CBVHCONTAINER2D& throughHoleOuter = - ( m_boardAdapter.GetFlag( FL_CLIP_SILK_ON_VIA_ANNULUS ) && - m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) + ( m_boardAdapter.GetFlag( FL_CLIP_SILK_ON_VIA_ANNULUS ) + && m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) && ( ( aLayer_id == B_SilkS ) || ( aLayer_id == F_SilkS ) ) ) ? m_boardAdapter.GetThroughHole_Outer_Ring() : m_boardAdapter.GetThroughHole_Outer(); @@ -363,14 +349,13 @@ void C3D_RENDER_RAYTRACING::createItemsFromContainer( const CBVHCONTAINER2D *aCo if( !intersectionList.empty() ) { for( CONST_LIST_OBJECT2D::const_iterator hole = intersectionList.begin(); - hole != intersectionList.end(); - ++hole ) + hole != intersectionList.end(); ++hole ) { - const COBJECT2D *hole2d = static_cast(*hole); + const COBJECT2D* hole2d = static_cast( *hole ); //if( object2d_A->Intersects( hole2d->GetBBox() ) ) - //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) ) - object2d_B->push_back( hole2d ); + //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) ) + object2d_B->push_back( hole2d ); } } } @@ -381,11 +366,11 @@ void C3D_RENDER_RAYTRACING::createItemsFromContainer( const CBVHCONTAINER2D *aCo CONST_LIST_OBJECT2D intersectionList; m_antioutlineBoard2dObjects->GetListObjectsIntersects( - object2d_A->GetBBox(), intersectionList ); + object2d_A->GetBBox(), intersectionList ); if( !intersectionList.empty() ) { - for( const COBJECT2D *obj : intersectionList ) + for( const COBJECT2D* obj : intersectionList ) { object2d_B->push_back( obj ); } @@ -394,30 +379,27 @@ void C3D_RENDER_RAYTRACING::createItemsFromContainer( const CBVHCONTAINER2D *aCo const MAP_CONTAINER_2D& mapLayers = m_boardAdapter.GetMapLayers(); - if( m_boardAdapter.GetFlag( FL_SUBTRACT_MASK_FROM_SILK ) && - m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) && - ( ( ( aLayer_id == B_SilkS ) && - ( mapLayers.find( B_Mask ) != mapLayers.end() ) ) || - ( ( aLayer_id == F_SilkS ) && - ( mapLayers.find( F_Mask ) != mapLayers.end() ) ) ) ) + if( m_boardAdapter.GetFlag( FL_SUBTRACT_MASK_FROM_SILK ) + && m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) + && ( ( ( aLayer_id == B_SilkS ) && ( mapLayers.find( B_Mask ) != mapLayers.end() ) ) + || ( ( aLayer_id == F_SilkS ) + && ( mapLayers.find( F_Mask ) != mapLayers.end() ) ) ) ) { const PCB_LAYER_ID layerMask_id = ( aLayer_id == B_SilkS ) ? B_Mask : F_Mask; - const CBVHCONTAINER2D *containerMaskLayer2d = + const CBVHCONTAINER2D* containerMaskLayer2d = static_cast( mapLayers.at( layerMask_id ) ); CONST_LIST_OBJECT2D intersectionList; - if( containerMaskLayer2d ) // can be null if B_Mask or F_Mask is not shown - containerMaskLayer2d->GetListObjectsIntersects( object2d_A->GetBBox(), - intersectionList ); + if( containerMaskLayer2d ) // can be null if B_Mask or F_Mask is not shown + containerMaskLayer2d->GetListObjectsIntersects( + object2d_A->GetBBox(), intersectionList ); if( !intersectionList.empty() ) { - for( CONST_LIST_OBJECT2D::const_iterator objOnLayer = - intersectionList.begin(); - objOnLayer != intersectionList.end(); - ++objOnLayer ) + for( CONST_LIST_OBJECT2D::const_iterator objOnLayer = intersectionList.begin(); + objOnLayer != intersectionList.end(); ++objOnLayer ) { const COBJECT2D* obj2d = static_cast( *objOnLayer ); @@ -432,27 +414,24 @@ void C3D_RENDER_RAYTRACING::createItemsFromContainer( const CBVHCONTAINER2D *aCo object2d_B = CSGITEM_EMPTY; } - if( (object2d_B == CSGITEM_EMPTY) && - (object2d_C == CSGITEM_FULL) ) + if( ( object2d_B == CSGITEM_EMPTY ) && ( object2d_C == CSGITEM_FULL ) ) { - CLAYERITEM *objPtr = new CLAYERITEM( object2d_A, - m_boardAdapter.GetLayerBottomZpos3DU( aLayer_id ) - aLayerZOffset, - m_boardAdapter.GetLayerTopZpos3DU( aLayer_id ) + aLayerZOffset ); + CLAYERITEM* objPtr = new CLAYERITEM( object2d_A, + m_boardAdapter.GetLayerBottomZpos3DU( aLayer_id ) - aLayerZOffset, + m_boardAdapter.GetLayerTopZpos3DU( aLayer_id ) + aLayerZOffset ); objPtr->SetMaterial( aMaterialLayer ); objPtr->SetColor( ConvertSRGBToLinear( aLayerColor ) ); m_object_container.Add( objPtr ); } else { - CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( object2d_A, - object2d_B, - object2d_C, - object2d_A->GetBoardItem() ); + CITEMLAYERCSG2D* itemCSG2d = new CITEMLAYERCSG2D( + object2d_A, object2d_B, object2d_C, object2d_A->GetBoardItem() ); m_containerWithObjectsToDelete.Add( itemCSG2d ); - CLAYERITEM *objPtr = new CLAYERITEM( itemCSG2d, - m_boardAdapter.GetLayerBottomZpos3DU( aLayer_id ) - aLayerZOffset, - m_boardAdapter.GetLayerTopZpos3DU( aLayer_id ) + aLayerZOffset ); + CLAYERITEM* objPtr = new CLAYERITEM( itemCSG2d, + m_boardAdapter.GetLayerBottomZpos3DU( aLayer_id ) - aLayerZOffset, + m_boardAdapter.GetLayerTopZpos3DU( aLayer_id ) + aLayerZOffset ); objPtr->SetMaterial( aMaterialLayer ); objPtr->SetColor( ConvertSRGBToLinear( aLayerColor ) ); @@ -462,11 +441,12 @@ void C3D_RENDER_RAYTRACING::createItemsFromContainer( const CBVHCONTAINER2D *aCo } } + extern void buildBoardBoundingBoxPoly( const BOARD* aBoard, SHAPE_POLY_SET& aOutline ); -void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter, - REPORTER* aWarningReporter, - bool aOnlyLoadCopperAndShapes ) + +void C3D_RENDER_RAYTRACING::Reload( + REPORTER* aStatusReporter, REPORTER* aWarningReporter, bool aOnlyLoadCopperAndShapes ) { m_reloadRequested = false; @@ -499,7 +479,7 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter, delete m_outlineBoard2dObjects; delete m_antioutlineBoard2dObjects; - m_outlineBoard2dObjects = new CCONTAINER2D; + m_outlineBoard2dObjects = new CCONTAINER2D; m_antioutlineBoard2dObjects = new CBVHCONTAINER2D; if( !aOnlyLoadCopperAndShapes ) @@ -512,9 +492,8 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter, if( m_boardAdapter.GetStats_Nr_Vias() ) divFactor = m_boardAdapter.GetStats_Med_Via_Hole_Diameter3DU() * 18.0f; - else - if( m_boardAdapter.GetStats_Nr_Holes() ) - divFactor = m_boardAdapter.GetStats_Med_Hole_Diameter3DU() * 8.0f; + else if( m_boardAdapter.GetStats_Nr_Holes() ) + divFactor = m_boardAdapter.GetStats_Med_Hole_Diameter3DU() * 8.0f; SHAPE_POLY_SET boardPolyCopy = m_boardAdapter.GetBoardPoly(); @@ -527,13 +506,11 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter, antiboardPoly.BooleanSubtract( boardPolyCopy, SHAPE_POLY_SET::PM_FAST ); antiboardPoly.Fracture( SHAPE_POLY_SET::PM_FAST ); - for( int iOutlinePolyIdx = 0; iOutlinePolyIdx < antiboardPoly.OutlineCount(); iOutlinePolyIdx++ ) + for( int iOutlinePolyIdx = 0; iOutlinePolyIdx < antiboardPoly.OutlineCount(); + iOutlinePolyIdx++ ) { - Convert_path_polygon_to_polygon_blocks_and_dummy_blocks( - antiboardPoly, - *m_antioutlineBoard2dObjects, - m_boardAdapter.BiuTo3Dunits(), - -1.0f, + Convert_path_polygon_to_polygon_blocks_and_dummy_blocks( antiboardPoly, + *m_antioutlineBoard2dObjects, m_boardAdapter.BiuTo3Dunits(), -1.0f, *dynamic_cast( m_boardAdapter.GetBoard() ), iOutlinePolyIdx ); } @@ -544,46 +521,41 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter, for( int iOutlinePolyIdx = 0; iOutlinePolyIdx < outlineCount; iOutlinePolyIdx++ ) { - Convert_path_polygon_to_polygon_blocks_and_dummy_blocks( - boardPolyCopy, - *m_outlineBoard2dObjects, - m_boardAdapter.BiuTo3Dunits(), - divFactor, + Convert_path_polygon_to_polygon_blocks_and_dummy_blocks( boardPolyCopy, + *m_outlineBoard2dObjects, m_boardAdapter.BiuTo3Dunits(), divFactor, *dynamic_cast( m_boardAdapter.GetBoard() ), iOutlinePolyIdx ); } if( m_boardAdapter.GetFlag( FL_SHOW_BOARD_BODY ) ) { - const LIST_OBJECT2D &listObjects = m_outlineBoard2dObjects->GetList(); + const LIST_OBJECT2D& listObjects = m_outlineBoard2dObjects->GetList(); for( LIST_OBJECT2D::const_iterator object2d_iterator = listObjects.begin(); - object2d_iterator != listObjects.end(); - ++object2d_iterator ) + object2d_iterator != listObjects.end(); ++object2d_iterator ) { - const COBJECT2D *object2d_A = static_cast(*object2d_iterator); + const COBJECT2D* object2d_A = + static_cast( *object2d_iterator ); - std::vector *object2d_B = new std::vector(); + std::vector* object2d_B = new std::vector(); // Check if there are any THT that intersects this outline object part if( !m_boardAdapter.GetThroughHole_Outer().GetList().empty() ) { - CONST_LIST_OBJECT2D intersectionList; m_boardAdapter.GetThroughHole_Outer().GetListObjectsIntersects( - object2d_A->GetBBox(), - intersectionList ); + object2d_A->GetBBox(), intersectionList ); if( !intersectionList.empty() ) { - for( CONST_LIST_OBJECT2D::const_iterator hole = intersectionList.begin(); - hole != intersectionList.end(); - ++hole ) + for( CONST_LIST_OBJECT2D::const_iterator hole = + intersectionList.begin(); + hole != intersectionList.end(); ++hole ) { - const COBJECT2D *hole2d = static_cast(*hole); + const COBJECT2D* hole2d = static_cast( *hole ); if( object2d_A->Intersects( hole2d->GetBBox() ) ) - //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) ) + //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) ) object2d_B->push_back( hole2d ); } } @@ -594,12 +566,11 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter, CONST_LIST_OBJECT2D intersectionList; m_antioutlineBoard2dObjects->GetListObjectsIntersects( - object2d_A->GetBBox(), - intersectionList ); + object2d_A->GetBBox(), intersectionList ); if( !intersectionList.empty() ) { - for( const COBJECT2D *obj : intersectionList ) + for( const COBJECT2D* obj : intersectionList ) { object2d_B->push_back( obj ); } @@ -614,59 +585,56 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter, if( object2d_B == CSGITEM_EMPTY ) { - CLAYERITEM *objPtr = new CLAYERITEM( object2d_A, - m_boardAdapter.GetLayerBottomZpos3DU( F_Cu ), - m_boardAdapter.GetLayerBottomZpos3DU( B_Cu ) ); + CLAYERITEM* objPtr = new CLAYERITEM( object2d_A, + m_boardAdapter.GetLayerBottomZpos3DU( F_Cu ), + m_boardAdapter.GetLayerBottomZpos3DU( B_Cu ) ); objPtr->SetMaterial( &m_materials.m_EpoxyBoard ); - objPtr->SetColor( ConvertSRGBToLinear( (SFVEC3F)m_boardAdapter.m_BoardBodyColor ) ); + objPtr->SetColor( + ConvertSRGBToLinear( (SFVEC3F) m_boardAdapter.m_BoardBodyColor ) ); m_object_container.Add( objPtr ); } else { - CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( - object2d_A, - object2d_B, - CSGITEM_FULL, - (const BOARD_ITEM &)*m_boardAdapter.GetBoard() ); + CITEMLAYERCSG2D* itemCSG2d = new CITEMLAYERCSG2D( object2d_A, object2d_B, + CSGITEM_FULL, (const BOARD_ITEM&) *m_boardAdapter.GetBoard() ); m_containerWithObjectsToDelete.Add( itemCSG2d ); - CLAYERITEM *objPtr = new CLAYERITEM( itemCSG2d, - m_boardAdapter.GetLayerBottomZpos3DU( F_Cu ), - m_boardAdapter.GetLayerBottomZpos3DU( B_Cu ) ); + CLAYERITEM* objPtr = new CLAYERITEM( itemCSG2d, + m_boardAdapter.GetLayerBottomZpos3DU( F_Cu ), + m_boardAdapter.GetLayerBottomZpos3DU( B_Cu ) ); objPtr->SetMaterial( &m_materials.m_EpoxyBoard ); - objPtr->SetColor( ConvertSRGBToLinear( (SFVEC3F)m_boardAdapter.m_BoardBodyColor ) ); + objPtr->SetColor( + ConvertSRGBToLinear( (SFVEC3F) m_boardAdapter.m_BoardBodyColor ) ); m_object_container.Add( objPtr ); - } } // Add cylinders of the board body to container - // Note: This is actually a workarround for the holes in the board. + // Note: This is actually a workaround for the holes in the board. // The issue is because if a hole is in a border of a divided polygon ( ex - // a polygon or dummyblock) it will cut also the render of the hole. + // a polygon or dummy block) it will cut also the render of the hole. // So this will add a full hole. // In fact, that is not need if the hole have copper. // ///////////////////////////////////////////////////////////////////////// if( !m_boardAdapter.GetThroughHole_Outer().GetList().empty() ) { - const LIST_OBJECT2D &holeList = m_boardAdapter.GetThroughHole_Outer().GetList(); + const LIST_OBJECT2D& holeList = m_boardAdapter.GetThroughHole_Outer().GetList(); for( LIST_OBJECT2D::const_iterator hole = holeList.begin(); - hole != holeList.end(); - ++hole ) + hole != holeList.end(); ++hole ) { - const COBJECT2D *hole2d = static_cast(*hole); + const COBJECT2D* hole2d = static_cast( *hole ); if( !m_antioutlineBoard2dObjects->GetList().empty() ) { CONST_LIST_OBJECT2D intersectionList; m_antioutlineBoard2dObjects->GetListObjectsIntersects( - hole2d->GetBBox(), intersectionList ); + hole2d->GetBBox(), intersectionList ); if( !intersectionList.empty() ) { @@ -682,14 +650,14 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter, { const float radius = hole2d->GetBBox().GetExtent().x * 0.5f * 0.999f; - CVCYLINDER *objPtr = new CVCYLINDER( - hole2d->GetCentroid(), - NextFloatDown( m_boardAdapter.GetLayerBottomZpos3DU( F_Cu ) ), - NextFloatUp( m_boardAdapter.GetLayerBottomZpos3DU( B_Cu ) ), - radius ); + CVCYLINDER* objPtr = new CVCYLINDER( hole2d->GetCentroid(), + NextFloatDown( m_boardAdapter.GetLayerBottomZpos3DU( F_Cu ) ), + NextFloatUp( m_boardAdapter.GetLayerBottomZpos3DU( B_Cu ) ), + radius ); objPtr->SetMaterial( &m_materials.m_EpoxyBoard ); - objPtr->SetColor( ConvertSRGBToLinear( (SFVEC3F)m_boardAdapter.m_BoardBodyColor ) ); + objPtr->SetColor( ConvertSRGBToLinear( + (SFVEC3F) m_boardAdapter.m_BoardBodyColor ) ); m_object_container.Add( objPtr ); } @@ -711,99 +679,98 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter, // ///////////////////////////////////////////////////////////////////////// for( MAP_CONTAINER_2D::const_iterator ii = m_boardAdapter.GetMapLayers().begin(); - ii != m_boardAdapter.GetMapLayers().end(); - ++ii ) + ii != m_boardAdapter.GetMapLayers().end(); ++ii ) { - PCB_LAYER_ID layer_id = static_cast(ii->first); + PCB_LAYER_ID layer_id = static_cast( ii->first ); if( aOnlyLoadCopperAndShapes && !IsCopperLayer( layer_id ) ) continue; // Mask layers are not processed here because they are a special case - if( (layer_id == B_Mask) || (layer_id == F_Mask) ) + if( ( layer_id == B_Mask ) || ( layer_id == F_Mask ) ) continue; - CMATERIAL *materialLayer = &m_materials.m_SilkS; - SFVEC3F layerColor = SFVEC3F( 0.0f, 0.0f, 0.0f ); + CMATERIAL* materialLayer = &m_materials.m_SilkS; + SFVEC3F layerColor = SFVEC3F( 0.0f, 0.0f, 0.0f ); switch( layer_id ) { - case B_Adhes: - case F_Adhes: + case B_Adhes: + case F_Adhes: break; - case B_Paste: - case F_Paste: - materialLayer = &m_materials.m_Paste; + case B_Paste: + case F_Paste: + materialLayer = &m_materials.m_Paste; - if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) ) - layerColor = m_boardAdapter.m_SolderPasteColor; + if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) ) + layerColor = m_boardAdapter.m_SolderPasteColor; + else + layerColor = m_boardAdapter.GetLayerColor( layer_id ); + break; + + case B_SilkS: + materialLayer = &m_materials.m_SilkS; + + if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) ) + layerColor = m_boardAdapter.m_SilkScreenColorBot; + else + layerColor = m_boardAdapter.GetLayerColor( layer_id ); + break; + case F_SilkS: + materialLayer = &m_materials.m_SilkS; + + if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) ) + layerColor = m_boardAdapter.m_SilkScreenColorTop; + else + layerColor = m_boardAdapter.GetLayerColor( layer_id ); + break; + + case Dwgs_User: + case Cmts_User: + case Eco1_User: + case Eco2_User: + case Edge_Cuts: + case Margin: + break; + + case B_CrtYd: + case F_CrtYd: + break; + + case B_Fab: + case F_Fab: + break; + + default: + if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) ) + { + if( m_boardAdapter.GetFlag( FL_RENDER_PLATED_PADS_AS_PLATED ) ) + layerColor = SFVEC3F( 184.0f / 255.0f, 115.0f / 255.0f, 50.0f / 255.0f ); else - layerColor = m_boardAdapter.GetLayerColor( layer_id ); - break; + layerColor = m_boardAdapter.m_CopperColor; + } + else + layerColor = m_boardAdapter.GetLayerColor( layer_id ); - case B_SilkS: - materialLayer = &m_materials.m_SilkS; - - if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) ) - layerColor = m_boardAdapter.m_SilkScreenColorBot; - else - layerColor = m_boardAdapter.GetLayerColor( layer_id ); - break; - case F_SilkS: - materialLayer = &m_materials.m_SilkS; - - if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) ) - layerColor = m_boardAdapter.m_SilkScreenColorTop; - else - layerColor = m_boardAdapter.GetLayerColor( layer_id ); - break; - - case Dwgs_User: - case Cmts_User: - case Eco1_User: - case Eco2_User: - case Edge_Cuts: - case Margin: - break; - - case B_CrtYd: - case F_CrtYd: - break; - - case B_Fab: - case F_Fab: - break; - - default: - if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) ) - { - if( m_boardAdapter.GetFlag( FL_RENDER_PLATED_PADS_AS_PLATED ) ) - layerColor = SFVEC3F( 184.0f / 255.0f, 115.0f / 255.0f, 50.0f / 255.0f ); - else - layerColor = m_boardAdapter.m_CopperColor; - } - else - layerColor = m_boardAdapter.GetLayerColor( layer_id ); - - materialLayer = &m_materials.m_NonPlatedCopper; + materialLayer = &m_materials.m_NonPlatedCopper; break; } - const CBVHCONTAINER2D* container2d = static_cast(ii->second); + const CBVHCONTAINER2D* container2d = static_cast( ii->second ); createItemsFromContainer( container2d, layer_id, materialLayer, layerColor, 0.0f ); - }// for each layer on map + } // for each layer on map // Create plated copper - if( m_boardAdapter.GetFlag( FL_RENDER_PLATED_PADS_AS_PLATED ) && - m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) ) + if( m_boardAdapter.GetFlag( FL_RENDER_PLATED_PADS_AS_PLATED ) + && m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) ) { createItemsFromContainer( m_boardAdapter.GetPlatedPads_Front(), F_Cu, &m_materials.m_Copper, - m_boardAdapter.m_CopperColor, +m_boardAdapter.GetCopperThickness3DU() * 0.1f ); + m_boardAdapter.m_CopperColor, +m_boardAdapter.GetCopperThickness3DU() * 0.1f ); createItemsFromContainer( m_boardAdapter.GetPlatedPads_Back(), B_Cu, &m_materials.m_Copper, - m_boardAdapter.m_CopperColor, -m_boardAdapter.GetCopperThickness3DU() * 0.1f ); + m_boardAdapter.m_CopperColor, -m_boardAdapter.GetCopperThickness3DU() * 0.1f ); } if( !aOnlyLoadCopperAndShapes ) @@ -814,19 +781,18 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter, // We will check for all objects in the outline if it intersects any object // in the layer container and also any hole. // ///////////////////////////////////////////////////////////////////////// - if( m_boardAdapter.GetFlag( FL_SOLDERMASK ) && - (m_outlineBoard2dObjects->GetList().size() >= 1) ) + if( m_boardAdapter.GetFlag( FL_SOLDERMASK ) + && ( m_outlineBoard2dObjects->GetList().size() >= 1 ) ) { - const CMATERIAL *materialLayer = &m_materials.m_SolderMask; + const CMATERIAL* materialLayer = &m_materials.m_SolderMask; for( MAP_CONTAINER_2D::const_iterator ii = m_boardAdapter.GetMapLayers().begin(); - ii != m_boardAdapter.GetMapLayers().end(); - ++ii ) + ii != m_boardAdapter.GetMapLayers().end(); ++ii ) { - PCB_LAYER_ID layer_id = static_cast(ii->first); + PCB_LAYER_ID layer_id = static_cast( ii->first ); - const CBVHCONTAINER2D *containerLayer2d = - static_cast(ii->second); + const CBVHCONTAINER2D* containerLayer2d = + static_cast( ii->second ); // Only get the Solder mask layers if( !( layer_id == B_Mask || layer_id == F_Mask ) ) @@ -847,15 +813,15 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter, const float zLayerMax = m_boardAdapter.GetLayerTopZpos3DU( layer_id ); // Get the outline board objects - const LIST_OBJECT2D &listObjects = m_outlineBoard2dObjects->GetList(); + const LIST_OBJECT2D& listObjects = m_outlineBoard2dObjects->GetList(); for( LIST_OBJECT2D::const_iterator object2d_iterator = listObjects.begin(); - object2d_iterator != listObjects.end(); - ++object2d_iterator ) + object2d_iterator != listObjects.end(); ++object2d_iterator ) { - const COBJECT2D *object2d_A = static_cast(*object2d_iterator); + const COBJECT2D* object2d_A = + static_cast( *object2d_iterator ); - std::vector *object2d_B = new std::vector(); + std::vector* object2d_B = new std::vector(); // Check if there are any THT that intersects this outline object part if( !m_boardAdapter.GetThroughHole_Outer().GetList().empty() ) @@ -864,44 +830,42 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter, CONST_LIST_OBJECT2D intersectionList; m_boardAdapter.GetThroughHole_Outer().GetListObjectsIntersects( - object2d_A->GetBBox(), - intersectionList ); + object2d_A->GetBBox(), intersectionList ); if( !intersectionList.empty() ) { - for( CONST_LIST_OBJECT2D::const_iterator hole = intersectionList.begin(); - hole != intersectionList.end(); - ++hole ) + for( CONST_LIST_OBJECT2D::const_iterator hole = + intersectionList.begin(); + hole != intersectionList.end(); ++hole ) { - const COBJECT2D *hole2d = static_cast(*hole); + const COBJECT2D* hole2d = static_cast( *hole ); if( object2d_A->Intersects( hole2d->GetBBox() ) ) - //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) ) + //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) ) object2d_B->push_back( hole2d ); } } } // Check if there are any objects in the layer to subtract with the - // corrent object + // current object if( !containerLayer2d->GetList().empty() ) { CONST_LIST_OBJECT2D intersectionList; - containerLayer2d->GetListObjectsIntersects( object2d_A->GetBBox(), - intersectionList ); + containerLayer2d->GetListObjectsIntersects( + object2d_A->GetBBox(), intersectionList ); if( !intersectionList.empty() ) { for( CONST_LIST_OBJECT2D::const_iterator obj = intersectionList.begin(); - obj != intersectionList.end(); - ++obj ) + obj != intersectionList.end(); ++obj ) { - const COBJECT2D *obj2d = static_cast(*obj); + const COBJECT2D* obj2d = static_cast( *obj ); //if( object2d_A->Intersects( obj2d->GetBBox() ) ) //if( object2d_A->GetBBox().Intersects( obj2d->GetBBox() ) ) - object2d_B->push_back( obj2d ); + object2d_B->push_back( obj2d ); } } } @@ -914,36 +878,30 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter, if( object2d_B == CSGITEM_EMPTY ) { - #if 0 +#if 0 create_3d_object_from( m_object_container, object2d_A, zLayerMin, zLayerMax, materialLayer, layerColor ); - #else - CLAYERITEM *objPtr = new CLAYERITEM( object2d_A, - zLayerMin, - zLayerMax ); +#else + CLAYERITEM* objPtr = new CLAYERITEM( object2d_A, zLayerMin, zLayerMax ); objPtr->SetMaterial( materialLayer ); objPtr->SetColor( ConvertSRGBToLinear( layerColor ) ); m_object_container.Add( objPtr ); - #endif +#endif } else { - CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( object2d_A, - object2d_B, - CSGITEM_FULL, - object2d_A->GetBoardItem() ); + CITEMLAYERCSG2D* itemCSG2d = new CITEMLAYERCSG2D( + object2d_A, object2d_B, CSGITEM_FULL, object2d_A->GetBoardItem() ); m_containerWithObjectsToDelete.Add( itemCSG2d ); - CLAYERITEM *objPtr = new CLAYERITEM( itemCSG2d, - zLayerMin, - zLayerMax ); + CLAYERITEM* objPtr = new CLAYERITEM( itemCSG2d, zLayerMin, zLayerMax ); objPtr->SetMaterial( materialLayer ); objPtr->SetColor( ConvertSRGBToLinear( layerColor ) ); @@ -957,7 +915,7 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter, } #ifdef PRINT_STATISTICS_3D_VIEWER - unsigned stats_endConvertTime = GetRunningMicroSecs(); + unsigned stats_endConvertTime = GetRunningMicroSecs(); unsigned stats_startLoad3DmodelsTime = stats_endConvertTime; #endif @@ -966,7 +924,6 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter, load_3D_models( m_object_container, aOnlyLoadCopperAndShapes ); - #ifdef PRINT_STATISTICS_3D_VIEWER unsigned stats_endLoad3DmodelsTime = GetRunningMicroSecs(); #endif @@ -992,58 +949,50 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter, const SFVEC3F centerBBox = containerBBox.GetCenter(); // Floor triangles - const float minZ = glm::min( containerBBox.Min().z, - boardBBox.Min().z ); + const float minZ = glm::min( containerBBox.Min().z, boardBBox.Min().z ); - const SFVEC3F v1 = SFVEC3F( -RANGE_SCALE_3D * 4.0f, - -RANGE_SCALE_3D * 4.0f, - minZ ) + - SFVEC3F( centerBBox.x, - centerBBox.y, - 0.0f ); + const SFVEC3F v1 = + SFVEC3F( -RANGE_SCALE_3D * 4.0f, -RANGE_SCALE_3D * 4.0f, minZ ) + + SFVEC3F( centerBBox.x, centerBBox.y, 0.0f ); - const SFVEC3F v3 = SFVEC3F( +RANGE_SCALE_3D * 4.0f, - +RANGE_SCALE_3D * 4.0f, - minZ ) + - SFVEC3F( centerBBox.x, - centerBBox.y, - 0.0f ); + const SFVEC3F v3 = + SFVEC3F( +RANGE_SCALE_3D * 4.0f, +RANGE_SCALE_3D * 4.0f, minZ ) + + SFVEC3F( centerBBox.x, centerBBox.y, 0.0f ); const SFVEC3F v2 = SFVEC3F( v1.x, v3.y, v1.z ); const SFVEC3F v4 = SFVEC3F( v3.x, v1.y, v1.z ); - SFVEC3F backgroundColor = - ConvertSRGBToLinear( static_cast( m_boardAdapter.m_BgColorTop ) ); + SFVEC3F backgroundColor = ConvertSRGBToLinear( + static_cast( m_boardAdapter.m_BgColorTop ) ); - CTRIANGLE *newTriangle1 = new CTRIANGLE( v1, v2, v3 ); - CTRIANGLE *newTriangle2 = new CTRIANGLE( v3, v4, v1 ); + CTRIANGLE* newTriangle1 = new CTRIANGLE( v1, v2, v3 ); + CTRIANGLE* newTriangle2 = new CTRIANGLE( v3, v4, v1 ); m_object_container.Add( newTriangle1 ); m_object_container.Add( newTriangle2 ); - newTriangle1->SetMaterial( (const CMATERIAL *)&m_materials.m_Floor ); - newTriangle2->SetMaterial( (const CMATERIAL *)&m_materials.m_Floor ); + newTriangle1->SetMaterial( (const CMATERIAL*) &m_materials.m_Floor ); + newTriangle2->SetMaterial( (const CMATERIAL*) &m_materials.m_Floor ); newTriangle1->SetColor( backgroundColor ); newTriangle2->SetColor( backgroundColor ); // Ceiling triangles - const float maxZ = glm::max( containerBBox.Max().z, - boardBBox.Max().z ); + const float maxZ = glm::max( containerBBox.Max().z, boardBBox.Max().z ); const SFVEC3F v5 = SFVEC3F( v1.x, v1.y, maxZ ); const SFVEC3F v6 = SFVEC3F( v2.x, v2.y, maxZ ); const SFVEC3F v7 = SFVEC3F( v3.x, v3.y, maxZ ); const SFVEC3F v8 = SFVEC3F( v4.x, v4.y, maxZ ); - CTRIANGLE *newTriangle3 = new CTRIANGLE( v7, v6, v5 ); - CTRIANGLE *newTriangle4 = new CTRIANGLE( v5, v8, v7 ); + CTRIANGLE* newTriangle3 = new CTRIANGLE( v7, v6, v5 ); + CTRIANGLE* newTriangle4 = new CTRIANGLE( v5, v8, v7 ); m_object_container.Add( newTriangle3 ); m_object_container.Add( newTriangle4 ); - newTriangle3->SetMaterial( (const CMATERIAL *)&m_materials.m_Floor ); - newTriangle4->SetMaterial( (const CMATERIAL *)&m_materials.m_Floor ); + newTriangle3->SetMaterial( (const CMATERIAL*) &m_materials.m_Floor ); + newTriangle4->SetMaterial( (const CMATERIAL*) &m_materials.m_Floor ); newTriangle3->SetColor( backgroundColor ); newTriangle4->SetColor( backgroundColor ); @@ -1051,17 +1000,16 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter, } } - // Init initial lights // ///////////////////////////////////////////////////////////////////////// m_lights.Clear(); - auto IsColorZero = [] ( const SFVEC3F& aSource ) - { - return ( ( aSource.r < ( 1.0f / 255.0f ) ) && - ( aSource.g < ( 1.0f / 255.0f ) ) && - ( aSource.b < ( 1.0f / 255.0f ) ) ); - }; + auto IsColorZero = + []( const SFVEC3F& aSource ) + { + return ( ( aSource.r < ( 1.0f / 255.0f ) ) && ( aSource.g < ( 1.0f / 255.0f ) ) + && ( aSource.b < ( 1.0f / 255.0f ) ) ); + }; m_camera_light = new CDIRECTIONALLIGHT( SFVEC3F( 0.0f, 0.0f, 0.0f ), m_boardAdapter.m_raytrace_lightColorCamera ); @@ -1073,11 +1021,13 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter, const SFVEC3F& boardCenter = m_boardAdapter.GetBBox3DU().GetCenter(); if( !IsColorZero( m_boardAdapter.m_raytrace_lightColorTop ) ) - m_lights.Add( new CPOINTLIGHT( SFVEC3F( boardCenter.x, boardCenter.y, +RANGE_SCALE_3D * 2.0f ), + m_lights.Add( new CPOINTLIGHT( SFVEC3F( boardCenter.x, boardCenter.y, + +RANGE_SCALE_3D * 2.0f ), m_boardAdapter.m_raytrace_lightColorTop ) ); if( !IsColorZero( m_boardAdapter.m_raytrace_lightColorBottom ) ) - m_lights.Add( new CPOINTLIGHT( SFVEC3F( boardCenter.x, boardCenter.y, -RANGE_SCALE_3D * 2.0f ), + m_lights.Add( new CPOINTLIGHT( SFVEC3F( boardCenter.x, boardCenter.y, + -RANGE_SCALE_3D * 2.0f ), m_boardAdapter.m_raytrace_lightColorBottom ) ); wxASSERT( m_boardAdapter.m_raytrace_lightColor.size() @@ -1089,9 +1039,9 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter, { const SFVEC2F sc = m_boardAdapter.m_raytrace_lightSphericalCoords[i]; - m_lights.Add( new CDIRECTIONALLIGHT( SphericalToCartesian( glm::pi() * sc.x, - glm::pi() * sc.y ), - m_boardAdapter.m_raytrace_lightColor[i] ) ); + m_lights.Add( new CDIRECTIONALLIGHT( + SphericalToCartesian( glm::pi() * sc.x, glm::pi() * sc.y ), + m_boardAdapter.m_raytrace_lightColor[i] ) ); } } } @@ -1109,126 +1059,112 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter, if( aStatusReporter ) { // Calculation time in seconds - const double calculation_time = (double)( GetRunningMicroSecs() - - stats_startReloadTime ) / 1e6; + const double calculation_time = + (double) ( GetRunningMicroSecs() - stats_startReloadTime ) / 1e6; aStatusReporter->Report( wxString::Format( _( "Reload time %.3f s" ), calculation_time ) ); } } - -// Based on draw3DViaHole from -// 3d_draw_helper_functions.cpp void C3D_RENDER_RAYTRACING::insert3DViaHole( const VIA* aVia ) { - PCB_LAYER_ID top_layer, bottom_layer; - int radiusBUI = (aVia->GetDrillValue() / 2); + PCB_LAYER_ID top_layer, bottom_layer; + int radiusBUI = ( aVia->GetDrillValue() / 2 ); aVia->LayerPair( &top_layer, &bottom_layer ); - float topZ = m_boardAdapter.GetLayerBottomZpos3DU( top_layer ) + - m_boardAdapter.GetCopperThickness3DU(); + float topZ = m_boardAdapter.GetLayerBottomZpos3DU( top_layer ) + + m_boardAdapter.GetCopperThickness3DU(); - float botZ = m_boardAdapter.GetLayerBottomZpos3DU( bottom_layer ) - - m_boardAdapter.GetCopperThickness3DU(); + float botZ = m_boardAdapter.GetLayerBottomZpos3DU( bottom_layer ) + - m_boardAdapter.GetCopperThickness3DU(); const SFVEC2F center = SFVEC2F( aVia->GetStart().x * m_boardAdapter.BiuTo3Dunits(), - -aVia->GetStart().y * m_boardAdapter.BiuTo3Dunits() ); + -aVia->GetStart().y * m_boardAdapter.BiuTo3Dunits() ); - CRING2D *ring = new CRING2D( center, - radiusBUI * m_boardAdapter.BiuTo3Dunits(), - ( radiusBUI + m_boardAdapter.GetHolePlatingThicknessBIU() ) * - m_boardAdapter.BiuTo3Dunits(), - *aVia ); + CRING2D* ring = new CRING2D( center, radiusBUI * m_boardAdapter.BiuTo3Dunits(), + ( radiusBUI + m_boardAdapter.GetHolePlatingThicknessBIU() ) + * m_boardAdapter.BiuTo3Dunits(), + *aVia ); m_containerWithObjectsToDelete.Add( ring ); - - CLAYERITEM *objPtr = new CLAYERITEM( ring, topZ, botZ ); + CLAYERITEM* objPtr = new CLAYERITEM( ring, topZ, botZ ); objPtr->SetMaterial( &m_materials.m_Copper ); if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) ) - objPtr->SetColor( ConvertSRGBToLinear( (SFVEC3F)m_boardAdapter.m_CopperColor ) ); + objPtr->SetColor( ConvertSRGBToLinear( (SFVEC3F) m_boardAdapter.m_CopperColor ) ); else - objPtr->SetColor( ConvertSRGBToLinear( - m_boardAdapter.GetItemColor( LAYER_VIAS + static_cast( aVia->GetViaType() ) ) ) ); + objPtr->SetColor( ConvertSRGBToLinear( m_boardAdapter.GetItemColor( + LAYER_VIAS + static_cast( aVia->GetViaType() ) ) ) ); m_object_container.Add( objPtr ); } -// Based on draw3DPadHole from -// 3d_draw_helper_functions.cpp void C3D_RENDER_RAYTRACING::insert3DPadHole( const PAD* aPad ) { - const COBJECT2D *object2d_A = NULL; + const COBJECT2D* object2d_A = NULL; SFVEC3F objColor; if( m_boardAdapter.GetFlag( FL_USE_REALISTIC_MODE ) ) - objColor = (SFVEC3F)m_boardAdapter.m_CopperColor; + objColor = (SFVEC3F) m_boardAdapter.m_CopperColor; else objColor = m_boardAdapter.GetItemColor( LAYER_PADS_TH ); - const wxSize drillsize = aPad->GetDrillSize(); - const bool hasHole = drillsize.x && drillsize.y; + const wxSize drillsize = aPad->GetDrillSize(); + const bool hasHole = drillsize.x && drillsize.y; if( !hasHole ) return; CONST_LIST_OBJECT2D antiOutlineIntersectionList; - const float topZ = m_boardAdapter.GetLayerBottomZpos3DU( F_Cu ) + - m_boardAdapter.GetCopperThickness3DU() * 0.99f; + const float topZ = m_boardAdapter.GetLayerBottomZpos3DU( F_Cu ) + + m_boardAdapter.GetCopperThickness3DU() * 0.99f; - const float botZ = m_boardAdapter.GetLayerBottomZpos3DU( B_Cu ) - - m_boardAdapter.GetCopperThickness3DU() * 0.99f; + const float botZ = m_boardAdapter.GetLayerBottomZpos3DU( B_Cu ) + - m_boardAdapter.GetCopperThickness3DU() * 0.99f; - if( drillsize.x == drillsize.y ) // usual round hole + if( drillsize.x == drillsize.y ) // usual round hole { SFVEC2F center = SFVEC2F( aPad->GetPosition().x * m_boardAdapter.BiuTo3Dunits(), - -aPad->GetPosition().y * m_boardAdapter.BiuTo3Dunits() ); + -aPad->GetPosition().y * m_boardAdapter.BiuTo3Dunits() ); int innerRadius = drillsize.x / 2; int outerRadius = innerRadius + m_boardAdapter.GetHolePlatingThicknessBIU(); - CRING2D *ring = new CRING2D( center, - innerRadius * m_boardAdapter.BiuTo3Dunits(), - outerRadius * m_boardAdapter.BiuTo3Dunits(), - *aPad ); + CRING2D* ring = new CRING2D( center, innerRadius * m_boardAdapter.BiuTo3Dunits(), + outerRadius * m_boardAdapter.BiuTo3Dunits(), *aPad ); m_containerWithObjectsToDelete.Add( ring ); object2d_A = ring; // If the object (ring) is intersected by an antioutline board, - // it will use instease a CSG of two circles. + // it will use instead a CSG of two circles. if( object2d_A && !m_antioutlineBoard2dObjects->GetList().empty() ) { m_antioutlineBoard2dObjects->GetListObjectsIntersects( - object2d_A->GetBBox(), - antiOutlineIntersectionList ); + object2d_A->GetBBox(), antiOutlineIntersectionList ); } if( !antiOutlineIntersectionList.empty() ) { - CFILLEDCIRCLE2D *innerCircle = new CFILLEDCIRCLE2D( center, - innerRadius * m_boardAdapter.BiuTo3Dunits(), - *aPad ); + CFILLEDCIRCLE2D* innerCircle = new CFILLEDCIRCLE2D( + center, innerRadius * m_boardAdapter.BiuTo3Dunits(), *aPad ); - CFILLEDCIRCLE2D *outterCircle = new CFILLEDCIRCLE2D( center, - outerRadius * m_boardAdapter.BiuTo3Dunits(), - *aPad ); - std::vector *object2d_B = new std::vector(); + CFILLEDCIRCLE2D* outterCircle = new CFILLEDCIRCLE2D( + center, outerRadius * m_boardAdapter.BiuTo3Dunits(), *aPad ); + std::vector* object2d_B = new std::vector(); object2d_B->push_back( innerCircle ); - CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( outterCircle, - object2d_B, - CSGITEM_FULL, - *aPad ); + CITEMLAYERCSG2D* itemCSG2d = + new CITEMLAYERCSG2D( outterCircle, object2d_B, CSGITEM_FULL, *aPad ); m_containerWithObjectsToDelete.Add( itemCSG2d ); m_containerWithObjectsToDelete.Add( innerCircle ); @@ -1237,52 +1173,49 @@ void C3D_RENDER_RAYTRACING::insert3DPadHole( const PAD* aPad ) object2d_A = itemCSG2d; } } - else // Oblong hole + else // Oblong hole { wxPoint ends_offset; int width; - if( drillsize.x > drillsize.y ) // Horizontal oval + if( drillsize.x > drillsize.y ) // Horizontal oval { ends_offset.x = ( drillsize.x - drillsize.y ) / 2; - width = drillsize.y; + width = drillsize.y; } - else // Vertical oval + else // Vertical oval { ends_offset.y = ( drillsize.y - drillsize.x ) / 2; - width = drillsize.x; + width = drillsize.x; } RotatePoint( &ends_offset, aPad->GetOrientation() ); - wxPoint start = aPad->GetPosition() + ends_offset; - wxPoint end = aPad->GetPosition() - ends_offset; + wxPoint start = aPad->GetPosition() + ends_offset; + wxPoint end = aPad->GetPosition() - ends_offset; - CROUNDSEGMENT2D *innerSeg = new CROUNDSEGMENT2D( - SFVEC2F( start.x * m_boardAdapter.BiuTo3Dunits(), + CROUNDSEGMENT2D* innerSeg = + new CROUNDSEGMENT2D( SFVEC2F( start.x * m_boardAdapter.BiuTo3Dunits(), -start.y * m_boardAdapter.BiuTo3Dunits() ), - SFVEC2F( end.x * m_boardAdapter.BiuTo3Dunits(), - -end.y * m_boardAdapter.BiuTo3Dunits() ), - width * m_boardAdapter.BiuTo3Dunits(), - *aPad ); + SFVEC2F( end.x * m_boardAdapter.BiuTo3Dunits(), + -end.y * m_boardAdapter.BiuTo3Dunits() ), + width * m_boardAdapter.BiuTo3Dunits(), *aPad ); - CROUNDSEGMENT2D *outerSeg = new CROUNDSEGMENT2D( - SFVEC2F( start.x * m_boardAdapter.BiuTo3Dunits(), + CROUNDSEGMENT2D* outerSeg = + new CROUNDSEGMENT2D( SFVEC2F( start.x * m_boardAdapter.BiuTo3Dunits(), -start.y * m_boardAdapter.BiuTo3Dunits() ), - SFVEC2F( end.x * m_boardAdapter.BiuTo3Dunits(), - -end.y * m_boardAdapter.BiuTo3Dunits() ), - ( width + m_boardAdapter.GetHolePlatingThicknessBIU() * 2 ) * m_boardAdapter.BiuTo3Dunits(), - *aPad ); + SFVEC2F( end.x * m_boardAdapter.BiuTo3Dunits(), + -end.y * m_boardAdapter.BiuTo3Dunits() ), + ( width + m_boardAdapter.GetHolePlatingThicknessBIU() * 2 ) + * m_boardAdapter.BiuTo3Dunits(), + *aPad ); // NOTE: the round segment width is the "diameter", so we double the thickness - - std::vector *object2d_B = new std::vector(); + std::vector* object2d_B = new std::vector(); object2d_B->push_back( innerSeg ); - CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( outerSeg, - object2d_B, - CSGITEM_FULL, - *aPad ); + CITEMLAYERCSG2D* itemCSG2d = + new CITEMLAYERCSG2D( outerSeg, object2d_B, CSGITEM_FULL, *aPad ); m_containerWithObjectsToDelete.Add( itemCSG2d ); m_containerWithObjectsToDelete.Add( innerSeg ); @@ -1293,36 +1226,32 @@ void C3D_RENDER_RAYTRACING::insert3DPadHole( const PAD* aPad ) if( object2d_A && !m_antioutlineBoard2dObjects->GetList().empty() ) { - m_antioutlineBoard2dObjects->GetListObjectsIntersects( - object2d_A->GetBBox(), - antiOutlineIntersectionList ); + m_antioutlineBoard2dObjects->GetListObjectsIntersects( object2d_A->GetBBox(), + antiOutlineIntersectionList ); } } - if( object2d_A ) { - std::vector *object2d_B = new std::vector(); + std::vector* object2d_B = new std::vector(); // Check if there are any other THT that intersects this hole // It will use the non inflated holes if( !m_boardAdapter.GetThroughHole_Inner().GetList().empty() ) { - CONST_LIST_OBJECT2D intersectionList; - m_boardAdapter.GetThroughHole_Inner().GetListObjectsIntersects( object2d_A->GetBBox(), - intersectionList ); + m_boardAdapter.GetThroughHole_Inner().GetListObjectsIntersects( + object2d_A->GetBBox(), intersectionList ); if( !intersectionList.empty() ) { for( CONST_LIST_OBJECT2D::const_iterator hole = intersectionList.begin(); - hole != intersectionList.end(); - ++hole ) + hole != intersectionList.end(); ++hole ) { - const COBJECT2D *hole2d = static_cast(*hole); + const COBJECT2D* hole2d = static_cast( *hole ); if( object2d_A->Intersects( hole2d->GetBBox() ) ) - //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) ) + //if( object2d_A->GetBBox().Intersects( hole2d->GetBBox() ) ) object2d_B->push_back( hole2d ); } } @@ -1330,7 +1259,7 @@ void C3D_RENDER_RAYTRACING::insert3DPadHole( const PAD* aPad ) if( !antiOutlineIntersectionList.empty() ) { - for( const COBJECT2D *obj : antiOutlineIntersectionList ) + for( const COBJECT2D* obj : antiOutlineIntersectionList ) { object2d_B->push_back( obj ); } @@ -1344,7 +1273,7 @@ void C3D_RENDER_RAYTRACING::insert3DPadHole( const PAD* aPad ) if( object2d_B == CSGITEM_EMPTY ) { - CLAYERITEM *objPtr = new CLAYERITEM( object2d_A, topZ, botZ ); + CLAYERITEM* objPtr = new CLAYERITEM( object2d_A, topZ, botZ ); objPtr->SetMaterial( &m_materials.m_Copper ); objPtr->SetColor( ConvertSRGBToLinear( objColor ) ); @@ -1352,14 +1281,12 @@ void C3D_RENDER_RAYTRACING::insert3DPadHole( const PAD* aPad ) } else { - CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( object2d_A, - object2d_B, - CSGITEM_FULL, - (const BOARD_ITEM &)*aPad ); + CITEMLAYERCSG2D* itemCSG2d = new CITEMLAYERCSG2D( + object2d_A, object2d_B, CSGITEM_FULL, (const BOARD_ITEM&) *aPad ); m_containerWithObjectsToDelete.Add( itemCSG2d ); - CLAYERITEM *objPtr = new CLAYERITEM( itemCSG2d, topZ, botZ ); + CLAYERITEM* objPtr = new CLAYERITEM( itemCSG2d, topZ, botZ ); objPtr->SetMaterial( &m_materials.m_Copper ); objPtr->SetColor( ConvertSRGBToLinear( objColor ) ); @@ -1380,7 +1307,7 @@ void C3D_RENDER_RAYTRACING::add_3D_vias_and_pads_to_container() { if( track->Type() == PCB_VIA_T ) { - const VIA *via = static_cast(track); + const VIA* via = static_cast( track ); insert3DViaHole( via ); } } @@ -1389,21 +1316,24 @@ void C3D_RENDER_RAYTRACING::add_3D_vias_and_pads_to_container() for( FOOTPRINT* footprint : m_boardAdapter.GetBoard()->Footprints() ) { for( PAD* pad : footprint->Pads() ) - if( pad->GetAttribute () != PAD_ATTRIB_NPTH ) + { + if( pad->GetAttribute() != PAD_ATTRIB_NPTH ) { insert3DPadHole( pad ); } + } } } -void C3D_RENDER_RAYTRACING::load_3D_models( CCONTAINER &aDstContainer, bool aSkipMaterialInformation ) +void C3D_RENDER_RAYTRACING::load_3D_models( CCONTAINER& aDstContainer, + bool aSkipMaterialInformation ) { // Go for all footprints for( FOOTPRINT* fp : m_boardAdapter.GetBoard()->Footprints() ) { if( !fp->Models().empty() - && m_boardAdapter.ShouldFPBeDisplayed( (FOOTPRINT_ATTR_T) fp->GetAttributes() ) ) + && m_boardAdapter.ShouldFPBeDisplayed( (FOOTPRINT_ATTR_T) fp->GetAttributes() ) ) { double zpos = m_boardAdapter.GetModulesZcoord3DIU( fp->IsFlipped() ); @@ -1411,18 +1341,18 @@ void C3D_RENDER_RAYTRACING::load_3D_models( CCONTAINER &aDstContainer, bool aSki glm::mat4 fpMatrix = glm::mat4( 1.0f ); - fpMatrix = glm::translate( fpMatrix, SFVEC3F( pos.x * m_boardAdapter.BiuTo3Dunits(), - -pos.y * m_boardAdapter.BiuTo3Dunits(), - zpos ) ); + fpMatrix = glm::translate( fpMatrix, + SFVEC3F( pos.x * m_boardAdapter.BiuTo3Dunits(), + -pos.y * m_boardAdapter.BiuTo3Dunits(), + zpos ) ); if( fp->GetOrientation() ) { fpMatrix = glm::rotate( fpMatrix, - ( (float)(fp->GetOrientation() / 10.0f) / 180.0f ) * glm::pi(), - SFVEC3F( 0.0f, 0.0f, 1.0f ) ); + ( (float) ( fp->GetOrientation() / 10.0f ) / 180.0f ) * glm::pi(), + SFVEC3F( 0.0f, 0.0f, 1.0f ) ); } - if( fp->IsFlipped() ) { fpMatrix = glm::rotate( fpMatrix, glm::pi(), SFVEC3F( 0.0f, 1.0f, 0.0f ) ); @@ -1430,28 +1360,27 @@ void C3D_RENDER_RAYTRACING::load_3D_models( CCONTAINER &aDstContainer, bool aSki fpMatrix = glm::rotate( fpMatrix, glm::pi(), SFVEC3F( 0.0f, 0.0f, 1.0f ) ); } - const double modelunit_to_3d_units_factor = m_boardAdapter.BiuTo3Dunits() * - UNITS3D_TO_UNITSPCB; + const double modelunit_to_3d_units_factor = + m_boardAdapter.BiuTo3Dunits() * UNITS3D_TO_UNITSPCB; - fpMatrix = glm::scale( fpMatrix, - SFVEC3F( modelunit_to_3d_units_factor, - modelunit_to_3d_units_factor, - modelunit_to_3d_units_factor ) ); + fpMatrix = glm::scale( + fpMatrix, SFVEC3F( modelunit_to_3d_units_factor, modelunit_to_3d_units_factor, + modelunit_to_3d_units_factor ) ); BOARD_ITEM* boardItem = dynamic_cast( fp ); // Get the list of model files for this model S3D_CACHE* cacheMgr = m_boardAdapter.Get3DCacheManager(); - auto sM = fp->Models().begin(); - auto eM = fp->Models().end(); + auto sM = fp->Models().begin(); + auto eM = fp->Models().end(); while( sM != eM ) { - if( ( static_cast( sM->m_Opacity ) > FLT_EPSILON ) && - ( sM->m_Show && !sM->m_Filename.empty() ) ) + if( ( static_cast( sM->m_Opacity ) > FLT_EPSILON ) + && ( sM->m_Show && !sM->m_Filename.empty() ) ) { // get it from cache - const S3DMODEL *modelPtr = cacheMgr->GetModel( sM->m_Filename ); + const S3DMODEL* modelPtr = cacheMgr->GetModel( sM->m_Filename ); // only add it if the return is not NULL if( modelPtr ) @@ -1459,36 +1388,25 @@ void C3D_RENDER_RAYTRACING::load_3D_models( CCONTAINER &aDstContainer, bool aSki glm::mat4 modelMatrix = fpMatrix; modelMatrix = glm::translate( modelMatrix, - SFVEC3F( sM->m_Offset.x, - sM->m_Offset.y, - sM->m_Offset.z ) ); + SFVEC3F( sM->m_Offset.x, sM->m_Offset.y, sM->m_Offset.z ) ); modelMatrix = glm::rotate( modelMatrix, - (float)-( sM->m_Rotation.z / 180.0f ) * - glm::pi(), - SFVEC3F( 0.0f, 0.0f, 1.0f ) ); + (float) -( sM->m_Rotation.z / 180.0f ) * glm::pi(), + SFVEC3F( 0.0f, 0.0f, 1.0f ) ); modelMatrix = glm::rotate( modelMatrix, - (float)-( sM->m_Rotation.y / 180.0f ) * - glm::pi(), - SFVEC3F( 0.0f, 1.0f, 0.0f ) ); + (float) -( sM->m_Rotation.y / 180.0f ) * glm::pi(), + SFVEC3F( 0.0f, 1.0f, 0.0f ) ); modelMatrix = glm::rotate( modelMatrix, - (float)-( sM->m_Rotation.x / 180.0f ) * - glm::pi(), - SFVEC3F( 1.0f, 0.0f, 0.0f ) ); + (float) -( sM->m_Rotation.x / 180.0f ) * glm::pi(), + SFVEC3F( 1.0f, 0.0f, 0.0f ) ); modelMatrix = glm::scale( modelMatrix, - SFVEC3F( sM->m_Scale.x, - sM->m_Scale.y, - sM->m_Scale.z ) ); + SFVEC3F( sM->m_Scale.x, sM->m_Scale.y, sM->m_Scale.z ) ); - add_3D_models( aDstContainer, - modelPtr, - modelMatrix, - (float)sM->m_Opacity, - aSkipMaterialInformation, - boardItem ); + add_3D_models( aDstContainer, modelPtr, modelMatrix, (float) sM->m_Opacity, + aSkipMaterialInformation, boardItem ); } } @@ -1498,9 +1416,10 @@ void C3D_RENDER_RAYTRACING::load_3D_models( CCONTAINER &aDstContainer, bool aSki } } -MODEL_MATERIALS *C3D_RENDER_RAYTRACING::get_3D_model_material( const S3DMODEL *a3DModel ) + +MODEL_MATERIALS* C3D_RENDER_RAYTRACING::get_3D_model_material( const S3DMODEL* a3DModel ) { - MODEL_MATERIALS *materialVector; + MODEL_MATERIALS* materialVector; // Try find if the materials already exists in the map list if( m_model_materials.find( a3DModel ) != m_model_materials.end() ) @@ -1514,77 +1433,82 @@ MODEL_MATERIALS *C3D_RENDER_RAYTRACING::get_3D_model_material( const S3DMODEL *a // this model. m_model_materials[a3DModel] = MODEL_MATERIALS(); - materialVector = &m_model_materials[a3DModel]; + materialVector = &m_model_materials[a3DModel]; materialVector->resize( a3DModel->m_MaterialsSize ); - for( unsigned int imat = 0; - imat < a3DModel->m_MaterialsSize; - ++imat ) + for( unsigned int imat = 0; imat < a3DModel->m_MaterialsSize; ++imat ) { if( m_boardAdapter.MaterialModeGet() == MATERIAL_MODE::NORMAL ) { - const SMATERIAL &material = a3DModel->m_Materials[imat]; + const SMATERIAL& material = a3DModel->m_Materials[imat]; // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiJtaW4oc3FydCh4LTAuMzUpKjAuNDAtMC4wNSwxLjApIiwiY29sb3IiOiIjMDAwMDAwIn0seyJ0eXBlIjoxMDAwLCJ3aW5kb3ciOlsiMC4wNzA3NzM2NzMyMzY1OTAxMiIsIjEuNTY5NTcxNjI5MjI1NDY5OCIsIi0wLjI3NDYzNTMyMTc1OTkyOTMiLCIwLjY0NzcwMTg4MTkyNTUzNjIiXSwic2l6ZSI6WzY0NCwzOTRdfV0- float reflectionFactor = 0.0f; - if( (material.m_Shininess - 0.35f) > FLT_EPSILON ) + if( ( material.m_Shininess - 0.35f ) > FLT_EPSILON ) { - reflectionFactor = glm::clamp( glm::sqrt( (material.m_Shininess - 0.35f) ) * - 0.40f - 0.05f, - 0.0f, - 0.5f ); + reflectionFactor = glm::clamp( + glm::sqrt( ( material.m_Shininess - 0.35f ) ) * 0.40f - 0.05f, 0.0f, + 0.5f ); } - CBLINN_PHONG_MATERIAL &blinnMaterial = (*materialVector)[imat]; + CBLINN_PHONG_MATERIAL& blinnMaterial = ( *materialVector )[imat]; - blinnMaterial = CBLINN_PHONG_MATERIAL( - ConvertSRGBToLinear( material.m_Ambient ), - ConvertSRGBToLinear( material.m_Emissive ), - ConvertSRGBToLinear( material.m_Specular ), - material.m_Shininess * 180.0f, - material.m_Transparency, - reflectionFactor ); + blinnMaterial = CBLINN_PHONG_MATERIAL( ConvertSRGBToLinear( material.m_Ambient ), + ConvertSRGBToLinear( material.m_Emissive ), + ConvertSRGBToLinear( material.m_Specular ), material.m_Shininess * 180.0f, + material.m_Transparency, reflectionFactor ); if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_PROCEDURAL_TEXTURES ) ) { // Guess material type and apply a normal perturbator - - if( ( RGBtoGray( material.m_Diffuse ) < 0.3f ) && - ( material.m_Shininess < 0.36f ) && - ( material.m_Transparency == 0.0f ) && - ( ( glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) < 0.15f ) && - ( glm::abs( material.m_Diffuse.b - material.m_Diffuse.g ) < 0.15f ) && - ( glm::abs( material.m_Diffuse.r - material.m_Diffuse.b ) < 0.15f ) ) ) + if( ( RGBtoGray( material.m_Diffuse ) < 0.3f ) + && ( material.m_Shininess < 0.36f ) + && ( material.m_Transparency == 0.0f ) + && ( ( glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) < 0.15f ) + && ( glm::abs( material.m_Diffuse.b - material.m_Diffuse.g ) + < 0.15f ) + && ( glm::abs( material.m_Diffuse.r - material.m_Diffuse.b ) + < 0.15f ) ) ) { // This may be a black plastic.. blinnMaterial.SetNormalPerturbator( &m_plastic_normal_perturbator ); } else { - if( ( RGBtoGray( material.m_Diffuse ) > 0.3f ) && - ( material.m_Shininess < 0.30f ) && - ( material.m_Transparency == 0.0f ) && - ( ( glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) > 0.25f ) || - ( glm::abs( material.m_Diffuse.b - material.m_Diffuse.g ) > 0.25f ) || - ( glm::abs( material.m_Diffuse.r - material.m_Diffuse.b ) > 0.25f ) ) ) + if( ( RGBtoGray( material.m_Diffuse ) > 0.3f ) + && ( material.m_Shininess < 0.30f ) + && ( material.m_Transparency == 0.0f ) + && ( ( glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) + > 0.25f ) + || ( glm::abs( material.m_Diffuse.b - material.m_Diffuse.g ) + > 0.25f ) + || ( glm::abs( material.m_Diffuse.r - material.m_Diffuse.b ) + > 0.25f ) ) ) { // This may be a color plastic ... - blinnMaterial.SetNormalPerturbator( &m_plastic_shine_normal_perturbator ); + blinnMaterial.SetNormalPerturbator( + &m_plastic_shine_normal_perturbator ); } else { - if( ( RGBtoGray( material.m_Diffuse ) > 0.6f ) && - ( material.m_Shininess > 0.35f ) && - ( material.m_Transparency == 0.0f ) && - ( ( glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) < 0.40f ) && - ( glm::abs( material.m_Diffuse.b - material.m_Diffuse.g ) < 0.40f ) && - ( glm::abs( material.m_Diffuse.r - material.m_Diffuse.b ) < 0.40f ) ) ) + if( ( RGBtoGray( material.m_Diffuse ) > 0.6f ) + && ( material.m_Shininess > 0.35f ) + && ( material.m_Transparency == 0.0f ) + && ( ( glm::abs( material.m_Diffuse.r - material.m_Diffuse.g ) + < 0.40f ) + && ( glm::abs( material.m_Diffuse.b + - material.m_Diffuse.g ) + < 0.40f ) + && ( glm::abs( material.m_Diffuse.r + - material.m_Diffuse.b ) + < 0.40f ) ) ) { // This may be a brushed metal - blinnMaterial.SetNormalPerturbator( &m_brushed_metal_normal_perturbator ); + blinnMaterial.SetNormalPerturbator( + &m_brushed_metal_normal_perturbator ); } } } @@ -1592,12 +1516,8 @@ MODEL_MATERIALS *C3D_RENDER_RAYTRACING::get_3D_model_material( const S3DMODEL *a } else { - (*materialVector)[imat] = CBLINN_PHONG_MATERIAL( SFVEC3F( 0.2f ), - SFVEC3F( 0.0f ), - SFVEC3F( 0.0f ), - 0.0f, - 0.0f, - 0.0f ); + ( *materialVector )[imat] = CBLINN_PHONG_MATERIAL( + SFVEC3F( 0.2f ), SFVEC3F( 0.0f ), SFVEC3F( 0.0f ), 0.0f, 0.0f, 0.0f ); } } } @@ -1605,11 +1525,12 @@ MODEL_MATERIALS *C3D_RENDER_RAYTRACING::get_3D_model_material( const S3DMODEL *a return materialVector; } -void C3D_RENDER_RAYTRACING::add_3D_models( CCONTAINER &aDstContainer, const S3DMODEL *a3DModel, - const glm::mat4 &aModelMatrix, float aFPOpacity, - bool aSkipMaterialInformation, BOARD_ITEM *aBoardItem ) -{ +void C3D_RENDER_RAYTRACING::add_3D_models( CCONTAINER& aDstContainer, const S3DMODEL* a3DModel, + const glm::mat4& aModelMatrix, float aFPOpacity, + bool aSkipMaterialInformation, + BOARD_ITEM* aBoardItem ) +{ // Validate a3DModel pointers wxASSERT( a3DModel != NULL ); @@ -1628,11 +1549,10 @@ void C3D_RENDER_RAYTRACING::add_3D_models( CCONTAINER &aDstContainer, const S3DM aFPOpacity = 1.0f; } - if( (a3DModel->m_Materials != NULL) && (a3DModel->m_Meshes != NULL) && - (a3DModel->m_MaterialsSize > 0) && (a3DModel->m_MeshesSize > 0) ) + if( ( a3DModel->m_Materials != NULL ) && ( a3DModel->m_Meshes != NULL ) + && ( a3DModel->m_MaterialsSize > 0 ) && ( a3DModel->m_MeshesSize > 0 ) ) { - - MODEL_MATERIALS *materialVector = NULL; + MODEL_MATERIALS* materialVector = NULL; if( !aSkipMaterialInformation ) { @@ -1641,42 +1561,36 @@ void C3D_RENDER_RAYTRACING::add_3D_models( CCONTAINER &aDstContainer, const S3DM const glm::mat3 normalMatrix = glm::transpose( glm::inverse( glm::mat3( aModelMatrix ) ) ); - for( unsigned int mesh_i = 0; - mesh_i < a3DModel->m_MeshesSize; - ++mesh_i ) + for( unsigned int mesh_i = 0; mesh_i < a3DModel->m_MeshesSize; ++mesh_i ) { - const SMESH &mesh = a3DModel->m_Meshes[mesh_i]; + const SMESH& mesh = a3DModel->m_Meshes[mesh_i]; // Validate the mesh pointers wxASSERT( mesh.m_Positions != NULL ); wxASSERT( mesh.m_FaceIdx != NULL ); wxASSERT( mesh.m_Normals != NULL ); wxASSERT( mesh.m_FaceIdxSize > 0 ); - wxASSERT( (mesh.m_FaceIdxSize % 3) == 0 ); + wxASSERT( ( mesh.m_FaceIdxSize % 3 ) == 0 ); - if( (mesh.m_Positions != NULL) && - (mesh.m_Normals != NULL) && - (mesh.m_FaceIdx != NULL) && - (mesh.m_FaceIdxSize > 0) && - (mesh.m_VertexSize > 0) && - ((mesh.m_FaceIdxSize % 3) == 0) && - (mesh.m_MaterialIdx < a3DModel->m_MaterialsSize) ) + if( ( mesh.m_Positions != NULL ) && ( mesh.m_Normals != NULL ) + && ( mesh.m_FaceIdx != NULL ) && ( mesh.m_FaceIdxSize > 0 ) + && ( mesh.m_VertexSize > 0 ) && ( ( mesh.m_FaceIdxSize % 3 ) == 0 ) + && ( mesh.m_MaterialIdx < a3DModel->m_MaterialsSize ) ) { - float fpTransparency; - const CBLINN_PHONG_MATERIAL *blinn_material; + float fpTransparency; + const CBLINN_PHONG_MATERIAL* blinn_material; if( !aSkipMaterialInformation ) { - blinn_material = &(*materialVector)[mesh.m_MaterialIdx]; + blinn_material = &( *materialVector )[mesh.m_MaterialIdx]; - fpTransparency = 1.0f - (( 1.0f - blinn_material->GetTransparency() ) * aFPOpacity ); + fpTransparency = + 1.0f - ( ( 1.0f - blinn_material->GetTransparency() ) * aFPOpacity ); } // Add all face triangles - for( unsigned int faceIdx = 0; - faceIdx < mesh.m_FaceIdxSize; - faceIdx += 3 ) + for( unsigned int faceIdx = 0; faceIdx < mesh.m_FaceIdxSize; faceIdx += 3 ) { const unsigned int idx0 = mesh.m_FaceIdx[faceIdx + 0]; const unsigned int idx1 = mesh.m_FaceIdx[faceIdx + 1]; @@ -1686,29 +1600,27 @@ void C3D_RENDER_RAYTRACING::add_3D_models( CCONTAINER &aDstContainer, const S3DM wxASSERT( idx1 < mesh.m_VertexSize ); wxASSERT( idx2 < mesh.m_VertexSize ); - if( ( idx0 < mesh.m_VertexSize ) && - ( idx1 < mesh.m_VertexSize ) && - ( idx2 < mesh.m_VertexSize ) ) + if( ( idx0 < mesh.m_VertexSize ) && ( idx1 < mesh.m_VertexSize ) + && ( idx2 < mesh.m_VertexSize ) ) { - const SFVEC3F &v0 = mesh.m_Positions[idx0]; - const SFVEC3F &v1 = mesh.m_Positions[idx1]; - const SFVEC3F &v2 = mesh.m_Positions[idx2]; + const SFVEC3F& v0 = mesh.m_Positions[idx0]; + const SFVEC3F& v1 = mesh.m_Positions[idx1]; + const SFVEC3F& v2 = mesh.m_Positions[idx2]; - const SFVEC3F &n0 = mesh.m_Normals[idx0]; - const SFVEC3F &n1 = mesh.m_Normals[idx1]; - const SFVEC3F &n2 = mesh.m_Normals[idx2]; + const SFVEC3F& n0 = mesh.m_Normals[idx0]; + const SFVEC3F& n1 = mesh.m_Normals[idx1]; + const SFVEC3F& n2 = mesh.m_Normals[idx2]; // Transform vertex with the model matrix - const SFVEC3F vt0 = SFVEC3F( aModelMatrix * glm::vec4( v0, 1.0f) ); - const SFVEC3F vt1 = SFVEC3F( aModelMatrix * glm::vec4( v1, 1.0f) ); - const SFVEC3F vt2 = SFVEC3F( aModelMatrix * glm::vec4( v2, 1.0f) ); + const SFVEC3F vt0 = SFVEC3F( aModelMatrix * glm::vec4( v0, 1.0f ) ); + const SFVEC3F vt1 = SFVEC3F( aModelMatrix * glm::vec4( v1, 1.0f ) ); + const SFVEC3F vt2 = SFVEC3F( aModelMatrix * glm::vec4( v2, 1.0f ) ); const SFVEC3F nt0 = glm::normalize( SFVEC3F( normalMatrix * n0 ) ); const SFVEC3F nt1 = glm::normalize( SFVEC3F( normalMatrix * n1 ) ); const SFVEC3F nt2 = glm::normalize( SFVEC3F( normalMatrix * n2 ) ); - CTRIANGLE *newTriangle = new CTRIANGLE( vt0, vt2, vt1, - nt0, nt2, nt1 ); + CTRIANGLE* newTriangle = new CTRIANGLE( vt0, vt2, vt1, nt0, nt2, nt1 ); newTriangle->SetBoardItem( aBoardItem ); @@ -1722,23 +1634,29 @@ void C3D_RENDER_RAYTRACING::add_3D_models( CCONTAINER &aDstContainer, const S3DM if( mesh.m_Color == NULL ) { const SFVEC3F diffuseColor = - a3DModel->m_Materials[mesh.m_MaterialIdx].m_Diffuse; + a3DModel->m_Materials[mesh.m_MaterialIdx].m_Diffuse; if( m_boardAdapter.MaterialModeGet() == MATERIAL_MODE::CAD_MODE ) - newTriangle->SetColor( ConvertSRGBToLinear( MaterialDiffuseToColorCAD( diffuseColor ) ) ); + newTriangle->SetColor( ConvertSRGBToLinear( + MaterialDiffuseToColorCAD( diffuseColor ) ) ); else newTriangle->SetColor( ConvertSRGBToLinear( diffuseColor ) ); } else { if( m_boardAdapter.MaterialModeGet() == MATERIAL_MODE::CAD_MODE ) - newTriangle->SetColor( ConvertSRGBToLinear( MaterialDiffuseToColorCAD( mesh.m_Color[idx0] ) ), - ConvertSRGBToLinear( MaterialDiffuseToColorCAD( mesh.m_Color[idx1] ) ), - ConvertSRGBToLinear( MaterialDiffuseToColorCAD( mesh.m_Color[idx2] ) ) ); + newTriangle->SetColor( + ConvertSRGBToLinear( MaterialDiffuseToColorCAD( + mesh.m_Color[idx0] ) ), + ConvertSRGBToLinear( MaterialDiffuseToColorCAD( + mesh.m_Color[idx1] ) ), + ConvertSRGBToLinear( MaterialDiffuseToColorCAD( + mesh.m_Color[idx2] ) ) ); else - newTriangle->SetColor( ConvertSRGBToLinear( mesh.m_Color[idx0] ), - ConvertSRGBToLinear( mesh.m_Color[idx1] ), - ConvertSRGBToLinear( mesh.m_Color[idx2] ) ); + newTriangle->SetColor( + ConvertSRGBToLinear( mesh.m_Color[idx0] ), + ConvertSRGBToLinear( mesh.m_Color[idx1] ), + ConvertSRGBToLinear( mesh.m_Color[idx2] ) ); } } } diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.cpp index 9ddebd0017..3743c9be39 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2020 Mario Luzeiro - * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -48,8 +48,8 @@ //#include C3D_RENDER_RAYTRACING::C3D_RENDER_RAYTRACING( BOARD_ADAPTER& aAdapter, CCAMERA& aCamera ) : - C3D_RENDER_BASE( aAdapter, aCamera ), - m_postshader_ssao( aCamera ) + C3D_RENDER_BASE( aAdapter, aCamera ), + m_postshader_ssao( aCamera ) { wxLogTrace( m_logTrace, wxT( "C3D_RENDER_RAYTRACING::C3D_RENDER_RAYTRACING" ) ); @@ -158,7 +158,6 @@ bool C3D_RENDER_RAYTRACING::Redraw( bool requestRedraw = false; // Initialize openGL if need - // ///////////////////////////////////////////////////////////////////////// if( !m_is_opengl_initialized ) { if( !initializeOpenGL() ) @@ -176,7 +175,6 @@ bool C3D_RENDER_RAYTRACING::Redraw( std::unique_ptr busy = CreateBusyIndicator(); // Reload board if it was requested - // ///////////////////////////////////////////////////////////////////////// if( m_reloadRequested ) { if( aStatusReporter ) @@ -189,7 +187,6 @@ bool C3D_RENDER_RAYTRACING::Redraw( // Recalculate constants if windows size was changed - // ///////////////////////////////////////////////////////////////////////// if( m_windowSize != m_oldWindowsSize ) { m_oldWindowsSize = m_windowSize; @@ -201,7 +198,6 @@ bool C3D_RENDER_RAYTRACING::Redraw( // Clear buffers - // ///////////////////////////////////////////////////////////////////////// glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); glClearDepth( 1.0f ); glClearStencil( 0x00 ); @@ -224,7 +220,6 @@ bool C3D_RENDER_RAYTRACING::Redraw( m_rt_render_state = RT_RENDER_STATE_MAX; // Set to an invalid state, // so it will restart again latter - // This will only render if need, otherwise it will redraw the PBO on the screen again if( aIsMoving || was_camera_changed ) { @@ -386,8 +381,8 @@ void C3D_RENDER_RAYTRACING::rt_render_tracing( GLubyte* ptrPBO , std::thread t = std::thread( [&]() { for( size_t iBlock = currentBlock.fetch_add( 1 ); - iBlock < m_blockPositions.size() && !breakLoop; - iBlock = currentBlock.fetch_add( 1 ) ) + iBlock < m_blockPositions.size() && !breakLoop; + iBlock = currentBlock.fetch_add( 1 ) ) { if( !m_blockPositionsWasProcessed[iBlock] ) { @@ -416,8 +411,8 @@ void C3D_RENDER_RAYTRACING::rt_render_tracing( GLubyte* ptrPBO , if( aStatusReporter ) aStatusReporter->Report( wxString::Format( _( "Rendering: %.0f %%" ), - (float)(m_nrBlocksRenderProgress * 100) / - (float)m_blockPositions.size() ) ); + (float)(m_nrBlocksRenderProgress * 100) / + (float)m_blockPositions.size() ) ); // Check if it finish the rendering and if should continue to a post processing // or mark it as finished @@ -430,6 +425,7 @@ void C3D_RENDER_RAYTRACING::rt_render_tracing( GLubyte* ptrPBO , } } + #ifdef USE_SRGB_SPACE // This should be removed in future when the KiCad support a greater version of @@ -437,6 +433,7 @@ void C3D_RENDER_RAYTRACING::rt_render_tracing( GLubyte* ptrPBO , #define SRGB_GAMA 2.4f + // This function implements the conversion from linear RGB to sRGB // https://github.com/g-truc/glm/blob/master/glm/gtc/color_space.inl#L12 static SFVEC3F convertLinearToSRGB( const SFVEC3F &aRGBcolor ) @@ -444,31 +441,31 @@ static SFVEC3F convertLinearToSRGB( const SFVEC3F &aRGBcolor ) const float gammaCorrection = 1.0f / SRGB_GAMA; const SFVEC3F clampedColor = glm::clamp( aRGBcolor, SFVEC3F(0.0f), SFVEC3F(1.0f) ); - return glm::mix( - glm::pow( clampedColor, SFVEC3F(gammaCorrection) ) * 1.055f - 0.055f, - clampedColor * 12.92f, - glm::lessThan( clampedColor, SFVEC3F(0.0031308f) ) ); + return glm::mix( glm::pow( clampedColor, SFVEC3F(gammaCorrection) ) * 1.055f - 0.055f, + clampedColor * 12.92f, + glm::lessThan( clampedColor, SFVEC3F(0.0031308f) ) ); } + // This function implements the conversion from sRGB to linear RGB // https://github.com/g-truc/glm/blob/master/glm/gtc/color_space.inl#L35 SFVEC3F ConvertSRGBToLinear( const SFVEC3F &aSRGBcolor ) { const float gammaCorrection = SRGB_GAMA; - return glm::mix( - glm::pow( (aSRGBcolor + SFVEC3F(0.055f)) * SFVEC3F(0.94786729857819905213270142180095f), - SFVEC3F(gammaCorrection) ), - aSRGBcolor * SFVEC3F(0.07739938080495356037151702786378f), - glm::lessThanEqual( aSRGBcolor, SFVEC3F(0.04045f) ) ); + return glm::mix( glm::pow( (aSRGBcolor + SFVEC3F(0.055f)) * + SFVEC3F(0.94786729857819905213270142180095f), + SFVEC3F(gammaCorrection) ), + aSRGBcolor * SFVEC3F(0.07739938080495356037151702786378f), + glm::lessThanEqual( aSRGBcolor, SFVEC3F(0.04045f) ) ); } #endif + void C3D_RENDER_RAYTRACING::rt_final_color( GLubyte *ptrPBO, const SFVEC3F &rgbColor, bool applyColorSpaceConversion ) { - SFVEC3F color = rgbColor; #ifdef USE_SRGB_SPACE @@ -503,11 +500,11 @@ static void HITINFO_PACKET_init( HITINFO_PACKET *aHitPacket ) } -void C3D_RENDER_RAYTRACING::rt_shades_packet(const SFVEC3F *bgColorY, - const RAY *aRayPkt, - HITINFO_PACKET *aHitPacket, - bool is_testShadow, - SFVEC3F *aOutHitColor ) +void C3D_RENDER_RAYTRACING::rt_shades_packet(const SFVEC3F *bgColorY, + const RAY *aRayPkt, + HITINFO_PACKET *aHitPacket, + bool is_testShadow, + SFVEC3F *aOutHitColor ) { for( unsigned int y = 0, i = 0; y < RAYPACKET_DIM; ++y ) { @@ -570,15 +567,14 @@ void C3D_RENDER_RAYTRACING::rt_trace_AA_packet( const SFVEC3F *aBgColorY, unsigned int nodex1y1 = 0; - if( ((x < (RAYPACKET_DIM - 1)) && - (y < (RAYPACKET_DIM - 1))) ) - nodex1y1 = aHitPck_X0Y0[ idx1y1 ].m_HitInfo.m_acc_node_info; + if( ( ( x < ( RAYPACKET_DIM - 1 ) ) && ( y < ( RAYPACKET_DIM - 1 ) ) ) ) + nodex1y1 = aHitPck_X0Y0[idx1y1].m_HitInfo.m_acc_node_info; - - if( ((nodex0y0 == nodex1y0) || (nodex1y0 == 0)) && // If all notes are equal we assume there was no change on the object hits - ((nodex0y0 == nodex0y1) || (nodex0y1 == 0)) && - ((nodex0y0 == nodex1y1) || (nodex1y1 == 0)) && - (nodex0y0 == node_AA_x0y0) ) + // If all notes are equal we assume there was no change on the object hits. + if( ( ( nodex0y0 == nodex1y0 ) || ( nodex1y0 == 0 ) ) + && ( ( nodex0y0 == nodex0y1 ) || ( nodex0y1 == 0 ) ) + && ( ( nodex0y0 == nodex1y1 ) || ( nodex1y1 == 0 ) ) + && ( nodex0y0 == node_AA_x0y0 ) ) { // Option 1 // This option will give a very good quality on reflections (slow) @@ -604,7 +600,6 @@ void C3D_RENDER_RAYTRACING::rt_trace_AA_packet( const SFVEC3F *aBgColorY, // Option 3 // Use same color - } else { @@ -640,7 +635,8 @@ void C3D_RENDER_RAYTRACING::rt_trace_AA_packet( const SFVEC3F *aBgColorY, if( hitted ) { // If we got any result, shade it - aOutHitColor[i] = shadeHit( aBgColorY[y], rayAA, hitAA, false, 0, is_testShadow ); + aOutHitColor[i] = shadeHit( aBgColorY[y], rayAA, hitAA, false, 0, + is_testShadow ); } else { @@ -649,20 +645,21 @@ void C3D_RENDER_RAYTRACING::rt_trace_AA_packet( const SFVEC3F *aBgColorY, // It was missed the 'last nodes' so, trace a ray from the beginning if( m_accelerator->Intersect( rayAA, hitAA ) ) - aOutHitColor[i] = shadeHit( aBgColorY[y], rayAA, hitAA, false, 0, is_testShadow ); + aOutHitColor[i] = shadeHit( aBgColorY[y], rayAA, hitAA, false, 0, + is_testShadow ); } } } } } + #define DISP_FACTOR 0.075f -void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO , - signed int iBlock ) + +void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO, signed int iBlock ) { // Initialize ray packets - // ///////////////////////////////////////////////////////////////////////// const SFVEC2UI &blockPos = m_blockPositions[iBlock]; const SFVEC2I blockPosI = SFVEC2I( blockPos.x + m_xoffset, blockPos.y + m_yoffset ); @@ -676,7 +673,6 @@ void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO , HITINFO_PACKET_init( hitPacket_X0Y0 ); // Calculate background gradient color - // ///////////////////////////////////////////////////////////////////////// SFVEC3F bgColor[RAYPACKET_DIM];// Store a vertical gradient color for( unsigned int y = 0; y < RAYPACKET_DIM; ++y ) @@ -688,10 +684,8 @@ void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO , } // Intersect ray packets (calculate the intersection with rays and objects) - // ///////////////////////////////////////////////////////////////////////// if( !m_accelerator->Intersect( blockPacket, hitPacket_X0Y0 ) ) { - // If block is empty then set shades and continue if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING ) ) { @@ -718,7 +712,6 @@ void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO , // If post processing is enabled, it will not reflect the final result // (as the final color will be computed on post processing) // but it is used for report progress - const bool isFinalColor = !m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING ); for( unsigned int y = 0; y < RAYPACKET_DIM; ++y ) @@ -740,11 +733,9 @@ void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO , return; } - SFVEC3F hitColor_X0Y0[RAYPACKET_RAYS_PER_PACKET]; // Shade original (0, 0) hits ("paint" the intersected objects) - // ///////////////////////////////////////////////////////////////////////// rt_shades_packet( bgColor, blockPacket.m_ray, hitPacket_X0Y0, @@ -755,9 +746,7 @@ void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO , { SFVEC3F hitColor_AA_X1Y1[RAYPACKET_RAYS_PER_PACKET]; - // Intersect one blockPosI + (0.5, 0.5) used for anti aliasing calculation - // ///////////////////////////////////////////////////////////////////////// HITINFO_PACKET hitPacket_AA_X1Y1[RAYPACKET_RAYS_PER_PACKET]; HITINFO_PACKET_init( hitPacket_AA_X1Y1 ); @@ -805,20 +794,20 @@ void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO , RAY blockRayPck_AA_X0Y1[RAYPACKET_RAYS_PER_PACKET]; RAY blockRayPck_AA_X1Y1_half[RAYPACKET_RAYS_PER_PACKET]; - RAYPACKET_InitRays_with2DDisplacement( m_camera, - (SFVEC2F)blockPosI + SFVEC2F(0.5f - DISP_FACTOR, DISP_FACTOR), - SFVEC2F(DISP_FACTOR, DISP_FACTOR), // Displacement random factor - blockRayPck_AA_X1Y0 ); + RAYPACKET_InitRays_with2DDisplacement( + m_camera, + (SFVEC2F) blockPosI + SFVEC2F( 0.5f - DISP_FACTOR, DISP_FACTOR ), + SFVEC2F( DISP_FACTOR, DISP_FACTOR ), blockRayPck_AA_X1Y0 ); - RAYPACKET_InitRays_with2DDisplacement( m_camera, - (SFVEC2F)blockPosI + SFVEC2F(DISP_FACTOR, 0.5f - DISP_FACTOR), - SFVEC2F(DISP_FACTOR, DISP_FACTOR), // Displacement random factor - blockRayPck_AA_X0Y1 ); + RAYPACKET_InitRays_with2DDisplacement( + m_camera, + (SFVEC2F) blockPosI + SFVEC2F( DISP_FACTOR, 0.5f - DISP_FACTOR ), + SFVEC2F( DISP_FACTOR, DISP_FACTOR ), blockRayPck_AA_X0Y1 ); - RAYPACKET_InitRays_with2DDisplacement( m_camera, - (SFVEC2F)blockPosI + SFVEC2F(0.25f - DISP_FACTOR, 0.25f - DISP_FACTOR), - SFVEC2F(DISP_FACTOR, DISP_FACTOR), // Displacement random factor - blockRayPck_AA_X1Y1_half ); + RAYPACKET_InitRays_with2DDisplacement( + m_camera, + (SFVEC2F) blockPosI + SFVEC2F( 0.25f - DISP_FACTOR, 0.25f - DISP_FACTOR ), + SFVEC2F( DISP_FACTOR, DISP_FACTOR ), blockRayPck_AA_X1Y1_half ); rt_trace_AA_packet( bgColor, hitPacket_X0Y0, hitPacket_AA_X1Y1, @@ -849,10 +838,7 @@ void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO , // Copy results to the next stage - // ///////////////////////////////////////////////////////////////////// - - GLubyte *ptr = &ptrPBO[ ( blockPos.x + - (blockPos.y * m_realBufferSize.x) ) * 4 ]; + GLubyte* ptr = &ptrPBO[( blockPos.x + ( blockPos.y * m_realBufferSize.x ) ) * 4]; const uint32_t ptrInc = (m_realBufferSize.x - RAYPACKET_DIM) * 4; @@ -978,6 +964,7 @@ void C3D_RENDER_RAYTRACING::rt_render_post_process_blur_finish( GLubyte *ptrPBO, std::atomic threadsFinished( 0 ); size_t parallelThreadCount = std::max( std::thread::hardware_concurrency(), 2 ); + for( size_t ii = 0; ii < parallelThreadCount; ++ii ) { std::thread t = std::thread( [&]() @@ -993,11 +980,14 @@ void C3D_RENDER_RAYTRACING::rt_render_post_process_blur_finish( GLubyte *ptrPBO, const SFVEC3F bluredShadeColor = m_postshader_ssao.Blur( SFVEC2I( x, y ) ); #ifdef USE_SRGB_SPACE - const SFVEC3F originColor = convertLinearToSRGB( m_postshader_ssao.GetColorAtNotProtected( SFVEC2I( x,y ) ) ); + const SFVEC3F originColor = convertLinearToSRGB( + m_postshader_ssao.GetColorAtNotProtected( SFVEC2I( x, y ) ) ); #else - const SFVEC3F originColor = m_postshader_ssao.GetColorAtNotProtected( SFVEC2I( x,y ) ); + const SFVEC3F originColor = + m_postshader_ssao.GetColorAtNotProtected( SFVEC2I( x, y ) ); #endif - const SFVEC3F shadedColor = m_postshader_ssao.ApplyShadeColor( SFVEC2I( x,y ), originColor, bluredShadeColor ); + const SFVEC3F shadedColor = m_postshader_ssao.ApplyShadeColor( + SFVEC2I( x, y ), originColor, bluredShadeColor ); rt_final_color( ptr, shadedColor, false ); @@ -1014,7 +1004,6 @@ void C3D_RENDER_RAYTRACING::rt_render_post_process_blur_finish( GLubyte *ptrPBO, while( threadsFinished < parallelThreadCount ) std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); - // Debug code //m_postshader_ssao.DebugBuffersOutputAsImages(); } @@ -1034,6 +1023,7 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO ) size_t parallelThreadCount = std::min( std::max( std::thread::hardware_concurrency(), 2 ), m_blockPositions.size() ); + for( size_t ii = 0; ii < parallelThreadCount; ++ii ) { std::thread t = std::thread( [&]() @@ -1068,10 +1058,12 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO ) for( unsigned int y = 0; y < RAYPACKET_DIM; ++y ) { - const float posYfactor = (float)(windowsPos.y + y * 4.0f) / (float)m_windowSize.y; + const float posYfactor = + (float) ( windowsPos.y + y * 4.0f ) / (float) m_windowSize.y; - bgColor[y] = (SFVEC3F)m_boardAdapter.m_BgColorTop * SFVEC3F( posYfactor) + - (SFVEC3F)m_boardAdapter.m_BgColorBot * ( SFVEC3F( 1.0f) - SFVEC3F( posYfactor) ); + bgColor[y] = (SFVEC3F) m_boardAdapter.m_BgColorTop * SFVEC3F( posYfactor ) + + (SFVEC3F) m_boardAdapter.m_BgColorBot + * ( SFVEC3F( 1.0f ) - SFVEC3F( posYfactor ) ); } CCOLORRGB hitColorShading[RAYPACKET_RAYS_PER_PACKET]; @@ -1099,7 +1091,6 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO ) for( unsigned int y = 0; y < (RAYPACKET_DIM - 1); ++y ) { - const SFVEC3F bgColorY = bgColor[y]; const CCOLORRGB bgColorYRGB = CCOLORRGB( bgColorY ); @@ -1127,15 +1118,12 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO ) const unsigned int iRB = ((x + 1) + RAYPACKET_DIM * (y + 1)); // !TODO: skip when there are no hits - - const CCOLORRGB &cLT = hitColorShading[ iLT ]; const CCOLORRGB &cRT = hitColorShading[ iRT ]; const CCOLORRGB &cLB = hitColorShading[ iLB ]; const CCOLORRGB &cRB = hitColorShading[ iRB ]; // Trace and shade cC - // ///////////////////////////////////////////////////////////// CCOLORRGB cC = bgColorYRGB; const SFVEC3F &oriLT = blockPacket.m_ray[ iLT ].m_Origin; @@ -1171,25 +1159,32 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO ) const unsigned int nodeRB = hitPacket[ iRB ].m_HitInfo.m_acc_node_info; if( nodeLT != 0 ) - hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo, nodeLT ); + hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo, + nodeLT ); if( ( nodeRT != 0 ) && ( nodeRT != nodeLT ) ) - hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo, nodeRT ); + hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo, + nodeRT ); if( ( nodeLB != 0 ) && ( nodeLB != nodeLT ) && ( nodeLB != nodeRT ) ) - hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo, nodeLB ); + hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo, + nodeLB ); if( ( nodeRB != 0 ) && ( nodeRB != nodeLB ) && ( nodeRB != nodeLT ) && ( nodeRB != nodeRT ) ) - hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo, nodeRB ); + hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo, + nodeRB ); if( hittedC ) - cC = CCOLORRGB( shadeHit( bgColorY, centerRay, centerHitInfo, false, 0, false ) ); + { + cC = CCOLORRGB( shadeHit( bgColorY, centerRay, centerHitInfo, + false, 0, false ) ); + } else { centerHitInfo.m_tHit = std::numeric_limits::infinity(); @@ -1278,11 +1273,11 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO ) } } else + { cLRT = cLRB_old[x]; - + } // Trace and shade cLTB - // ///////////////////////////////////////////////////////////// CCOLORRGB cLTB = bgColorYRGB; if( x == 0 ) @@ -1309,16 +1304,19 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO ) hitInfoLTB.m_HitNormal = glm::normalize( ( hitPacket[ iLT ].m_HitInfo.m_HitNormal + hitPacket[ iLB ].m_HitInfo.m_HitNormal ) * 0.5f ); - cLTB = CCOLORRGB( shadeHit( bgColorY, rayLTB, hitInfoLTB, false, 0, false ) ); + cLTB = CCOLORRGB( shadeHit( bgColorY, rayLTB, hitInfoLTB, false, + 0, false ) ); cLTB = BlendColor( cLTB, BlendColor( cLT, cLB) ); } else { - if( hitPacket[ iLT ].m_hitresult || - hitPacket[ iLB ].m_hitresult ) // If any hits + // If any hits + if( hitPacket[ iLT ].m_hitresult || hitPacket[ iLB ].m_hitresult ) { - const unsigned int nodeLT = hitPacket[ iLT ].m_HitInfo.m_acc_node_info; - const unsigned int nodeLB = hitPacket[ iLB ].m_HitInfo.m_acc_node_info; + const unsigned int nodeLT = + hitPacket[ iLT ].m_HitInfo.m_acc_node_info; + const unsigned int nodeLB = + hitPacket[ iLB ].m_HitInfo.m_acc_node_info; bool hittedLTB = false; @@ -1356,11 +1354,11 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO ) } } else + { cLTB = cRTB_old; - + } // Trace and shade cRTB - // ///////////////////////////////////////////////////////////// CCOLORRGB cRTB = bgColorYRGB; // Trace the center ray @@ -1371,8 +1369,7 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO ) HITINFO hitInfoRTB; hitInfoRTB.m_tHit = std::numeric_limits::infinity(); - if( hitPacket[ iRT ].m_hitresult && - hitPacket[ iRB ].m_hitresult && + if( hitPacket[ iRT ].m_hitresult && hitPacket[ iRB ].m_hitresult && ( hitPacket[ iRT ].m_HitInfo.pHitObject == hitPacket[ iRB ].m_HitInfo.pHitObject ) ) { @@ -1385,33 +1382,40 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO ) glm::normalize( ( hitPacket[ iRT ].m_HitInfo.m_HitNormal + hitPacket[ iRB ].m_HitInfo.m_HitNormal ) * 0.5f ); - cRTB = CCOLORRGB( shadeHit( bgColorY, rayRTB, hitInfoRTB, false, 0, false ) ); + cRTB = CCOLORRGB( shadeHit( bgColorY, rayRTB, hitInfoRTB, false, 0, + false ) ); cRTB = BlendColor( cRTB, BlendColor( cRT, cRB) ); } else { - if( hitPacket[ iRT ].m_hitresult || - hitPacket[ iRB ].m_hitresult ) // If any hits + // If any hits + if( hitPacket[ iRT ].m_hitresult || hitPacket[ iRB ].m_hitresult ) { - const unsigned int nodeRT = hitPacket[ iRT ].m_HitInfo.m_acc_node_info; - const unsigned int nodeRB = hitPacket[ iRB ].m_HitInfo.m_acc_node_info; + const unsigned int nodeRT = + hitPacket[ iRT ].m_HitInfo.m_acc_node_info; + const unsigned int nodeRB = + hitPacket[ iRB ].m_HitInfo.m_acc_node_info; bool hittedRTB = false; if( nodeRT != 0 ) - hittedRTB |= m_accelerator->Intersect( rayRTB, hitInfoRTB, nodeRT ); + hittedRTB |= m_accelerator->Intersect( rayRTB, hitInfoRTB, + nodeRT ); if( ( nodeRB != 0 ) && ( nodeRB != nodeRT ) ) - hittedRTB |= m_accelerator->Intersect( rayRTB, hitInfoRTB, nodeRB ); + hittedRTB |= m_accelerator->Intersect( rayRTB, hitInfoRTB, + nodeRB ); if( hittedRTB ) + { cRTB = CCOLORRGB( shadeHit( bgColorY, rayRTB, hitInfoRTB, false, 0, false) ); + } else { hitInfoRTB.m_tHit = std::numeric_limits::infinity(); @@ -1429,9 +1433,7 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO ) cRTB_old = cRTB; - // Trace and shade cLRB - // ///////////////////////////////////////////////////////////// CCOLORRGB cLRB = bgColorYRGB; const SFVEC3F &oriLB = blockPacket.m_ray[ iLB ].m_Origin; @@ -1440,13 +1442,12 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO ) // Trace the center ray RAY rayLRB; rayLRB.Init( ( oriLB + oriRB ) * 0.5f, - glm::normalize( ( dirLB + dirRB ) * 0.5f ) ); + glm::normalize( ( dirLB + dirRB ) * 0.5f ) ); HITINFO hitInfoLRB; hitInfoLRB.m_tHit = std::numeric_limits::infinity(); - if( hitPacket[ iLB ].m_hitresult && - hitPacket[ iRB ].m_hitresult && + if( hitPacket[ iLB ].m_hitresult && hitPacket[ iRB ].m_hitresult && ( hitPacket[ iLB ].m_HitInfo.pHitObject == hitPacket[ iRB ].m_HitInfo.pHitObject ) ) { @@ -1459,28 +1460,35 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO ) glm::normalize( ( hitPacket[ iLB ].m_HitInfo.m_HitNormal + hitPacket[ iRB ].m_HitInfo.m_HitNormal ) * 0.5f ); - cLRB = CCOLORRGB( shadeHit( bgColorY, rayLRB, hitInfoLRB, false, 0, false ) ); + cLRB = CCOLORRGB( shadeHit( bgColorY, rayLRB, hitInfoLRB, false, 0, + false ) ); cLRB = BlendColor( cLRB, BlendColor( cLB, cRB) ); } else { - if( hitPacket[ iLB ].m_hitresult || - hitPacket[ iRB ].m_hitresult ) // If any hits + // If any hits + if( hitPacket[ iLB ].m_hitresult || hitPacket[ iRB ].m_hitresult ) { - const unsigned int nodeLB = hitPacket[ iLB ].m_HitInfo.m_acc_node_info; - const unsigned int nodeRB = hitPacket[ iRB ].m_HitInfo.m_acc_node_info; + const unsigned int nodeLB = + hitPacket[ iLB ].m_HitInfo.m_acc_node_info; + const unsigned int nodeRB = + hitPacket[ iRB ].m_HitInfo.m_acc_node_info; bool hittedLRB = false; if( nodeLB != 0 ) - hittedLRB |= m_accelerator->Intersect( rayLRB, hitInfoLRB, nodeLB ); + hittedLRB |= m_accelerator->Intersect( rayLRB, hitInfoLRB, + nodeLB ); - if( ( nodeRB != 0 ) && - ( nodeRB != nodeLB ) ) - hittedLRB |= m_accelerator->Intersect( rayLRB, hitInfoLRB, nodeRB ); + if( ( nodeRB != 0 ) && ( nodeRB != nodeLB ) ) + hittedLRB |= m_accelerator->Intersect( rayLRB, hitInfoLRB, + nodeRB ); if( hittedLRB ) - cLRB = CCOLORRGB( shadeHit( bgColorY, rayLRB, hitInfoLRB, false, 0, false ) ); + { + cLRB = CCOLORRGB( shadeHit( bgColorY, rayLRB, hitInfoLRB, + false, 0, false ) ); + } else { hitInfoLRB.m_tHit = std::numeric_limits::infinity(); @@ -1498,9 +1506,7 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO ) cLRB_old[x] = cLRB; - // Trace and shade cLTC - // ///////////////////////////////////////////////////////////// CCOLORRGB cLTC = BlendColor( cLT , cC ); if( hitPacket[ iLT ].m_hitresult || hittedC ) @@ -1517,18 +1523,17 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO ) if( hittedC ) hitted = centerHitInfo.pHitObject->Intersect( rayLTC, hitInfoLTC ); - else - if( hitPacket[ iLT ].m_hitresult ) - hitted = hitPacket[ iLT ].m_HitInfo.pHitObject->Intersect( rayLTC, - hitInfoLTC ); + else if( hitPacket[ iLT ].m_hitresult ) + hitted = hitPacket[ iLT ].m_HitInfo.pHitObject->Intersect( + rayLTC, + hitInfoLTC ); if( hitted ) - cLTC = CCOLORRGB( shadeHit( bgColorY, rayLTC, hitInfoLTC, false, 0, false ) ); + cLTC = CCOLORRGB( shadeHit( bgColorY, rayLTC, hitInfoLTC, false, + 0, false ) ); } - // Trace and shade cRTC - // ///////////////////////////////////////////////////////////// CCOLORRGB cRTC = BlendColor( cRT , cC ); if( hitPacket[ iRT ].m_hitresult || hittedC ) @@ -1545,18 +1550,16 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO ) if( hittedC ) hitted = centerHitInfo.pHitObject->Intersect( rayRTC, hitInfoRTC ); - else - if( hitPacket[ iRT ].m_hitresult ) - hitted = hitPacket[ iRT ].m_HitInfo.pHitObject->Intersect( rayRTC, - hitInfoRTC ); + else if( hitPacket[ iRT ].m_hitresult ) + hitted = hitPacket[ iRT ].m_HitInfo.pHitObject->Intersect( rayRTC, + hitInfoRTC ); if( hitted ) - cRTC = CCOLORRGB( shadeHit( bgColorY, rayRTC, hitInfoRTC, false, 0, false ) ); + cRTC = CCOLORRGB( shadeHit( bgColorY, rayRTC, hitInfoRTC, false, + 0, false ) ); } - // Trace and shade cLBC - // ///////////////////////////////////////////////////////////// CCOLORRGB cLBC = BlendColor( cLB , cC ); if( hitPacket[ iLB ].m_hitresult || hittedC ) @@ -1573,18 +1576,16 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO ) if( hittedC ) hitted = centerHitInfo.pHitObject->Intersect( rayLBC, hitInfoLBC ); - else - if( hitPacket[ iLB ].m_hitresult ) - hitted = hitPacket[ iLB ].m_HitInfo.pHitObject->Intersect( rayLBC, - hitInfoLBC ); + else if( hitPacket[ iLB ].m_hitresult ) + hitted = hitPacket[ iLB ].m_HitInfo.pHitObject->Intersect( rayLBC, + hitInfoLBC ); if( hitted ) - cLBC = CCOLORRGB( shadeHit( bgColorY, rayLBC, hitInfoLBC, false, 0, false ) ); + cLBC = CCOLORRGB( shadeHit( bgColorY, rayLBC, hitInfoLBC, false, + 0, false ) ); } - // Trace and shade cRBC - // ///////////////////////////////////////////////////////////// CCOLORRGB cRBC = BlendColor( cRB , cC ); if( hitPacket[ iRB ].m_hitresult || hittedC ) @@ -1601,19 +1602,16 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO ) if( hittedC ) hitted = centerHitInfo.pHitObject->Intersect( rayRBC, hitInfoRBC ); - else - if( hitPacket[ iRB ].m_hitresult ) - hitted = hitPacket[ iRB ].m_HitInfo.pHitObject->Intersect( rayRBC, - hitInfoRBC ); + else if( hitPacket[ iRB ].m_hitresult ) + hitted = hitPacket[ iRB ].m_HitInfo.pHitObject->Intersect( rayRBC, + hitInfoRBC ); if( hitted ) - cRBC = CCOLORRGB( shadeHit( bgColorY, rayRBC, hitInfoRBC, false, 0, false ) ); + cRBC = CCOLORRGB( shadeHit( bgColorY, rayRBC, hitInfoRBC, false, + 0, false ) ); } - // Set pixel colors - // ///////////////////////////////////////////////////////////// - GLubyte *ptr = &ptrPBO[ (4 * x + m_blockPositionsFast[iBlock].x + m_realBufferSize.x * (m_blockPositionsFast[iBlock].y + 4 * y)) * 4 ]; @@ -1742,7 +1740,8 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor, else { - const unsigned int shadow_number_of_samples = m_boardAdapter.m_raytrace_nrsamples_shadows; + const unsigned int shadow_number_of_samples = + m_boardAdapter.m_raytrace_nrsamples_shadows; const float shadow_inc_factor = 1.0f / (float)(shadow_number_of_samples); for( unsigned int i = 0; i < shadow_number_of_samples; ++i ) @@ -1756,9 +1755,9 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor, else { const SFVEC3F unifVector = UniformRandomHemisphereDirection(); - const SFVEC3F disturbed_vector_to_light = glm::normalize( vectorToLight + - unifVector * - m_boardAdapter.m_raytrace_spread_shadows ); + const SFVEC3F disturbed_vector_to_light = + glm::normalize( vectorToLight + unifVector * + m_boardAdapter.m_raytrace_spread_shadows ); rayToLight.Init( hitPoint, disturbed_vector_to_light ); } @@ -1766,7 +1765,6 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor, // !TODO: there are multiple ways that this tests can be // optimized. Eg: by packing rays or to test against the // latest hit object. - if( m_accelerator->IntersectP( rayToLight, distToLight ) ) { shadow_att_factor_light -= shadow_inc_factor; @@ -1808,13 +1806,12 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor, if( !m_isPreview ) { // Reflections - // ///////////////////////////////////////////////////////////////////// - if( ( objMaterial->GetReflection() > 0.0f ) && m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_REFLECTIONS ) && ( aRecursiveLevel < objMaterial->GetReflectionsRecursiveLevel() ) ) { - const unsigned int reflection_number_of_samples = objMaterial->GetNrReflectionsSamples(); + const unsigned int reflection_number_of_samples = + objMaterial->GetNrReflectionsSamples(); SFVEC3F sum_color = SFVEC3F(0.0f); @@ -1863,10 +1860,7 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor, outColor += (sum_color / SFVEC3F( (float)reflection_number_of_samples) ); } - // Refractions - // ///////////////////////////////////////////////////////////////////// - const float objTransparency = aHitInfo.pHitObject->GetModelTransparency(); if( ( objTransparency > 0.0f ) && @@ -1889,9 +1883,12 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor, { // This increase the start point by a "fixed" factor so it will work the // same for all distances - const SFVEC3F startPoint = aRay.at( aHitInfo.m_tHit + m_boardAdapter.GetNonCopperLayerThickness3DU() * 0.25f ); + const SFVEC3F startPoint = + aRay.at( aHitInfo.m_tHit + m_boardAdapter.GetNonCopperLayerThickness3DU() * + 0.25f ); - const unsigned int refractions_number_of_samples = objMaterial->GetNrRefractionsSamples(); + const unsigned int refractions_number_of_samples = + objMaterial->GetNrRefractionsSamples(); SFVEC3F sum_color = SFVEC3F(0.0f); @@ -1906,9 +1903,10 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor, else { // apply some randomize to the refracted vector - const SFVEC3F randomizeRefractedVector = glm::normalize( refractedVector + - UniformRandomHemisphereDirection() * - m_boardAdapter.m_raytrace_spread_refractions ); + const SFVEC3F randomizeRefractedVector = + glm::normalize( refractedVector + + UniformRandomHemisphereDirection() * + m_boardAdapter.m_raytrace_spread_refractions ); refractedRay.Init( startPoint, randomizeRefractedVector ); } @@ -1916,7 +1914,6 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor, HITINFO refractedHit; refractedHit.m_tHit = std::numeric_limits::infinity(); - SFVEC3F refractedColor = aBgColor; if( m_accelerator->Intersect( refractedRay, refractedHit ) ) @@ -1930,7 +1927,7 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor, const SFVEC3F absorbance = ( SFVEC3F(1.0f) - diffuseColorObj ) * (1.0f - objTransparency ) * - objMaterial->GetAbsorvance() * // Adjust falloff factor + objMaterial->GetAbsorvance() * refractedHit.m_tHit; const SFVEC3F transparency = 1.0f / ( absorbance + 1.0f ); @@ -1944,7 +1941,8 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor, } outColor = outColor * (1.0f - objTransparency) + - objTransparency * sum_color / SFVEC3F( (float)refractions_number_of_samples); + objTransparency * sum_color / + SFVEC3F( (float)refractions_number_of_samples); } else { @@ -2010,13 +2008,12 @@ static float distance( const SFVEC2UI& a, const SFVEC2UI& b ) return hypotf( dx, dy ); } + void C3D_RENDER_RAYTRACING::initialize_block_positions() { - m_realBufferSize = SFVEC2UI( 0 ); // Calc block positions for fast preview mode - // ///////////////////////////////////////////////////////////////////// m_blockPositionsFast.clear(); unsigned int i = 0; @@ -2061,7 +2058,6 @@ void C3D_RENDER_RAYTRACING::initialize_block_positions() // Calc block positions for regular rendering. Choose an 'inside out' // style of rendering - // ///////////////////////////////////////////////////////////////////// m_blockPositions.clear(); const int blocks_x = m_realBufferSize.x / RAYPACKET_DIM; const int blocks_y = m_realBufferSize.y / RAYPACKET_DIM; @@ -2085,17 +2081,20 @@ void C3D_RENDER_RAYTRACING::initialize_block_positions() opengl_init_pbo(); } + BOARD_ITEM *C3D_RENDER_RAYTRACING::IntersectBoardItem( const RAY &aRay ) { HITINFO hitInfo; hitInfo.m_tHit = std::numeric_limits::infinity(); if( m_accelerator ) + { if( m_accelerator->Intersect( aRay, hitInfo ) ) { if( hitInfo.pHitObject ) return hitInfo.pHitObject->GetBoardItem(); } + } return nullptr; } diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.h b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.h index 7bf815dfbd..6f3db18037 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.h +++ b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2020 Mario Luzeiro - * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -54,7 +54,8 @@ typedef enum RT_RENDER_STATE_POST_PROCESS_BLUR_AND_FINISH, RT_RENDER_STATE_FINISH, RT_RENDER_STATE_MAX -}RT_RENDER_STATE; +} RT_RENDER_STATE; + class C3D_RENDER_RAYTRACING : public C3D_RENDER_BASE { @@ -69,7 +70,8 @@ public: int GetWaitForEditingTimeOut() override; - void Reload( REPORTER* aStatusReporter, REPORTER* aWarningReporter, bool aOnlyLoadCopperAndShapes ); + void Reload( REPORTER* aStatusReporter, REPORTER* aWarningReporter, + bool aOnlyLoadCopperAndShapes ); BOARD_ITEM *IntersectBoardItem( const RAY &aRay ); @@ -106,6 +108,43 @@ private: // Materials void setupMaterials(); + SFVEC3F shadeHit( const SFVEC3F &aBgColor, + const RAY &aRay, + HITINFO &aHitInfo, + bool aIsInsideObject, + unsigned int aRecursiveLevel, + bool is_testShadow ) const; + + /** + * Create one or more 3D objects form a 2D object and Z positions. + * + * It tries to optimize some types of objects that will be faster to trace than the + * CLAYERITEM object. + */ + void create_3d_object_from( CCONTAINER &aDstContainer, + const COBJECT2D *aObject2D, + float aZMin, float aZMax, + const CMATERIAL *aMaterial, + const SFVEC3F &aObjColor ); + + void add_3D_vias_and_pads_to_container(); + void insert3DViaHole( const VIA* aVia ); + void insert3DPadHole( const PAD* aPad ); + void load_3D_models( CCONTAINER &aDstContainer, bool aSkipMaterialInformation ); + void add_3D_models( CCONTAINER &aDstContainer, + const S3DMODEL *a3DModel, + const glm::mat4 &aModelMatrix, + float aFPOpacity, + bool aSkipMaterialInformation, + BOARD_ITEM *aBoardItem ); + + MODEL_MATERIALS *get_3D_model_material( const S3DMODEL *a3DModel ); + + void initialize_block_positions(); + + void render( GLubyte* ptrPBO, REPORTER* aStatusReporter ); + void render_preview( GLubyte *ptrPBO ); + struct { CBLINN_PHONG_MATERIAL m_Paste; @@ -115,7 +154,7 @@ private: CBLINN_PHONG_MATERIAL m_Copper; CBLINN_PHONG_MATERIAL m_NonPlatedCopper; CBLINN_PHONG_MATERIAL m_Floor; - }m_materials; + } m_materials; CBOARDNORMAL m_board_normal_perturbator; CCOPPERNORMAL m_copper_normal_perturbator; @@ -128,13 +167,6 @@ private: bool m_isPreview; - SFVEC3F shadeHit( const SFVEC3F &aBgColor, - const RAY &aRay, - HITINFO &aHitInfo, - bool aIsInsideObject, - unsigned int aRecursiveLevel, - bool is_testShadow ) const; - /// State used on quality render RT_RENDER_STATE m_rt_render_state; @@ -151,6 +183,7 @@ private: CDIRECTIONALLIGHT *m_camera_light; bool m_opengl_support_vertex_buffer_object; + GLuint m_pboId; GLuint m_pboDataSize; @@ -193,36 +226,12 @@ private: unsigned int m_xoffset; unsigned int m_yoffset; - // Statistics - unsigned int m_stats_converted_dummy_to_plane; - unsigned int m_stats_converted_roundsegment2d_to_roundsegment; - - void create_3d_object_from( CCONTAINER &aDstContainer, - const COBJECT2D *aObject2D, - float aZMin, float aZMax, - const CMATERIAL *aMaterial, - const SFVEC3F &aObjColor ); - - void add_3D_vias_and_pads_to_container(); - void insert3DViaHole( const VIA* aVia ); - void insert3DPadHole( const PAD* aPad ); - void load_3D_models( CCONTAINER &aDstContainer, bool aSkipMaterialInformation ); - void add_3D_models( CCONTAINER &aDstContainer, - const S3DMODEL *a3DModel, - const glm::mat4 &aModelMatrix, - float aFPOpacity, - bool aSkipMaterialInformation, - BOARD_ITEM *aBoardItem ); - - MODEL_MATERIALS *get_3D_model_material( const S3DMODEL *a3DModel ); - /// Stores materials of the 3D models MAP_MODEL_MATERIALS m_model_materials; - void initialize_block_positions(); - - void render( GLubyte* ptrPBO, REPORTER* aStatusReporter ); - void render_preview( GLubyte *ptrPBO ); + // Statistics + unsigned int m_stats_converted_dummy_to_plane; + unsigned int m_stats_converted_roundsegment2d_to_roundsegment; }; #define USE_SRGB_SPACE diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/clight.h b/3d-viewer/3d_rendering/3d_render_raytracing/clight.h index 024277b434..d355435c80 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/clight.h +++ b/3d-viewer/3d_rendering/3d_render_raytracing/clight.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -33,8 +33,11 @@ #include "ray.h" #include "hitinfo.h" -/// A base light class to derive to implement other light classes -class CLIGHT + +/** + * A base light class to derive to implement other light classes. + */ +class CLIGHT { public: CLIGHT() { m_castShadow = true; } @@ -42,12 +45,13 @@ public: virtual ~CLIGHT() {} /** - * @brief GetLightParameters - Get parameters from this light + * Get parameters from this light. + * * @param aHitPoint: input hit position - * @param aOutVectorToLight: a vector that points from the hit - * position in direction to the light - * @param aOutLightColor: the color of this light - * @param aOutDistance: the distance from the point to the light + * @param aOutVectorToLight a vector that points from the hit + * position in direction to the light + * @param aOutLightColor the color of this light + * @param aOutDistance the distance from the point to the light */ virtual void GetLightParameters( const SFVEC3F &aHitPoint, SFVEC3F &aOutVectorToLight, @@ -62,11 +66,11 @@ protected: }; -/// Point light based on: -/// http://ogldev.atspace.co.uk/www/tutorial20/tutorial20.html -class CPOINTLIGHT : public CLIGHT +/** + * Point light based on http://ogldev.atspace.co.uk/www/tutorial20/tutorial20.html. + */ +class CPOINTLIGHT : public CLIGHT { - public: CPOINTLIGHT( const SFVEC3F &aPos, const SFVEC3F &aColor ) { @@ -79,7 +83,6 @@ public: } // Imported functions from CLIGHT - void GetLightParameters( const SFVEC3F &aHitPoint, SFVEC3F &aOutVectorToLight, SFVEC3F &aOutLightColor, @@ -110,8 +113,10 @@ private: }; -/// Directional light - a light based only on a direction vector -class CDIRECTIONALLIGHT : public CLIGHT +/** + * A light based only on a direction vector. + */ +class CDIRECTIONALLIGHT : public CLIGHT { public: CDIRECTIONALLIGHT( const SFVEC3F &aDir, const SFVEC3F &aColor ) @@ -123,13 +128,12 @@ public: } /** - * @brief SetDirection - Set directional light orientation + * @brief SetDirection Set directional light orientation * @param aDir: vector from the light */ void SetDirection( const SFVEC3F &aDir ) { m_inv_direction = -aDir; } // Imported functions from CLIGHT - void GetLightParameters( const SFVEC3F &aHitPoint, SFVEC3F &aOutVectorToLight, SFVEC3F &aOutLightColor, @@ -143,7 +147,7 @@ public: } private: - SFVEC3F m_inv_direction; ///< oposite direction of the light + SFVEC3F m_inv_direction; ///< opposite direction of the light SFVEC3F m_color; ///< light color }; @@ -151,7 +155,11 @@ private: typedef std::list< CLIGHT * > LIST_LIGHT; -/// A light contariner. It will add lights and remove it in the end +/** + * A light container. It will add lights and remove it in the end. + * + * @todo Do we really need this object? Wouldn't it be cleaner to just use std::list directly? + */ class CLIGHTCONTAINER { public: @@ -178,7 +186,6 @@ public: } } - /** * @brief Add - Add a light to the container * @param aLight diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.cpp index b0ef98406a..05e3ad910d 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2020 Mario Luzeiro - * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -41,6 +41,7 @@ int CMATERIAL::m_default_reflections_recursive_levels = 3; #define AMBIENT_FACTOR (1.0f / 6.0f) #define SPECULAR_FACTOR 1.0f + CMATERIAL::CMATERIAL() { m_ambientColor = SFVEC3F( 0.2f, 0.2f, 0.2f ); @@ -170,7 +171,6 @@ SFVEC3F CBOARDNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) const // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiJzaW4oc2luKHNpbih4KSoxLjkpKjEuNSkiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyItMC45NjIxMDU3MDgwNzg1MjYyIiwiNy45NzE0MjYyNjc2MDE0MyIsIi0yLjUxNzYyMDM1MTQ4MjQ0OSIsIjIuOTc5OTM3Nzg3Mzk3NTMwMyJdLCJzaXplIjpbNjQ2LDM5Nl19XQ-- // Implement a texture as the "measling crazing blistering" method of FR4 - const float x = glm::sin( glm::sin( hitPos.x ) * 1.5f ) * 0.06f; const float y = glm::sin( glm::sin( hitPos.y ) * 1.5f ) * 0.03f; const float z = -(x + y) + glm::sin( hitPos.z ) * 0.06f; @@ -198,10 +198,14 @@ SFVEC3F CCOPPERNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) cons SFVEC3F hitPos = aHitInfo.m_HitPoint * m_scale; - const float noise = (s_perlinNoise.noise( hitPos.x + boardNormal.y + aRay.m_Origin.x * 0.2f, - hitPos.y + boardNormal.x ) - 0.5f) * 2.0f; + const float noise = + ( s_perlinNoise.noise( hitPos.x + boardNormal.y + aRay.m_Origin.x * 0.2f, + hitPos.y + boardNormal.x ) + - 0.5f ) + * 2.0f; - float scratchPattern = (s_perlinNoise.noise( noise + hitPos.x / 100.0f, hitPos.y * 100.0f ) - 0.5f); + float scratchPattern = + ( s_perlinNoise.noise( noise + hitPos.x / 100.0f, hitPos.y * 100.0f ) - 0.5f ); const float x = scratchPattern * 0.14f; const float y = (noise + noise * scratchPattern) * 0.14f; @@ -209,7 +213,9 @@ SFVEC3F CCOPPERNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) cons return SFVEC3F( x, y, - ( x + y ) ) + boardNormal * 0.25f; } else - return SFVEC3F(0.0f); + { + return SFVEC3F( 0.0f ); + } } @@ -228,7 +234,9 @@ SFVEC3F CSOLDERMASKNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) return copperNormal * 0.05f; } else + { return SFVEC3F(0.0f); + } } @@ -344,8 +352,9 @@ SFVEC3F CSILKSCREENNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) hitPos.y * 1.2f, hitPos.z ); - SFVEC3F t = glm::abs( ( 1.8f / ( SFVEC3F( noise1, noise2, hitPos.z ) + 0.4f ) ) - 1.5f ) - 0.25f; + SFVEC3F t = + glm::abs( ( 1.8f / ( SFVEC3F( noise1, noise2, hitPos.z ) + 0.4f ) ) - 1.5f ) - 0.25f; t = t * t * t * 0.1f; return t; -} \ No newline at end of file +} diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.h b/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.h index 078b49a60a..fe688c959b 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.h +++ b/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -35,7 +35,7 @@ #include "PerlinNoise.h" /// A base class that can be used to derive a procedural generator implementation -class CPROCEDURALGENERATOR +class CPROCEDURALGENERATOR { public: CPROCEDURALGENERATOR(); @@ -45,22 +45,17 @@ public: } /** - * @brief Generate - Generates a 3D vector based on the ray and - * hit information depending on the implementation - * @param aRay: the camera ray that hits the object - * @param aHitInfo: the hit information + * Generates a 3D vector based on the ray and* hit information depending on the implementation. + * + * @param aRay the camera ray that hits the object + * @param aHitInfo the hit information * @return the result of the procedural */ - virtual SFVEC3F Generate( const RAY &aRay, - const HITINFO &aHitInfo ) const = 0; - -protected: - + virtual SFVEC3F Generate( const RAY &aRay, const HITINFO &aHitInfo ) const = 0; }; -// Procedural generation of the board normals -class CBOARDNORMAL : public CPROCEDURALGENERATOR +class CBOARDNORMAL : public CPROCEDURALGENERATOR { public: CBOARDNORMAL() : CPROCEDURALGENERATOR() { m_scale = 1.0f; } @@ -70,15 +65,17 @@ public: { } - // Imported from CPROCEDURALGENERATOR - SFVEC3F Generate( const RAY &aRay, - const HITINFO &aHitInfo ) const override; + SFVEC3F Generate( const RAY &aRay, const HITINFO &aHitInfo ) const override; + private: float m_scale; }; -// Procedural generation of the copper normals -class CCOPPERNORMAL : public CPROCEDURALGENERATOR + +/** + * Procedural generation of the copper normals. + */ +class CCOPPERNORMAL : public CPROCEDURALGENERATOR { public: CCOPPERNORMAL() : CPROCEDURALGENERATOR() @@ -93,15 +90,15 @@ public: { } - // Imported from CPROCEDURALGENERATOR - SFVEC3F Generate( const RAY &aRay, - const HITINFO &aHitInfo ) const override; + SFVEC3F Generate( const RAY &aRay, const HITINFO &aHitInfo ) const override; + private: const CPROCEDURALGENERATOR *m_board_normal_generator; float m_scale; }; -class CPLATEDCOPPERNORMAL : public CPROCEDURALGENERATOR + +class CPLATEDCOPPERNORMAL : public CPROCEDURALGENERATOR { public: CPLATEDCOPPERNORMAL() : CPROCEDURALGENERATOR() @@ -118,15 +115,16 @@ public: { } - // Imported from CPROCEDURALGENERATOR - SFVEC3F Generate( const RAY &aRay, - const HITINFO &aHitInfo ) const override; + SFVEC3F Generate( const RAY &aRay, const HITINFO &aHitInfo ) const override; private: float m_scale; }; -// Procedural generation of the solder mask -class CSOLDERMASKNORMAL : public CPROCEDURALGENERATOR + +/** + * Procedural generation of the solder mask. + */ +class CSOLDERMASKNORMAL : public CPROCEDURALGENERATOR { public: CSOLDERMASKNORMAL() : CPROCEDURALGENERATOR() { m_copper_normal_generator = NULL; } @@ -136,16 +134,17 @@ public: { } - // Imported from CPROCEDURALGENERATOR - SFVEC3F Generate( const RAY &aRay, - const HITINFO &aHitInfo ) const override; + SFVEC3F Generate( const RAY &aRay, const HITINFO &aHitInfo ) const override; + private: const CPROCEDURALGENERATOR *m_copper_normal_generator; }; -// Procedural generation of the plastic normals -class CPLASTICNORMAL : public CPROCEDURALGENERATOR +/** + * Procedural generation of the plastic normals. + */ +class CPLASTICNORMAL : public CPROCEDURALGENERATOR { public: CPLASTICNORMAL() : CPROCEDURALGENERATOR() @@ -159,16 +158,17 @@ public: { } - // Imported from CPROCEDURALGENERATOR - SFVEC3F Generate( const RAY &aRay, - const HITINFO &aHitInfo ) const override; + SFVEC3F Generate( const RAY &aRay, const HITINFO &aHitInfo ) const override; + private: float m_scale; }; -// Procedural generation of the shiny plastic normals -class CPLASTICSHINENORMAL : public CPROCEDURALGENERATOR +/** + * Procedural generation of the shiny plastic normals. + */ +class CPLASTICSHINENORMAL : public CPROCEDURALGENERATOR { public: CPLASTICSHINENORMAL() : CPROCEDURALGENERATOR() @@ -189,8 +189,10 @@ private: float m_scale; }; -// Procedural generation of the shiny brushed metal -class CMETALBRUSHEDNORMAL : public CPROCEDURALGENERATOR +/** + * Procedural generation of the shiny brushed metal. + */ +class CMETALBRUSHEDNORMAL : public CPROCEDURALGENERATOR { public: CMETALBRUSHEDNORMAL() : CPROCEDURALGENERATOR() @@ -204,14 +206,14 @@ public: { } - // Imported from CPROCEDURALGENERATOR - SFVEC3F Generate( const RAY &aRay, - const HITINFO &aHitInfo ) const override; + SFVEC3F Generate( const RAY &aRay, const HITINFO &aHitInfo ) const override; + private: float m_scale; }; -class CSILKSCREENNORMAL : public CPROCEDURALGENERATOR + +class CSILKSCREENNORMAL : public CPROCEDURALGENERATOR { public: CSILKSCREENNORMAL() : CPROCEDURALGENERATOR() @@ -225,30 +227,39 @@ public: { } - // Imported from CPROCEDURALGENERATOR - SFVEC3F Generate( const RAY &aRay, - const HITINFO &aHitInfo ) const override; + SFVEC3F Generate( const RAY &aRay, const HITINFO &aHitInfo ) const override; + private: float m_scale; }; -/// A base material class that can be used to derive a material implementation -class CMATERIAL + +/** + * Base material class that can be used to derive other material implementations. + */ +class CMATERIAL { public: - static void SetDefaultNrRefractionsSamples( unsigned int aNrRefractions ) { m_default_nrsamples_refractions = aNrRefractions; } - static void SetDefaultNrReflectionsSamples( unsigned int aNrReflections ) { m_default_nrsamples_reflections = aNrReflections; } + static void SetDefaultNrRefractionsSamples( unsigned int aNrRefractions ) + { + m_default_nrsamples_refractions = aNrRefractions; + } - static void SetDefaultRefractionsLevel( unsigned int aRefractionLevel ) { m_default_refractions_recursive_levels = aRefractionLevel; } - static void SetDefaultReflectionsLevel( unsigned int aReflectionLevel ) { m_default_reflections_recursive_levels = aReflectionLevel; } + static void SetDefaultNrReflectionsSamples( unsigned int aNrReflections ) + { + m_default_nrsamples_reflections = aNrReflections; + } -private: - static int m_default_nrsamples_refractions; - static int m_default_nrsamples_reflections; - static int m_default_refractions_recursive_levels; - static int m_default_reflections_recursive_levels; + static void SetDefaultRefractionsLevel( unsigned int aRefractionLevel ) + { + m_default_refractions_recursive_levels = aRefractionLevel; + } + + static void SetDefaultReflectionsLevel( unsigned int aReflectionLevel ) + { + m_default_reflections_recursive_levels = aReflectionLevel; + } -public: CMATERIAL(); CMATERIAL( const SFVEC3F &aAmbient, const SFVEC3F &aEmissive, @@ -273,27 +284,44 @@ public: unsigned int GetRefractionsRecursiveLevel() const { return m_refractions_recursive_levels; } void SetAbsorvance( float aAbsorvanceFactor ) { m_absorbance = aAbsorvanceFactor; } - void SetNrRefractionsSamples( unsigned int aNrRefractions ) { m_refraction_nr_samples = aNrRefractions; } - void SetNrReflectionsSamples( unsigned int aNrReflections ) { m_reflections_nr_samples = aNrReflections; } - void SetReflectionsRecursiveLevel( unsigned int aReflectionsLevel ) { m_reflections_recursive_levels = aReflectionsLevel; } - void SetRefractionsRecursiveLevel( unsigned int aRefractionsLevel ) { m_refractions_recursive_levels = aRefractionsLevel; } + void SetNrRefractionsSamples( unsigned int aNrRefractions ) + { + m_refraction_nr_samples = aNrRefractions; + } + + void SetNrReflectionsSamples( unsigned int aNrReflections ) + { + m_reflections_nr_samples = aNrReflections; + } + + void SetReflectionsRecursiveLevel( unsigned int aReflectionsLevel ) + { + m_reflections_recursive_levels = aReflectionsLevel; + } + + void SetRefractionsRecursiveLevel( unsigned int aRefractionsLevel ) + { + m_refractions_recursive_levels = aRefractionsLevel; + } /** - * @brief SetCastShadows - Set if the material can receive shadows - * @param aCastShadows - true yes it can, false not it cannot + * Set if the material can receive shadows. + * + * @param aCastShadows true yes it can, false not it cannot */ void SetCastShadows( bool aCastShadows ) { m_cast_shadows = aCastShadows; } bool GetCastShadows() const { return m_cast_shadows; } /** - * @brief Shade - Shades an intersection point - * @param aRay: the camera ray that hits the object - * @param aHitInfo: the hit information - * @param NdotL: the dot product between Normal and Light - * @param aDiffuseObjColor: diffuse object color - * @param aDirToLight: a vector of the incident light direction - * @param aLightColor: the light color + * Shade an intersection point. + * + * @param aRay the camera ray that hits the object + * @param aHitInfo the hit information + * @param NdotL the dot product between Normal and Light + * @param aDiffuseObjColor diffuse object color + * @param aDirToLight a vector of the incident light direction + * @param aLightColor the light color * @param aShadowAttenuationFactor 0.0f total in shadow, 1.0f completely not in shadow * @return the resultant color */ @@ -305,7 +333,11 @@ public: const SFVEC3F &aLightColor, float aShadowAttenuationFactor ) const = 0; - void SetNormalPerturbator( const CPROCEDURALGENERATOR *aPerturbator ) { m_normal_perturbator = aPerturbator; } + void SetNormalPerturbator( const CPROCEDURALGENERATOR *aPerturbator ) + { + m_normal_perturbator = aPerturbator; + } + const CPROCEDURALGENERATOR *GetNormalPerturbator() const { return m_normal_perturbator; } void PerturbeNormal( SFVEC3F &aNormal, const RAY &aRay, const HITINFO &aHitInfo ) const; @@ -320,22 +352,38 @@ protected: SFVEC3F m_emissiveColor; SFVEC3F m_specularColor; float m_shinness; - float m_transparency; ///< 1.0 is completely transparent, 0.0 completely opaque - float m_absorbance; ///< absorvance factor for the transparent material - float m_reflection; ///< 1.0 completely reflective, 0.0 no reflective - bool m_cast_shadows; ///< true if this object will block the light - unsigned int m_refraction_nr_samples; ///< nr of rays that will be interpolated for this material if it is a transparent - unsigned int m_reflections_nr_samples; ///< nr of rays that will be interpolated for this material if it is reflective - unsigned int m_refractions_recursive_levels; ///< nr of levels it allows for refractions recursiveness - unsigned int m_reflections_recursive_levels; ///< nr of levels it allows for reflection recursiveness + + ///< 1.0 is completely transparent, 0.0 completely opaque. + float m_transparency; + float m_absorbance; ///< absorbance factor for the transparent material. + float m_reflection; ///< 1.0 completely reflective, 0.0 no reflective. + bool m_cast_shadows; ///< true if this object will block the light. + + ///< Number of rays that will be interpolated for this material if it is a transparent. + unsigned int m_refraction_nr_samples; + + ///< Number of rays that will be interpolated for this material if it is reflective. + unsigned int m_reflections_nr_samples; + + ///< Number of levels it allows for refraction recursiveness. + unsigned int m_refractions_recursive_levels; + + ///< Number of levels it allows for reflection recursiveness. + unsigned int m_reflections_recursive_levels; const CPROCEDURALGENERATOR *m_normal_perturbator; + +private: + static int m_default_nrsamples_refractions; + static int m_default_nrsamples_reflections; + static int m_default_refractions_recursive_levels; + static int m_default_reflections_recursive_levels; }; /// Blinn Phong based material /// https://en.wikipedia.org/wiki/Blinn%E2%80%93Phong_shading_model -class CBLINN_PHONG_MATERIAL : public CMATERIAL +class CBLINN_PHONG_MATERIAL : public CMATERIAL { public: CBLINN_PHONG_MATERIAL() : CMATERIAL() {} diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/ray.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/ray.cpp index 780617a731..f8aa7fbd95 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/ray.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/ray.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2017 Mario Luzeiro - * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -56,7 +56,6 @@ void RAY::Init( const SFVEC3F& o, const SFVEC3F& d ) m_dirIsNeg[1] = m_Dir.y < 0.0f; m_dirIsNeg[2] = m_Dir.z < 0.0f; - // ray slope // "Fast Ray / Axis-Aligned Bounding Box Overlap Tests using Ray Slopes" @@ -94,12 +93,12 @@ void RAY::Init( const SFVEC3F& o, const SFVEC3F& d ) { m_Classification = RAY_CLASSIFICATION::MMP; } - else//( m_Dir.z >= 0 ) + else { m_Classification = RAY_CLASSIFICATION::MMO; } } - else//( m_Dir.y >= 0 ) + else { if( m_Dir.z < 0 ) { @@ -107,7 +106,7 @@ void RAY::Init( const SFVEC3F& o, const SFVEC3F& d ) if( m_Dir.y == 0 ) m_Classification = RAY_CLASSIFICATION::MOM; } - else//( m_Dir.z >= 0 ) + else { if( ( m_Dir.y == 0 ) && ( m_Dir.z == 0 ) ) m_Classification = RAY_CLASSIFICATION::MOO; @@ -120,7 +119,7 @@ void RAY::Init( const SFVEC3F& o, const SFVEC3F& d ) } } } - else//( m_Dir.x >= 0 ) + else { if( m_Dir.y < 0 ) { @@ -130,7 +129,7 @@ void RAY::Init( const SFVEC3F& o, const SFVEC3F& d ) if( m_Dir.x == 0 ) m_Classification = RAY_CLASSIFICATION::OMM; } - else//( m_Dir.z >= 0 ) + else { if( ( m_Dir.x == 0 ) && ( m_Dir.z == 0 ) ) m_Classification = RAY_CLASSIFICATION::OMO; @@ -142,7 +141,7 @@ void RAY::Init( const SFVEC3F& o, const SFVEC3F& d ) m_Classification = RAY_CLASSIFICATION::PMP; } } - else//( m_Dir.y >= 0 ) + else { if( m_Dir.z < 0 ) { @@ -155,7 +154,7 @@ void RAY::Init( const SFVEC3F& o, const SFVEC3F& d ) else m_Classification = RAY_CLASSIFICATION::PPM; } - else//( m_Dir.z > 0 ) + else { if( m_Dir.x == 0 ) { @@ -196,14 +195,14 @@ bool IntersectSegment( const SFVEC2F &aStartA, const SFVEC2F &aEnd_minus_startA, SFVEC2F pq = aStartB - aStartA; - float t = (pq.x * aEnd_minus_startB.y - pq.y * aEnd_minus_startB.x) * inv_rxs; + float t = ( pq.x * aEnd_minus_startB.y - pq.y * aEnd_minus_startB.x ) * inv_rxs; - if( (t < 0.0f) || (t > 1.0f) ) + if( ( t < 0.0f ) || ( t > 1.0f ) ) return false; - float u = (pq.x * aEnd_minus_startA.y - pq.y * aEnd_minus_startA.x) * inv_rxs; + float u = ( pq.x * aEnd_minus_startA.y - pq.y * aEnd_minus_startA.x ) * inv_rxs; - if( (u < 0.0f) || (u > 1.0f) ) + if( ( u < 0.0f ) || ( u > 1.0f ) ) return false; return true; @@ -213,8 +212,9 @@ bool IntersectSegment( const SFVEC2F &aStartA, const SFVEC2F &aEnd_minus_startA, } -// !TODO: not tested -bool RAY::IntersectSphere( const SFVEC3F &aCenter, float aRadius, float &aOutT0, float &aOutT1 ) const +/// @todo: not tested +bool RAY::IntersectSphere( const SFVEC3F &aCenter, float aRadius, float &aOutT0, + float &aOutT1 ) const { /* // Ray-sphere intersection: algebraic @@ -279,13 +279,13 @@ RAYSEG2D::RAYSEG2D( const SFVEC2F& s, const SFVEC2F& e ) m_End_minus_start = e - s; m_Length = glm::length( m_End_minus_start ); m_Dir = glm::normalize( m_End_minus_start ); - m_InvDir = (1.0f / m_Dir); + m_InvDir = ( 1.0f / m_Dir ); - if( fabs(m_Dir.x) < FLT_EPSILON ) - m_InvDir.x = NextFloatDown(FLT_MAX); + if( fabs( m_Dir.x ) < FLT_EPSILON ) + m_InvDir.x = NextFloatDown( FLT_MAX ); - if( fabs(m_Dir.y) < FLT_EPSILON ) - m_InvDir.y = NextFloatDown(FLT_MAX); + if( fabs( m_Dir.y ) < FLT_EPSILON ) + m_InvDir.y = NextFloatDown( FLT_MAX ); m_DOT_End_minus_start = glm::dot( m_End_minus_start, m_End_minus_start ); } @@ -295,8 +295,7 @@ bool RAYSEG2D::IntersectSegment( const SFVEC2F &aStart, const SFVEC2F &aEnd_minus_start, float *aOutT ) const { - float rxs = m_End_minus_start.x * - aEnd_minus_start.y - m_End_minus_start.y * + float rxs = m_End_minus_start.x * aEnd_minus_start.y - m_End_minus_start.y * aEnd_minus_start.x; if( std::abs( rxs ) > glm::epsilon() ) @@ -305,14 +304,14 @@ bool RAYSEG2D::IntersectSegment( const SFVEC2F &aStart, const SFVEC2F pq = aStart - m_Start; - const float t = (pq.x * aEnd_minus_start.y - pq.y * aEnd_minus_start.x) * inv_rxs; + const float t = ( pq.x * aEnd_minus_start.y - pq.y * aEnd_minus_start.x ) * inv_rxs; - if( (t < 0.0f) || (t > 1.0f) ) + if( ( t < 0.0f ) || ( t > 1.0f ) ) return false; - float u = (pq.x * m_End_minus_start.y - pq.y * m_End_minus_start.x) * inv_rxs; + float u = ( pq.x * m_End_minus_start.y - pq.y * m_End_minus_start.x ) * inv_rxs; - if( (u < 0.0f) || (u > 1.0f) ) + if( ( u < 0.0f ) || ( u > 1.0f ) ) return false; *aOutT = t; @@ -335,7 +334,9 @@ float RAYSEG2D::DistanceToPointSquared( const SFVEC2F &aPoint ) const return glm::dot( p, p ); if( m_DOT_End_minus_start <= c1 ) + { p = aPoint - m_End; + } else { const float b = c1 / m_DOT_End_minus_start; @@ -373,16 +374,14 @@ bool RAYSEG2D::IntersectCircle( const SFVEC2F &aCenter, if( discriminantsqr < FLT_EPSILON ) return false; - // Otherwise check and make sure that the intersections occur on the ray (t // > 0) and return the closer one const float discriminant = std::sqrt( discriminantsqr ); - const float t1 = (-qd - discriminant); - const float t2 = (-qd + discriminant); + const float t1 = ( -qd - discriminant ); + const float t2 = ( -qd + discriminant ); - if( (( t1 < 0.0f ) || ( t1 > m_Length ) ) && - (( t2 < 0.0f ) || ( t2 > m_Length ) ) ) - return false;// Neither intersection was in the ray's half line. + if( ( ( t1 < 0.0f ) || ( t1 > m_Length ) ) && ( ( t2 < 0.0f ) || ( t2 > m_Length ) ) ) + return false; // Neither intersection was in the ray's half line. // Convert the intersection to a normalized *aOutT0 = t1 / m_Length; @@ -391,8 +390,8 @@ bool RAYSEG2D::IntersectCircle( const SFVEC2F &aCenter, SFVEC2F hitPointT1 = at( t1 ); SFVEC2F hitPointT2 = at( t2 ); - *aOutNormalT0 = (hitPointT1 - aCenter) / aRadius; - *aOutNormalT1 = (hitPointT2 - aCenter) / aRadius; + *aOutNormalT0 = ( hitPointT1 - aCenter ) / aRadius; + *aOutNormalT1 = ( hitPointT2 - aCenter ) / aRadius; return true; } @@ -401,5 +400,5 @@ bool RAYSEG2D::IntersectCircle( const SFVEC2F &aCenter, void RAY::debug() const { wxLogDebug( "O(%f, %f, %f) D(%f, %f, %f)\n", m_Origin.x, m_Origin.y, m_Origin.z, - m_Dir.x, m_Dir.y, m_Dir.z ); + m_Dir.x, m_Dir.y, m_Dir.z ); } diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/ray.h b/3d-viewer/3d_rendering/3d_render_raytracing/ray.h index 1f319e015c..4df3ec85cc 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/ray.h +++ b/3d-viewer/3d_rendering/3d_render_raytracing/ray.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2017 Mario Luzeiro - * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -133,7 +133,8 @@ struct RAYSEG2D float DistanceToPointSquared( const SFVEC2F &aPoint ) const; /** - * Function atNormalized - returns the position at t + * Return the position at \a t. + * * t - value 0.0 ... 1.0 */ SFVEC2F atNormalized( float t ) const { return m_Start + m_End_minus_start * t; } diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/raypacket.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/raypacket.cpp index bc8d14d781..fa1421fab2 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/raypacket.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/raypacket.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -96,24 +96,25 @@ RAYPACKET::RAYPACKET( const CCAMERA &aCamera, const SFVEC3F &aDirectionDisplacementFactor ) { unsigned int i = 0; + for( unsigned int y = 0; y < RAYPACKET_DIM; ++y ) - for( unsigned int x = 0; x < RAYPACKET_DIM; ++x ) { - SFVEC3F rayOrigin; - SFVEC3F rayDir; + for( unsigned int x = 0; x < RAYPACKET_DIM; ++x ) + { + SFVEC3F rayOrigin; + SFVEC3F rayDir; - aCamera.MakeRay( SFVEC2I( aWindowsPosition.x + x, - aWindowsPosition.y + y ), - rayOrigin, rayDir ); + aCamera.MakeRay( SFVEC2I( aWindowsPosition.x + x, aWindowsPosition.y + y ), + rayOrigin, rayDir ); - const SFVEC3F randVector = SFVEC3F( Fast_RandFloat() * aDirectionDisplacementFactor.x, - Fast_RandFloat() * aDirectionDisplacementFactor.y, - Fast_RandFloat() * aDirectionDisplacementFactor.z ); + const SFVEC3F randVector = SFVEC3F( Fast_RandFloat() * aDirectionDisplacementFactor.x, + Fast_RandFloat() * aDirectionDisplacementFactor.y, + Fast_RandFloat() * aDirectionDisplacementFactor.z ); - m_ray[i].Init( rayOrigin, - glm::normalize( rayDir + randVector ) ); + m_ray[i].Init( rayOrigin, glm::normalize( rayDir + randVector ) ); - i++; + i++; + } } wxASSERT( i == RAYPACKET_RAYS_PER_PACKET ); @@ -171,6 +172,7 @@ void RAYPACKET_InitRays( const CCAMERA &aCamera, } } + void RAYPACKET_InitRays_with2DDisplacement( const CCAMERA &aCamera, const SFVEC2F &aWindowsPosition, const SFVEC2F &a2DWindowsPosDisplacementFactor,