3D viewer code cleaning round 2.

This commit is contained in:
Wayne Stambaugh 2020-12-12 12:29:11 -05:00
parent 5d7a6ea990
commit 1eba0c435b
18 changed files with 1089 additions and 1118 deletions

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt>
* 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -32,8 +32,8 @@
* Original copyright notice: * Original copyright notice:
* *
* Perlin_Noise * Perlin_Noise
* Here you could find the code for "Perlin noise in C++11", for more informations visit the project webpage: * Here you could find the code for "Perlin noise in C++11", for more information visit the
* http://solarianprogrammer.com/2012/07/18/perlin-noise-cpp-11/ * 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: * You could use this program under the terms of GPL v3, for more details see:
* http://www.gnu.org/copyleft/gpl.html * http://www.gnu.org/copyleft/gpl.html
* Copyright 2012 Sol from www.solarianprogrammer.com * Copyright 2012 Sol from www.solarianprogrammer.com
@ -79,7 +79,7 @@ PerlinNoise::PerlinNoise()
std::copy_n( p.begin(), oldsize, p.begin() + oldsize ); 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 ) PerlinNoise::PerlinNoise( unsigned int seed )
{ {
p.resize( 256 ); p.resize( 256 );
@ -90,7 +90,7 @@ PerlinNoise::PerlinNoise( unsigned int seed )
// Initialize a random engine with seed // Initialize a random engine with seed
std::default_random_engine engine( 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 ); std::shuffle( p.begin(), p.end(), engine );
// Duplicate the permutation vector // Duplicate the permutation vector
@ -99,6 +99,7 @@ PerlinNoise::PerlinNoise( unsigned int seed )
std::copy_n( p.begin(), oldsize, p.begin() + oldsize ); std::copy_n( p.begin(), oldsize, p.begin() + oldsize );
} }
float PerlinNoise::noise( float x, float y, float z ) const float PerlinNoise::noise( float x, float y, float z ) const
{ {
// Find the unit cube that contains the point // Find the unit cube that contains the point

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2016-2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -33,7 +33,7 @@
* *
* Perlin_Noise * Perlin_Noise
* "Here you could find the code for "Perlin noise in C++11", * "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/ * 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: * You could use this program under the terms of GPL v3, for more details see:
* http://www.gnu.org/copyleft/gpl.html * http://www.gnu.org/copyleft/gpl.html
@ -54,14 +54,15 @@
class PerlinNoise class PerlinNoise
{ {
// The permutation vector
std::vector<int> p;
public: public:
// Initialize with the reference values for the permutation vector /**
* Initialize with the reference values for the permutation vector.
*/
PerlinNoise(); 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 ); PerlinNoise( unsigned int seed );
// Returns between 0.0f and 1.0f // Returns between 0.0f and 1.0f
@ -73,6 +74,9 @@ private:
float lerp( float t, float a, float b ) const; 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, float z ) const;
float grad( int hash, float x, float y ) const; float grad( int hash, float x, float y ) const;
// The permutation vector
std::vector<int> p;
}; };
#endif #endif

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -52,8 +52,8 @@ static inline unsigned int getFirstHit( const RAYPACKET &aRayPacket,
{ {
float hitT; float hitT;
if( aBBox.Intersect( aRayPacket.m_ray[ia], &hitT ) ) if( aBBox.Intersect( aRayPacket.m_ray[ia], &hitT )
if( hitT < aHitInfoPacket[ia].m_HitInfo.m_tHit ) && ( hitT < aHitInfoPacket[ia].m_HitInfo.m_tHit ) )
return ia; return ia;
if( !aRayPacket.m_Frustum.Intersect( aBBox ) ) if( !aRayPacket.m_Frustum.Intersect( aBBox ) )
@ -61,8 +61,8 @@ static inline unsigned int getFirstHit( const RAYPACKET &aRayPacket,
for( unsigned int i = ia + 1; i < RAYPACKET_RAYS_PER_PACKET; ++i ) for( unsigned int i = ia + 1; i < RAYPACKET_RAYS_PER_PACKET; ++i )
{ {
if( aBBox.Intersect( aRayPacket.m_ray[i], &hitT ) ) if( aBBox.Intersect( aRayPacket.m_ray[i], &hitT )
if( hitT < aHitInfoPacket[i].m_HitInfo.m_tHit ) && ( hitT < aHitInfoPacket[i].m_HitInfo.m_tHit ) )
return i; return i;
} }
@ -81,8 +81,8 @@ static inline unsigned int getLastHit( const RAYPACKET &aRayPacket,
{ {
float hitT; float hitT;
if( aBBox.Intersect( aRayPacket.m_ray[ie], &hitT ) ) if( aBBox.Intersect( aRayPacket.m_ray[ie], &hitT )
if( hitT < aHitInfoPacket[ie].m_HitInfo.m_tHit ) && ( hitT < aHitInfoPacket[ie].m_HitInfo.m_tHit ) )
return ie + 1; return ie + 1;
} }
@ -94,8 +94,7 @@ static inline unsigned int getLastHit( const RAYPACKET &aRayPacket,
// http://cseweb.ucsd.edu/~ravir/whitted.pdf // http://cseweb.ucsd.edu/~ravir/whitted.pdf
// Ranged Traversal // Ranged Traversal
bool CBVH_PBRT::Intersect( const RAYPACKET &aRayPacket, bool CBVH_PBRT::Intersect( const RAYPACKET &aRayPacket, HITINFO_PACKET *aHitInfoPacket ) const
HITINFO_PACKET *aHitInfoPacket ) const
{ {
if( m_nodes == NULL ) if( m_nodes == NULL )
return false; return false;
@ -185,8 +184,8 @@ static inline unsigned int getLastHit( const RAYPACKET &aRayPacket,
{ {
float hitT; float hitT;
if( aBBox.Intersect( aRayPacket.m_ray[ aRayIndex[ie] ], &hitT ) ) if( aBBox.Intersect( aRayPacket.m_ray[ aRayIndex[ie] ], &hitT )
if( hitT < aHitInfoPacket[ aRayIndex[ie] ].m_HitInfo.m_tHit ) && ( hitT < aHitInfoPacket[ aRayIndex[ie] ].m_HitInfo.m_tHit ) )
return ie + 1; return ie + 1;
} }
@ -209,8 +208,8 @@ static inline unsigned int partRays( const RAYPACKET &aRayPacket,
for( unsigned int i = 0; i < ia; ++i ) for( unsigned int i = 0; i < ia; ++i )
{ {
float hitT; float hitT;
if( aBBox.Intersect( aRayPacket.m_ray[ aRayIndex[i] ], &hitT ) ) if( aBBox.Intersect( aRayPacket.m_ray[ aRayIndex[i] ], &hitT )
if( hitT < aHitInfoPacket[ aRayIndex[i] ].m_HitInfo.m_tHit ) && ( hitT < aHitInfoPacket[ aRayIndex[i] ].m_HitInfo.m_tHit ) )
std::swap( aRayIndex[ie++], aRayIndex[i] ); std::swap( aRayIndex[ie++], aRayIndex[i] );
} }
@ -218,8 +217,7 @@ static inline unsigned int partRays( const RAYPACKET &aRayPacket,
} }
bool CBVH_PBRT::Intersect( const RAYPACKET &aRayPacket, bool CBVH_PBRT::Intersect( const RAYPACKET &aRayPacket, HITINFO_PACKET *aHitInfoPacket ) const
HITINFO_PACKET *aHitInfoPacket ) const
{ {
bool anyHitted = false; bool anyHitted = false;
int todoOffset = 0, nodeNum = 0; int todoOffset = 0, nodeNum = 0;
@ -265,8 +263,7 @@ bool CBVH_PBRT::Intersect( const RAYPACKET &aRayPacket,
{ {
unsigned int idx = I[i]; unsigned int idx = I[i];
bool hitted = obj->Intersect( bool hitted = obj->Intersect( aRayPacket.m_ray[idx],
aRayPacket.m_ray[idx],
aHitInfoPacket[idx].m_HitInfo ); aHitInfoPacket[idx].m_HitInfo );
if( hitted ) if( hitted )

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * 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 * @brief This BVH implementation is based on the source code implementation
* from the book "Physically Based Rendering" (v2 and v3) * 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 * - Types and class types adapted to KiCad project
* - Convert some source to build in the C++ specification of KiCad * - Convert some source to build in the C++ specification of KiCad
* - Code style to match KiCad * - Code style to match KiCad
* - Asserts converted * - Asserts converted
* - Use compare functions/structures for std::partition and std::nth_element * - 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 * "pbrt source code is Copyright(c) 1998-2015
* Matt Pharr, Greg Humphreys, and Wenzel Jakob. * 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 // Convert the objects list to vector of objects
// /////////////////////////////////////////////////////////////////////////
aObjectContainer.ConvertTo( m_primitives ); aObjectContainer.ConvertTo( m_primitives );
wxASSERT( aObjectContainer.GetList().size() == m_primitives.size() ); wxASSERT( aObjectContainer.GetList().size() == m_primitives.size() );
// Initialize _primitiveInfo_ array for primitives // Initialize _primitiveInfo_ array for primitives
// /////////////////////////////////////////////////////////////////////////
std::vector<BVHPrimitiveInfo> primitiveInfo( m_primitives.size() ); std::vector<BVHPrimitiveInfo> primitiveInfo( m_primitives.size() );
for( size_t i = 0; i < m_primitives.size(); ++i ) for( size_t i = 0; i < m_primitives.size(); ++i )
@ -331,8 +329,7 @@ struct ComparePoints
int dim; int dim;
bool operator()( const BVHPrimitiveInfo &a, bool operator()( const BVHPrimitiveInfo &a, const BVHPrimitiveInfo &b ) const
const BVHPrimitiveInfo &b ) const
{ {
return a.centroid[dim] < b.centroid[dim]; return a.centroid[dim] < b.centroid[dim];
} }
@ -357,7 +354,10 @@ struct CompareToBucket
{ {
CompareToBucket( int split, int num, int d, const CBBOX &b ) CompareToBucket( int split, int num, int d, const CBBOX &b )
: centroidBounds(b) : centroidBounds(b)
{ splitBucket = split; nBuckets = num; dim = d; } {
splitBucket = split;
nBuckets = num; dim = d;
}
bool operator()(const BVHPrimitiveInfo &p) const; 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 ) HLBVH_SAH_Evaluator( int split, int num, int d, const CBBOX &b )
: centroidBounds(b) : centroidBounds(b)
{ minCostSplitBucket = split; nBuckets = num; dim = d; } {
minCostSplitBucket = split;
nBuckets = num; dim = d;
}
bool operator()(const BVHBuildNode *node) const; bool operator()(const BVHBuildNode *node) const;
@ -497,8 +500,7 @@ BVHBuildNode *CBVH_PBRT::recursiveBuild ( std::vector<BVHPrimitiveInfo> &primiti
{ {
int primitiveNr = primitiveInfo[i].primitiveNumber; int primitiveNr = primitiveInfo[i].primitiveNumber;
wxASSERT( (primitiveNr >= 0) && wxASSERT( ( primitiveNr >= 0 ) && ( primitiveNr < (int) m_primitives.size() ) );
(primitiveNr < (int)m_primitives.size()) );
const COBJECT *obj = static_cast<const COBJECT *>( m_primitives[ primitiveNr ] ); const COBJECT *obj = static_cast<const COBJECT *>( m_primitives[ primitiveNr ] );
@ -524,8 +526,7 @@ BVHBuildNode *CBVH_PBRT::recursiveBuild ( std::vector<BVHPrimitiveInfo> &primiti
CompareToMid( dim, pmid ) ); CompareToMid( dim, pmid ) );
mid = midPtr - &primitiveInfo[0]; mid = midPtr - &primitiveInfo[0];
wxASSERT( (mid >= start) && wxASSERT( ( mid >= start ) && ( mid <= end ) );
(mid <= end) );
if( (mid != start) && (mid != end) ) if( (mid != start) && (mid != end) )
break; break;
@ -640,10 +641,8 @@ BVHBuildNode *CBVH_PBRT::recursiveBuild ( std::vector<BVHPrimitiveInfo> &primiti
} }
} }
// Either create leaf or split primitives at selected SAH // Either create leaf or split primitives at selected SAH bucket
// bucket if( ( nPrimitives > m_maxPrimsInNode ) || ( minCost < (float) nPrimitives ) )
if( (nPrimitives > m_maxPrimsInNode) ||
(minCost < (float)nPrimitives) )
{ {
BVHPrimitiveInfo *pmid = BVHPrimitiveInfo *pmid =
std::partition( &primitiveInfo[start], std::partition( &primitiveInfo[start],
@ -654,8 +653,7 @@ BVHBuildNode *CBVH_PBRT::recursiveBuild ( std::vector<BVHPrimitiveInfo> &primiti
centroidBounds ) ); centroidBounds ) );
mid = pmid - &primitiveInfo[0]; mid = pmid - &primitiveInfo[0];
wxASSERT( (mid >= start) && wxASSERT( ( mid >= start ) && ( mid <= end ) );
(mid <= end) );
} }
else else
{ {
@ -744,9 +742,9 @@ BVHBuildNode *CBVH_PBRT::HLBVHBuild( const std::vector<BVHPrimitiveInfo> &primit
{ {
const uint32_t mask = 0b00111111111111000000000000000000; const uint32_t mask = 0b00111111111111000000000000000000;
if( (end == (int)mortonPrims.size()) || if( ( end == (int) mortonPrims.size() )
( (mortonPrims[start].mortonCode & mask) != || ( ( mortonPrims[start].mortonCode & mask )
(mortonPrims[end].mortonCode & mask) ) ) != ( mortonPrims[end].mortonCode & mask ) ) )
{ {
// Add entry to _treeletsToBuild_ for this treelet // Add entry to _treeletsToBuild_ for this treelet
const int numPrimitives = end - start; const int numPrimitives = end - start;
@ -825,8 +823,7 @@ BVHBuildNode *CBVH_PBRT::HLBVHBuild( const std::vector<BVHPrimitiveInfo> &primit
} }
BVHBuildNode *CBVH_PBRT::emitLBVH( BVHBuildNode *CBVH_PBRT::emitLBVH( BVHBuildNode *&buildNodes,
BVHBuildNode *&buildNodes,
const std::vector<BVHPrimitiveInfo> &primitiveInfo, const std::vector<BVHPrimitiveInfo> &primitiveInfo,
MortonPrimitive *mortonPrims, int nPrimitives, int *totalNodes, MortonPrimitive *mortonPrims, int nPrimitives, int *totalNodes,
CONST_VECTOR_OBJECT &orderedPrims, CONST_VECTOR_OBJECT &orderedPrims,
@ -873,9 +870,8 @@ BVHBuildNode *CBVH_PBRT::emitLBVH(
// Advance to next subtree level if there's no LBVH split for this bit // Advance to next subtree level if there's no LBVH split for this bit
if( ( mortonPrims[0].mortonCode & mask ) == if( ( mortonPrims[0].mortonCode & mask ) ==
( mortonPrims[nPrimitives - 1].mortonCode & mask ) ) ( mortonPrims[nPrimitives - 1].mortonCode & mask ) )
return emitLBVH( buildNodes, primitiveInfo, mortonPrims, nPrimitives, return emitLBVH( buildNodes, primitiveInfo, mortonPrims, nPrimitives, totalNodes,
totalNodes, orderedPrims, orderedPrimsOffset, orderedPrims, orderedPrimsOffset, bit - 1 );
bit - 1 );
// Find LBVH split point for this dimension // Find LBVH split point for this dimension
int searchStart = 0; int searchStart = 0;
@ -926,10 +922,8 @@ BVHBuildNode *CBVH_PBRT::emitLBVH(
} }
BVHBuildNode *CBVH_PBRT::buildUpperSAH( BVHBuildNode *CBVH_PBRT::buildUpperSAH( std::vector<BVHBuildNode *> &treeletRoots,
std::vector<BVHBuildNode *> &treeletRoots, int start, int end, int *totalNodes )
int start, int end,
int *totalNodes )
{ {
wxASSERT( totalNodes != NULL ); wxASSERT( totalNodes != NULL );
wxASSERT( start < end ); wxASSERT( start < end );
@ -940,7 +934,6 @@ BVHBuildNode *CBVH_PBRT::buildUpperSAH(
if( nNodes == 1 ) if( nNodes == 1 )
return treeletRoots[start]; return treeletRoots[start];
(*totalNodes)++; (*totalNodes)++;
BVHBuildNode *node = static_cast<BVHBuildNode *>( malloc( sizeof( BVHBuildNode ) ) ); BVHBuildNode *node = static_cast<BVHBuildNode *>( malloc( sizeof( BVHBuildNode ) ) );
@ -997,8 +990,7 @@ BVHBuildNode *CBVH_PBRT::buildUpperSAH(
const float centroid = ( treeletRoots[i]->bounds.Min()[dim] + const float centroid = ( treeletRoots[i]->bounds.Min()[dim] +
treeletRoots[i]->bounds.Max()[dim] ) * treeletRoots[i]->bounds.Max()[dim] ) *
0.5f; 0.5f;
int b = int b = nBuckets * ( (centroid - centroidBounds.Min()[dim] ) /
nBuckets * ( (centroid - centroidBounds.Min()[dim] ) /
(centroidBounds.Max()[dim] - centroidBounds.Min()[dim] ) ); (centroidBounds.Max()[dim] - centroidBounds.Min()[dim] ) );
if( b == nBuckets ) if( b == nBuckets )
@ -1095,7 +1087,7 @@ int CBVH_PBRT::flattenBVHTree( BVHBuildNode *node, uint32_t *offset )
} }
else else
{ {
// Creater interior flattened BVH node // Create interior flattened BVH node
linearNode->axis = node->splitAxis; linearNode->axis = node->splitAxis;
linearNode->nPrimitives = 0; linearNode->nPrimitives = 0;
flattenBVHTree( node->children[0], offset ); flattenBVHTree( node->children[0], offset );
@ -1108,6 +1100,7 @@ int CBVH_PBRT::flattenBVHTree( BVHBuildNode *node, uint32_t *offset )
#define MAX_TODOS 64 #define MAX_TODOS 64
bool CBVH_PBRT::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const bool CBVH_PBRT::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const
{ {
if( !m_nodes ) 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 // Intersect ray with primitives in leaf BVH node
for( int i = 0; i < node->nPrimitives; ++i ) for( int i = 0; i < node->nPrimitives; ++i )
{ {
if( m_primitives[node->primitivesOffset + i]->Intersect( aRay, if( m_primitives[node->primitivesOffset + i]->Intersect( aRay, aHitInfo ) )
aHitInfo ) )
{ {
aHitInfo.m_acc_node_info = nodeNum; aHitInfo.m_acc_node_info = nodeNum;
hit = true; hit = true;
@ -1172,10 +1164,9 @@ bool CBVH_PBRT::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const
return hit; return hit;
} }
// !TODO: this may be optimized
bool CBVH_PBRT::Intersect( const RAY &aRay, /// @todo This may be optimized
HITINFO &aHitInfo, bool CBVH_PBRT::Intersect( const RAY& aRay, HITINFO& aHitInfo, unsigned int aAccNodeInfo ) const
unsigned int aAccNodeInfo ) const
{ {
if( !m_nodes ) if( !m_nodes )
return false; return false;
@ -1204,8 +1195,7 @@ bool CBVH_PBRT::Intersect( const RAY &aRay,
// Intersect ray with primitives in leaf BVH node // Intersect ray with primitives in leaf BVH node
for( int i = 0; i < node->nPrimitives; ++i ) for( int i = 0; i < node->nPrimitives; ++i )
{ {
if( m_primitives[node->primitivesOffset + i]->Intersect( aRay, if( m_primitives[node->primitivesOffset + i]->Intersect( aRay, aHitInfo ) )
aHitInfo ) )
{ {
//aHitInfo.m_acc_node_info = nodeNum; //aHitInfo.m_acc_node_info = nodeNum;
hit = true; hit = true;
@ -1269,8 +1259,8 @@ bool CBVH_PBRT::IntersectP( const RAY &aRay, float aMaxDistance ) const
{ {
const COBJECT *obj = m_primitives[node->primitivesOffset + i]; const COBJECT *obj = m_primitives[node->primitivesOffset + i];
if( obj->GetMaterial()->GetCastShadows() ) if( obj->GetMaterial()->GetCastShadows()
if( obj->IntersectP( aRay, aMaxDistance ) ) && obj->IntersectP( aRay, aMaxDistance ) )
return true; return true;
} }
} }

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -148,8 +148,7 @@ private:
int end, int end,
int *totalNodes ); int *totalNodes );
int flattenBVHTree( BVHBuildNode *node, int flattenBVHTree( BVHBuildNode *node, uint32_t *offset );
uint32_t *offset );
// BVH Private Data // BVH Private Data
const int m_maxPrimsInNode; const int m_maxPrimsInNode;

View File

@ -36,13 +36,12 @@ CGENERICCONTAINER::CGENERICCONTAINER()
m_bbox.Reset(); m_bbox.Reset();
} }
void CGENERICCONTAINER::Clear() void CGENERICCONTAINER::Clear()
{ {
if( !m_objects.empty() ) if( !m_objects.empty() )
{ {
for( LIST_OBJECT::iterator ii = m_objects.begin(); for( LIST_OBJECT::iterator ii = m_objects.begin(); ii != m_objects.end(); ++ii )
ii != m_objects.end();
++ii )
{ {
delete *ii; delete *ii;
*ii = NULL; *ii = NULL;
@ -69,9 +68,7 @@ void CGENERICCONTAINER::ConvertTo( CONST_VECTOR_OBJECT &aOutVector ) const
{ {
unsigned int i = 0; unsigned int i = 0;
for( LIST_OBJECT::const_iterator ii = m_objects.begin(); for( LIST_OBJECT::const_iterator ii = m_objects.begin(); ii != m_objects.end(); ++ii )
ii != m_objects.end();
++ii )
{ {
wxASSERT( (*ii) != NULL ); wxASSERT( (*ii) != NULL );
@ -89,9 +86,7 @@ bool CCONTAINER::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const
bool hitted = false; bool hitted = false;
for( LIST_OBJECT::const_iterator ii = m_objects.begin(); for( LIST_OBJECT::const_iterator ii = m_objects.begin(); ii != m_objects.end(); ++ii )
ii != m_objects.end();
++ii )
{ {
const COBJECT *object = static_cast<const COBJECT *>( *ii ); const COBJECT *object = static_cast<const COBJECT *>( *ii );
@ -105,14 +100,13 @@ bool CCONTAINER::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const
bool CCONTAINER::IntersectP( const RAY &aRay, float aMaxDistance ) 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.Inside( aRay.m_Origin ) )
if( !m_bbox.Intersect( aRay ) ) if( !m_bbox.Intersect( aRay ) )
return false; return false;
*/ */
for( LIST_OBJECT::const_iterator ii = m_objects.begin(); for( LIST_OBJECT::const_iterator ii = m_objects.begin(); ii != m_objects.end(); ++ii )
ii != m_objects.end();
++ii )
{ {
const COBJECT *object = static_cast<const COBJECT *>(*ii); const COBJECT *object = static_cast<const COBJECT *>(*ii);

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -38,12 +38,9 @@ typedef std::list<COBJECT *> LIST_OBJECT;
typedef std::vector<COBJECT *> VECTOR_OBJECT; typedef std::vector<COBJECT *> VECTOR_OBJECT;
typedef std::vector<const COBJECT *> CONST_VECTOR_OBJECT; typedef std::vector<const COBJECT *> CONST_VECTOR_OBJECT;
class CGENERICCONTAINER class CGENERICCONTAINER
{ {
protected:
CBBOX m_bbox;
LIST_OBJECT m_objects;
public: public:
CGENERICCONTAINER(); CGENERICCONTAINER();
@ -51,7 +48,7 @@ public:
void Add( COBJECT *aObject ) void Add( COBJECT *aObject )
{ {
if( aObject ) // Only add if it is a valid pointer if( aObject )
{ {
m_objects.push_back( aObject ); m_objects.push_back( aObject );
m_bbox.Union( aObject->GetBBox() ); m_bbox.Union( aObject->GetBBox() );
@ -69,7 +66,9 @@ public:
virtual bool Intersect( const RAY &aRay, HITINFO &aHitInfo ) const = 0; virtual bool Intersect( const RAY &aRay, HITINFO &aHitInfo ) const = 0;
virtual bool IntersectP( const RAY &aRay, float aMaxDistance ) const = 0; virtual bool IntersectP( const RAY &aRay, float aMaxDistance ) const = 0;
private: protected:
CBBOX m_bbox;
LIST_OBJECT m_objects;
}; };

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -35,10 +35,6 @@
#include <wx/debug.h> #include <wx/debug.h>
// /////////////////////////////////////////////////////////////////////////////
// CGENERICCONTAINER2
// /////////////////////////////////////////////////////////////////////////////
CGENERICCONTAINER2D::CGENERICCONTAINER2D( OBJECT2D_TYPE aObjType ) CGENERICCONTAINER2D::CGENERICCONTAINER2D( OBJECT2D_TYPE aObjType )
{ {
m_bbox.Reset(); m_bbox.Reset();
@ -67,16 +63,13 @@ CGENERICCONTAINER2D::~CGENERICCONTAINER2D()
} }
// /////////////////////////////////////////////////////////////////////////////
// CCONTAINER2D
// /////////////////////////////////////////////////////////////////////////////
CCONTAINER2D::CCONTAINER2D() : CGENERICCONTAINER2D( OBJECT2D_TYPE::CONTAINER ) CCONTAINER2D::CCONTAINER2D() : CGENERICCONTAINER2D( OBJECT2D_TYPE::CONTAINER )
{ {
} }
/// @todo Determine what to do with this commented out code.
/* /*
bool CCONTAINER2D::Intersects( const CBBOX2D &aBBox ) const bool CCONTAINER2D::Intersects( const CBBOX2D &aBBox ) const
@ -149,22 +142,17 @@ bool CCONTAINER2D::IsPointInside( const SFVEC2F &aPoint ) const
void CCONTAINER2D::GetListObjectsIntersects( const CBBOX2D & aBBox, void CCONTAINER2D::GetListObjectsIntersects( const CBBOX2D & aBBox,
CONST_LIST_OBJECT2D &aOutList ) const CONST_LIST_OBJECT2D &aOutList ) const
{ {
// !TODO: /// @todo Determine what to do with this code.
} }
bool CCONTAINER2D::IntersectAny( const RAYSEG2D &aSegRay ) const bool CCONTAINER2D::IntersectAny( const RAYSEG2D &aSegRay ) const
{ {
// !TODO: /// @todo Determine what what needs done because someone wrote TODO here.
return false; return false;
} }
// /////////////////////////////////////////////////////////////////////////////
// CBVHCONTAINER2D
// /////////////////////////////////////////////////////////////////////////////
CBVHCONTAINER2D::CBVHCONTAINER2D() : CGENERICCONTAINER2D( OBJECT2D_TYPE::BVHCONTAINER ) CBVHCONTAINER2D::CBVHCONTAINER2D() : CGENERICCONTAINER2D( OBJECT2D_TYPE::BVHCONTAINER )
{ {
m_isInitialized = false; m_isInitialized = false;
@ -173,6 +161,8 @@ CBVHCONTAINER2D::CBVHCONTAINER2D() : CGENERICCONTAINER2D( OBJECT2D_TYPE::BVHCONT
m_Tree = NULL; m_Tree = NULL;
} }
/// @todo Determine what to do with this commented out code.
/* /*
bool CBVHCONTAINER2D::Intersects( const CBBOX2D &aBBox ) const bool CBVHCONTAINER2D::Intersects( const CBBOX2D &aBBox ) const
{ {
@ -246,12 +236,14 @@ bool CBVHCONTAINER2D::IsPointInside( const SFVEC2F &aPoint ) const
} }
*/ */
void CBVHCONTAINER2D::Clear() void CBVHCONTAINER2D::Clear()
{ {
CGENERICCONTAINER2D::Clear(); CGENERICCONTAINER2D::Clear();
destroy(); destroy();
} }
void CBVHCONTAINER2D::destroy() void CBVHCONTAINER2D::destroy()
{ {
for( std::list<BVH_CONTAINER_NODE_2D *>::iterator ii = m_elements_to_delete.begin(); for( std::list<BVH_CONTAINER_NODE_2D *>::iterator ii = m_elements_to_delete.begin();
@ -260,6 +252,7 @@ void CBVHCONTAINER2D::destroy()
{ {
delete *ii; delete *ii;
} }
m_elements_to_delete.clear(); m_elements_to_delete.clear();
m_Tree = nullptr; m_Tree = nullptr;
m_isInitialized = false; m_isInitialized = false;
@ -292,9 +285,7 @@ void CBVHCONTAINER2D::BuildBVH()
m_elements_to_delete.push_back( m_Tree ); m_elements_to_delete.push_back( m_Tree );
m_Tree->m_BBox = m_bbox; m_Tree->m_BBox = m_bbox;
for( LIST_OBJECT2D::const_iterator ii = m_objects.begin(); for( LIST_OBJECT2D::const_iterator ii = m_objects.begin(); ii != m_objects.end(); ++ii )
ii != m_objects.end();
++ii )
{ {
m_Tree->m_LeafList.push_back( static_cast<const COBJECT2D *>( *ii ) ); m_Tree->m_LeafList.push_back( static_cast<const COBJECT2D *>( *ii ) );
} }
@ -310,22 +301,24 @@ void CBVHCONTAINER2D::BuildBVH()
// "Split in the middle of the longest Axis" // "Split in the middle of the longest Axis"
// "Creates a binary tree with Top-Down approach. // "Creates a binary tree with Top-Down approach.
// Fastest BVH building, but least [speed] accuracy." // Fastest BVH building, but least [speed] accuracy."
static bool sortByCentroid_X( const COBJECT2D *a, const COBJECT2D *b ) static bool sortByCentroid_X( const COBJECT2D *a, const COBJECT2D *b )
{ {
return a->GetCentroid()[0] < b->GetCentroid()[0]; return a->GetCentroid()[0] < b->GetCentroid()[0];
} }
static bool sortByCentroid_Y( const COBJECT2D *a, const COBJECT2D *b ) static bool sortByCentroid_Y( const COBJECT2D *a, const COBJECT2D *b )
{ {
return a->GetCentroid()[0] < b->GetCentroid()[0]; return a->GetCentroid()[0] < b->GetCentroid()[0];
} }
static bool sortByCentroid_Z( const COBJECT2D *a, const COBJECT2D *b ) static bool sortByCentroid_Z( const COBJECT2D *a, const COBJECT2D *b )
{ {
return a->GetCentroid()[0] < b->GetCentroid()[0]; return a->GetCentroid()[0] < b->GetCentroid()[0];
} }
void CBVHCONTAINER2D::recursiveBuild_MIDDLE_SPLIT( BVH_CONTAINER_NODE_2D *aNodeParent ) void CBVHCONTAINER2D::recursiveBuild_MIDDLE_SPLIT( BVH_CONTAINER_NODE_2D *aNodeParent )
{ {
wxASSERT( aNodeParent != NULL ); wxASSERT( aNodeParent != NULL );
@ -345,7 +338,7 @@ void CBVHCONTAINER2D::recursiveBuild_MIDDLE_SPLIT( BVH_CONTAINER_NODE_2D *aNodeP
leftNode->m_LeafList.clear(); leftNode->m_LeafList.clear();
rightNode->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(); const unsigned int axis_to_split = aNodeParent->m_BBox.MaxDimension();
// Divide the objects // Divide the objects
@ -454,6 +447,7 @@ bool CBVHCONTAINER2D::recursiveIntersectAny( const BVH_CONTAINER_NODE_2D *aNode,
return false; return false;
} }
void CBVHCONTAINER2D::GetListObjectsIntersects( const CBBOX2D &aBBox, void CBVHCONTAINER2D::GetListObjectsIntersects( const CBBOX2D &aBBox,
CONST_LIST_OBJECT2D &aOutList ) const CONST_LIST_OBJECT2D &aOutList ) const
{ {

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -40,10 +40,6 @@ typedef std::list<const COBJECT2D *> CONST_LIST_OBJECT2D;
class CGENERICCONTAINER2D class CGENERICCONTAINER2D
{ {
protected:
CBBOX2D m_bbox;
LIST_OBJECT2D m_objects;
public: public:
explicit CGENERICCONTAINER2D( OBJECT2D_TYPE aObjType ); explicit CGENERICCONTAINER2D( OBJECT2D_TYPE aObjType );
@ -51,7 +47,7 @@ public:
void Add( COBJECT2D *aObject ) void Add( COBJECT2D *aObject )
{ {
if( aObject ) // Only add if it is a valid pointer if( aObject )
{ {
std::lock_guard<std::mutex> lock( m_lock ); std::lock_guard<std::mutex> lock( m_lock );
m_objects.push_back( aObject ); m_objects.push_back( aObject );
@ -69,20 +65,26 @@ public:
const LIST_OBJECT2D &GetList() const { return m_objects; } const LIST_OBJECT2D &GetList() const { return m_objects; }
/** /**
* @brief GetListObjectsIntersects - Get a list of objects that intersects a bbox * Get a list of objects that intersects a bounding box.
* @param aBBox - a bbox to make the query *
* @param aOutList - A list of objects that intersects the bbox * @param aBBox The bounding box to test.
* @param aOutList The list of objects that intersects the bounding box.
*/ */
virtual void GetListObjectsIntersects( const CBBOX2D & aBBox, virtual void GetListObjectsIntersects( const CBBOX2D & aBBox,
CONST_LIST_OBJECT2D &aOutList ) const = 0; CONST_LIST_OBJECT2D &aOutList ) const = 0;
/** /**
* @brief IntersectAny - Intersect and check if a segment ray hits a object or is inside it * 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 * @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; virtual bool IntersectAny( const RAYSEG2D &aSegRay ) const = 0;
protected:
CBBOX2D m_bbox;
LIST_OBJECT2D m_objects;
private: private:
std::mutex m_lock; std::mutex m_lock;
}; };
@ -121,11 +123,13 @@ public:
void Clear() override; void Clear() override;
private: // Imported from CGENERICCONTAINER2D
bool m_isInitialized; void GetListObjectsIntersects( const CBBOX2D & aBBox,
std::list<BVH_CONTAINER_NODE_2D *> m_elements_to_delete; CONST_LIST_OBJECT2D &aOutList ) const override;
BVH_CONTAINER_NODE_2D *m_Tree;
bool IntersectAny( const RAYSEG2D &aSegRay ) const override;
private:
void destroy(); void destroy();
void recursiveBuild_MIDDLE_SPLIT( BVH_CONTAINER_NODE_2D *aNodeParent ); void recursiveBuild_MIDDLE_SPLIT( BVH_CONTAINER_NODE_2D *aNodeParent );
void recursiveGetListObjectsIntersects( const BVH_CONTAINER_NODE_2D *aNode, void recursiveGetListObjectsIntersects( const BVH_CONTAINER_NODE_2D *aNode,
@ -134,13 +138,10 @@ private:
bool recursiveIntersectAny( const BVH_CONTAINER_NODE_2D *aNode, bool recursiveIntersectAny( const BVH_CONTAINER_NODE_2D *aNode,
const RAYSEG2D &aSegRay ) const; const RAYSEG2D &aSegRay ) const;
public: bool m_isInitialized;
std::list<BVH_CONTAINER_NODE_2D *> 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_ #endif // _CCONTAINER2D_H_

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -158,7 +158,6 @@ bool C3D_RENDER_RAYTRACING::Redraw(
bool requestRedraw = false; bool requestRedraw = false;
// Initialize openGL if need // Initialize openGL if need
// /////////////////////////////////////////////////////////////////////////
if( !m_is_opengl_initialized ) if( !m_is_opengl_initialized )
{ {
if( !initializeOpenGL() ) if( !initializeOpenGL() )
@ -176,7 +175,6 @@ bool C3D_RENDER_RAYTRACING::Redraw(
std::unique_ptr<BUSY_INDICATOR> busy = CreateBusyIndicator(); std::unique_ptr<BUSY_INDICATOR> busy = CreateBusyIndicator();
// Reload board if it was requested // Reload board if it was requested
// /////////////////////////////////////////////////////////////////////////
if( m_reloadRequested ) if( m_reloadRequested )
{ {
if( aStatusReporter ) if( aStatusReporter )
@ -189,7 +187,6 @@ bool C3D_RENDER_RAYTRACING::Redraw(
// Recalculate constants if windows size was changed // Recalculate constants if windows size was changed
// /////////////////////////////////////////////////////////////////////////
if( m_windowSize != m_oldWindowsSize ) if( m_windowSize != m_oldWindowsSize )
{ {
m_oldWindowsSize = m_windowSize; m_oldWindowsSize = m_windowSize;
@ -201,7 +198,6 @@ bool C3D_RENDER_RAYTRACING::Redraw(
// Clear buffers // Clear buffers
// /////////////////////////////////////////////////////////////////////////
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glClearDepth( 1.0f ); glClearDepth( 1.0f );
glClearStencil( 0x00 ); glClearStencil( 0x00 );
@ -224,7 +220,6 @@ bool C3D_RENDER_RAYTRACING::Redraw(
m_rt_render_state = RT_RENDER_STATE_MAX; // Set to an invalid state, m_rt_render_state = RT_RENDER_STATE_MAX; // Set to an invalid state,
// so it will restart again latter // so it will restart again latter
// This will only render if need, otherwise it will redraw the PBO on the screen again // This will only render if need, otherwise it will redraw the PBO on the screen again
if( aIsMoving || was_camera_changed ) if( aIsMoving || was_camera_changed )
{ {
@ -430,6 +425,7 @@ void C3D_RENDER_RAYTRACING::rt_render_tracing( GLubyte* ptrPBO ,
} }
} }
#ifdef USE_SRGB_SPACE #ifdef USE_SRGB_SPACE
// This should be removed in future when the KiCad support a greater version of // 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 #define SRGB_GAMA 2.4f
// This function implements the conversion from linear RGB to sRGB // This function implements the conversion from linear RGB to sRGB
// https://github.com/g-truc/glm/blob/master/glm/gtc/color_space.inl#L12 // https://github.com/g-truc/glm/blob/master/glm/gtc/color_space.inl#L12
static SFVEC3F convertLinearToSRGB( const SFVEC3F &aRGBcolor ) static SFVEC3F convertLinearToSRGB( const SFVEC3F &aRGBcolor )
@ -444,20 +441,20 @@ static SFVEC3F convertLinearToSRGB( const SFVEC3F &aRGBcolor )
const float gammaCorrection = 1.0f / SRGB_GAMA; const float gammaCorrection = 1.0f / SRGB_GAMA;
const SFVEC3F clampedColor = glm::clamp( aRGBcolor, SFVEC3F(0.0f), SFVEC3F(1.0f) ); const SFVEC3F clampedColor = glm::clamp( aRGBcolor, SFVEC3F(0.0f), SFVEC3F(1.0f) );
return glm::mix( return glm::mix( glm::pow( clampedColor, SFVEC3F(gammaCorrection) ) * 1.055f - 0.055f,
glm::pow( clampedColor, SFVEC3F(gammaCorrection) ) * 1.055f - 0.055f,
clampedColor * 12.92f, clampedColor * 12.92f,
glm::lessThan( clampedColor, SFVEC3F(0.0031308f) ) ); glm::lessThan( clampedColor, SFVEC3F(0.0031308f) ) );
} }
// This function implements the conversion from sRGB to linear RGB // This function implements the conversion from sRGB to linear RGB
// https://github.com/g-truc/glm/blob/master/glm/gtc/color_space.inl#L35 // https://github.com/g-truc/glm/blob/master/glm/gtc/color_space.inl#L35
SFVEC3F ConvertSRGBToLinear( const SFVEC3F &aSRGBcolor ) SFVEC3F ConvertSRGBToLinear( const SFVEC3F &aSRGBcolor )
{ {
const float gammaCorrection = SRGB_GAMA; const float gammaCorrection = SRGB_GAMA;
return glm::mix( return glm::mix( glm::pow( (aSRGBcolor + SFVEC3F(0.055f)) *
glm::pow( (aSRGBcolor + SFVEC3F(0.055f)) * SFVEC3F(0.94786729857819905213270142180095f), SFVEC3F(0.94786729857819905213270142180095f),
SFVEC3F(gammaCorrection) ), SFVEC3F(gammaCorrection) ),
aSRGBcolor * SFVEC3F(0.07739938080495356037151702786378f), aSRGBcolor * SFVEC3F(0.07739938080495356037151702786378f),
glm::lessThanEqual( aSRGBcolor, SFVEC3F(0.04045f) ) ); glm::lessThanEqual( aSRGBcolor, SFVEC3F(0.04045f) ) );
@ -465,10 +462,10 @@ SFVEC3F ConvertSRGBToLinear( const SFVEC3F &aSRGBcolor )
#endif #endif
void C3D_RENDER_RAYTRACING::rt_final_color( GLubyte *ptrPBO, const SFVEC3F &rgbColor, void C3D_RENDER_RAYTRACING::rt_final_color( GLubyte *ptrPBO, const SFVEC3F &rgbColor,
bool applyColorSpaceConversion ) bool applyColorSpaceConversion )
{ {
SFVEC3F color = rgbColor; SFVEC3F color = rgbColor;
#ifdef USE_SRGB_SPACE #ifdef USE_SRGB_SPACE
@ -570,15 +567,14 @@ void C3D_RENDER_RAYTRACING::rt_trace_AA_packet( const SFVEC3F *aBgColorY,
unsigned int nodex1y1 = 0; unsigned int nodex1y1 = 0;
if( ((x < (RAYPACKET_DIM - 1)) && if( ( ( x < ( RAYPACKET_DIM - 1 ) ) && ( y < ( RAYPACKET_DIM - 1 ) ) ) )
(y < (RAYPACKET_DIM - 1))) )
nodex1y1 = aHitPck_X0Y0[idx1y1].m_HitInfo.m_acc_node_info; nodex1y1 = aHitPck_X0Y0[idx1y1].m_HitInfo.m_acc_node_info;
// If all notes are equal we assume there was no change on the object hits.
if( ((nodex0y0 == nodex1y0) || (nodex1y0 == 0)) && // 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 == nodex0y1 ) || ( nodex0y1 == 0 ) )
((nodex0y0 == nodex1y1) || (nodex1y1 == 0)) && && ( ( nodex0y0 == nodex1y1 ) || ( nodex1y1 == 0 ) )
(nodex0y0 == node_AA_x0y0) ) && ( nodex0y0 == node_AA_x0y0 ) )
{ {
// Option 1 // Option 1
// This option will give a very good quality on reflections (slow) // 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 // Option 3
// Use same color // Use same color
} }
else else
{ {
@ -640,7 +635,8 @@ void C3D_RENDER_RAYTRACING::rt_trace_AA_packet( const SFVEC3F *aBgColorY,
if( hitted ) if( hitted )
{ {
// If we got any result, shade it // 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 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 // It was missed the 'last nodes' so, trace a ray from the beginning
if( m_accelerator->Intersect( rayAA, hitAA ) ) 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 #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 // Initialize ray packets
// /////////////////////////////////////////////////////////////////////////
const SFVEC2UI &blockPos = m_blockPositions[iBlock]; const SFVEC2UI &blockPos = m_blockPositions[iBlock];
const SFVEC2I blockPosI = SFVEC2I( blockPos.x + m_xoffset, const SFVEC2I blockPosI = SFVEC2I( blockPos.x + m_xoffset,
blockPos.y + m_yoffset ); blockPos.y + m_yoffset );
@ -676,7 +673,6 @@ void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO ,
HITINFO_PACKET_init( hitPacket_X0Y0 ); HITINFO_PACKET_init( hitPacket_X0Y0 );
// Calculate background gradient color // Calculate background gradient color
// /////////////////////////////////////////////////////////////////////////
SFVEC3F bgColor[RAYPACKET_DIM];// Store a vertical gradient color SFVEC3F bgColor[RAYPACKET_DIM];// Store a vertical gradient color
for( unsigned int y = 0; y < RAYPACKET_DIM; ++y ) 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) // Intersect ray packets (calculate the intersection with rays and objects)
// /////////////////////////////////////////////////////////////////////////
if( !m_accelerator->Intersect( blockPacket, hitPacket_X0Y0 ) ) if( !m_accelerator->Intersect( blockPacket, hitPacket_X0Y0 ) )
{ {
// If block is empty then set shades and continue // If block is empty then set shades and continue
if( m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING ) ) 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 // If post processing is enabled, it will not reflect the final result
// (as the final color will be computed on post processing) // (as the final color will be computed on post processing)
// but it is used for report progress // but it is used for report progress
const bool isFinalColor = !m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING ); const bool isFinalColor = !m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_POST_PROCESSING );
for( unsigned int y = 0; y < RAYPACKET_DIM; ++y ) for( unsigned int y = 0; y < RAYPACKET_DIM; ++y )
@ -740,11 +733,9 @@ void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO ,
return; return;
} }
SFVEC3F hitColor_X0Y0[RAYPACKET_RAYS_PER_PACKET]; SFVEC3F hitColor_X0Y0[RAYPACKET_RAYS_PER_PACKET];
// Shade original (0, 0) hits ("paint" the intersected objects) // Shade original (0, 0) hits ("paint" the intersected objects)
// /////////////////////////////////////////////////////////////////////////
rt_shades_packet( bgColor, rt_shades_packet( bgColor,
blockPacket.m_ray, blockPacket.m_ray,
hitPacket_X0Y0, hitPacket_X0Y0,
@ -755,9 +746,7 @@ void C3D_RENDER_RAYTRACING::rt_render_trace_block( GLubyte *ptrPBO ,
{ {
SFVEC3F hitColor_AA_X1Y1[RAYPACKET_RAYS_PER_PACKET]; SFVEC3F hitColor_AA_X1Y1[RAYPACKET_RAYS_PER_PACKET];
// Intersect one blockPosI + (0.5, 0.5) used for anti aliasing calculation // Intersect one blockPosI + (0.5, 0.5) used for anti aliasing calculation
// /////////////////////////////////////////////////////////////////////////
HITINFO_PACKET hitPacket_AA_X1Y1[RAYPACKET_RAYS_PER_PACKET]; HITINFO_PACKET hitPacket_AA_X1Y1[RAYPACKET_RAYS_PER_PACKET];
HITINFO_PACKET_init( hitPacket_AA_X1Y1 ); 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_X0Y1[RAYPACKET_RAYS_PER_PACKET];
RAY blockRayPck_AA_X1Y1_half[RAYPACKET_RAYS_PER_PACKET]; RAY blockRayPck_AA_X1Y1_half[RAYPACKET_RAYS_PER_PACKET];
RAYPACKET_InitRays_with2DDisplacement( m_camera, RAYPACKET_InitRays_with2DDisplacement(
m_camera,
(SFVEC2F) blockPosI + SFVEC2F( 0.5f - DISP_FACTOR, DISP_FACTOR ), (SFVEC2F) blockPosI + SFVEC2F( 0.5f - DISP_FACTOR, DISP_FACTOR ),
SFVEC2F(DISP_FACTOR, DISP_FACTOR), // Displacement random factor SFVEC2F( DISP_FACTOR, DISP_FACTOR ), blockRayPck_AA_X1Y0 );
blockRayPck_AA_X1Y0 );
RAYPACKET_InitRays_with2DDisplacement( m_camera, RAYPACKET_InitRays_with2DDisplacement(
m_camera,
(SFVEC2F) blockPosI + SFVEC2F( DISP_FACTOR, 0.5f - DISP_FACTOR ), (SFVEC2F) blockPosI + SFVEC2F( DISP_FACTOR, 0.5f - DISP_FACTOR ),
SFVEC2F(DISP_FACTOR, DISP_FACTOR), // Displacement random factor SFVEC2F( DISP_FACTOR, DISP_FACTOR ), blockRayPck_AA_X0Y1 );
blockRayPck_AA_X0Y1 );
RAYPACKET_InitRays_with2DDisplacement( m_camera, RAYPACKET_InitRays_with2DDisplacement(
m_camera,
(SFVEC2F) blockPosI + SFVEC2F( 0.25f - DISP_FACTOR, 0.25f - DISP_FACTOR ), (SFVEC2F) blockPosI + SFVEC2F( 0.25f - DISP_FACTOR, 0.25f - DISP_FACTOR ),
SFVEC2F(DISP_FACTOR, DISP_FACTOR), // Displacement random factor SFVEC2F( DISP_FACTOR, DISP_FACTOR ), blockRayPck_AA_X1Y1_half );
blockRayPck_AA_X1Y1_half );
rt_trace_AA_packet( bgColor, rt_trace_AA_packet( bgColor,
hitPacket_X0Y0, hitPacket_AA_X1Y1, 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 // 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; 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<size_t> threadsFinished( 0 ); std::atomic<size_t> threadsFinished( 0 );
size_t parallelThreadCount = std::max<size_t>( std::thread::hardware_concurrency(), 2 ); size_t parallelThreadCount = std::max<size_t>( std::thread::hardware_concurrency(), 2 );
for( size_t ii = 0; ii < parallelThreadCount; ++ii ) for( size_t ii = 0; ii < parallelThreadCount; ++ii )
{ {
std::thread t = std::thread( [&]() 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 ) ); const SFVEC3F bluredShadeColor = m_postshader_ssao.Blur( SFVEC2I( x, y ) );
#ifdef USE_SRGB_SPACE #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 #else
const SFVEC3F originColor = m_postshader_ssao.GetColorAtNotProtected( SFVEC2I( x,y ) ); const SFVEC3F originColor =
m_postshader_ssao.GetColorAtNotProtected( SFVEC2I( x, y ) );
#endif #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 ); 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 ) while( threadsFinished < parallelThreadCount )
std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) ); std::this_thread::sleep_for( std::chrono::milliseconds( 10 ) );
// Debug code // Debug code
//m_postshader_ssao.DebugBuffersOutputAsImages(); //m_postshader_ssao.DebugBuffersOutputAsImages();
} }
@ -1034,6 +1023,7 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
size_t parallelThreadCount = std::min<size_t>( size_t parallelThreadCount = std::min<size_t>(
std::max<size_t>( std::thread::hardware_concurrency(), 2 ), std::max<size_t>( std::thread::hardware_concurrency(), 2 ),
m_blockPositions.size() ); m_blockPositions.size() );
for( size_t ii = 0; ii < parallelThreadCount; ++ii ) for( size_t ii = 0; ii < parallelThreadCount; ++ii )
{ {
std::thread t = std::thread( [&]() 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 ) 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) + bgColor[y] = (SFVEC3F) m_boardAdapter.m_BgColorTop * SFVEC3F( posYfactor )
(SFVEC3F)m_boardAdapter.m_BgColorBot * ( SFVEC3F( 1.0f) - SFVEC3F( posYfactor) ); + (SFVEC3F) m_boardAdapter.m_BgColorBot
* ( SFVEC3F( 1.0f ) - SFVEC3F( posYfactor ) );
} }
CCOLORRGB hitColorShading[RAYPACKET_RAYS_PER_PACKET]; 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 ) for( unsigned int y = 0; y < (RAYPACKET_DIM - 1); ++y )
{ {
const SFVEC3F bgColorY = bgColor[y]; const SFVEC3F bgColorY = bgColor[y];
const CCOLORRGB bgColorYRGB = CCOLORRGB( bgColorY ); 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)); const unsigned int iRB = ((x + 1) + RAYPACKET_DIM * (y + 1));
// !TODO: skip when there are no hits // !TODO: skip when there are no hits
const CCOLORRGB &cLT = hitColorShading[ iLT ]; const CCOLORRGB &cLT = hitColorShading[ iLT ];
const CCOLORRGB &cRT = hitColorShading[ iRT ]; const CCOLORRGB &cRT = hitColorShading[ iRT ];
const CCOLORRGB &cLB = hitColorShading[ iLB ]; const CCOLORRGB &cLB = hitColorShading[ iLB ];
const CCOLORRGB &cRB = hitColorShading[ iRB ]; const CCOLORRGB &cRB = hitColorShading[ iRB ];
// Trace and shade cC // Trace and shade cC
// /////////////////////////////////////////////////////////////
CCOLORRGB cC = bgColorYRGB; CCOLORRGB cC = bgColorYRGB;
const SFVEC3F &oriLT = blockPacket.m_ray[ iLT ].m_Origin; 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; const unsigned int nodeRB = hitPacket[ iRB ].m_HitInfo.m_acc_node_info;
if( nodeLT != 0 ) if( nodeLT != 0 )
hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo, nodeLT ); hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo,
nodeLT );
if( ( nodeRT != 0 ) && if( ( nodeRT != 0 ) &&
( nodeRT != nodeLT ) ) ( nodeRT != nodeLT ) )
hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo, nodeRT ); hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo,
nodeRT );
if( ( nodeLB != 0 ) && if( ( nodeLB != 0 ) &&
( nodeLB != nodeLT ) && ( nodeLB != nodeLT ) &&
( nodeLB != nodeRT ) ) ( nodeLB != nodeRT ) )
hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo, nodeLB ); hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo,
nodeLB );
if( ( nodeRB != 0 ) && if( ( nodeRB != 0 ) &&
( nodeRB != nodeLB ) && ( nodeRB != nodeLB ) &&
( nodeRB != nodeLT ) && ( nodeRB != nodeLT ) &&
( nodeRB != nodeRT ) ) ( nodeRB != nodeRT ) )
hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo, nodeRB ); hittedC |= m_accelerator->Intersect( centerRay, centerHitInfo,
nodeRB );
if( hittedC ) if( hittedC )
cC = CCOLORRGB( shadeHit( bgColorY, centerRay, centerHitInfo, false, 0, false ) ); {
cC = CCOLORRGB( shadeHit( bgColorY, centerRay, centerHitInfo,
false, 0, false ) );
}
else else
{ {
centerHitInfo.m_tHit = std::numeric_limits<float>::infinity(); centerHitInfo.m_tHit = std::numeric_limits<float>::infinity();
@ -1278,11 +1273,11 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
} }
} }
else else
{
cLRT = cLRB_old[x]; cLRT = cLRB_old[x];
}
// Trace and shade cLTB // Trace and shade cLTB
// /////////////////////////////////////////////////////////////
CCOLORRGB cLTB = bgColorYRGB; CCOLORRGB cLTB = bgColorYRGB;
if( x == 0 ) if( x == 0 )
@ -1309,16 +1304,19 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
hitInfoLTB.m_HitNormal = hitInfoLTB.m_HitNormal =
glm::normalize( ( hitPacket[ iLT ].m_HitInfo.m_HitNormal + glm::normalize( ( hitPacket[ iLT ].m_HitInfo.m_HitNormal +
hitPacket[ iLB ].m_HitInfo.m_HitNormal ) * 0.5f ); 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) ); cLTB = BlendColor( cLTB, BlendColor( cLT, cLB) );
} }
else else
{ {
if( hitPacket[ iLT ].m_hitresult || // If any hits
hitPacket[ iLB ].m_hitresult ) // 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 nodeLT =
const unsigned int nodeLB = hitPacket[ iLB ].m_HitInfo.m_acc_node_info; hitPacket[ iLT ].m_HitInfo.m_acc_node_info;
const unsigned int nodeLB =
hitPacket[ iLB ].m_HitInfo.m_acc_node_info;
bool hittedLTB = false; bool hittedLTB = false;
@ -1356,11 +1354,11 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
} }
} }
else else
{
cLTB = cRTB_old; cLTB = cRTB_old;
}
// Trace and shade cRTB // Trace and shade cRTB
// /////////////////////////////////////////////////////////////
CCOLORRGB cRTB = bgColorYRGB; CCOLORRGB cRTB = bgColorYRGB;
// Trace the center ray // Trace the center ray
@ -1371,8 +1369,7 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
HITINFO hitInfoRTB; HITINFO hitInfoRTB;
hitInfoRTB.m_tHit = std::numeric_limits<float>::infinity(); hitInfoRTB.m_tHit = std::numeric_limits<float>::infinity();
if( hitPacket[ iRT ].m_hitresult && if( hitPacket[ iRT ].m_hitresult && hitPacket[ iRB ].m_hitresult &&
hitPacket[ iRB ].m_hitresult &&
( hitPacket[ iRT ].m_HitInfo.pHitObject == ( hitPacket[ iRT ].m_HitInfo.pHitObject ==
hitPacket[ iRB ].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 + glm::normalize( ( hitPacket[ iRT ].m_HitInfo.m_HitNormal +
hitPacket[ iRB ].m_HitInfo.m_HitNormal ) * 0.5f ); 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) ); cRTB = BlendColor( cRTB, BlendColor( cRT, cRB) );
} }
else else
{ {
if( hitPacket[ iRT ].m_hitresult || // If any hits
hitPacket[ iRB ].m_hitresult ) // 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 nodeRT =
const unsigned int nodeRB = hitPacket[ iRB ].m_HitInfo.m_acc_node_info; hitPacket[ iRT ].m_HitInfo.m_acc_node_info;
const unsigned int nodeRB =
hitPacket[ iRB ].m_HitInfo.m_acc_node_info;
bool hittedRTB = false; bool hittedRTB = false;
if( nodeRT != 0 ) if( nodeRT != 0 )
hittedRTB |= m_accelerator->Intersect( rayRTB, hitInfoRTB, nodeRT ); hittedRTB |= m_accelerator->Intersect( rayRTB, hitInfoRTB,
nodeRT );
if( ( nodeRB != 0 ) && if( ( nodeRB != 0 ) &&
( nodeRB != nodeRT ) ) ( nodeRB != nodeRT ) )
hittedRTB |= m_accelerator->Intersect( rayRTB, hitInfoRTB, nodeRB ); hittedRTB |= m_accelerator->Intersect( rayRTB, hitInfoRTB,
nodeRB );
if( hittedRTB ) if( hittedRTB )
{
cRTB = CCOLORRGB( shadeHit( bgColorY, cRTB = CCOLORRGB( shadeHit( bgColorY,
rayRTB, rayRTB,
hitInfoRTB, hitInfoRTB,
false, false,
0, 0,
false) ); false) );
}
else else
{ {
hitInfoRTB.m_tHit = std::numeric_limits<float>::infinity(); hitInfoRTB.m_tHit = std::numeric_limits<float>::infinity();
@ -1429,9 +1433,7 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
cRTB_old = cRTB; cRTB_old = cRTB;
// Trace and shade cLRB // Trace and shade cLRB
// /////////////////////////////////////////////////////////////
CCOLORRGB cLRB = bgColorYRGB; CCOLORRGB cLRB = bgColorYRGB;
const SFVEC3F &oriLB = blockPacket.m_ray[ iLB ].m_Origin; const SFVEC3F &oriLB = blockPacket.m_ray[ iLB ].m_Origin;
@ -1445,8 +1447,7 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
HITINFO hitInfoLRB; HITINFO hitInfoLRB;
hitInfoLRB.m_tHit = std::numeric_limits<float>::infinity(); hitInfoLRB.m_tHit = std::numeric_limits<float>::infinity();
if( hitPacket[ iLB ].m_hitresult && if( hitPacket[ iLB ].m_hitresult && hitPacket[ iRB ].m_hitresult &&
hitPacket[ iRB ].m_hitresult &&
( hitPacket[ iLB ].m_HitInfo.pHitObject == ( hitPacket[ iLB ].m_HitInfo.pHitObject ==
hitPacket[ iRB ].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 + glm::normalize( ( hitPacket[ iLB ].m_HitInfo.m_HitNormal +
hitPacket[ iRB ].m_HitInfo.m_HitNormal ) * 0.5f ); 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) ); cLRB = BlendColor( cLRB, BlendColor( cLB, cRB) );
} }
else else
{ {
if( hitPacket[ iLB ].m_hitresult || // If any hits
hitPacket[ iRB ].m_hitresult ) // 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 nodeLB =
const unsigned int nodeRB = hitPacket[ iRB ].m_HitInfo.m_acc_node_info; hitPacket[ iLB ].m_HitInfo.m_acc_node_info;
const unsigned int nodeRB =
hitPacket[ iRB ].m_HitInfo.m_acc_node_info;
bool hittedLRB = false; bool hittedLRB = false;
if( nodeLB != 0 ) if( nodeLB != 0 )
hittedLRB |= m_accelerator->Intersect( rayLRB, hitInfoLRB, nodeLB ); hittedLRB |= m_accelerator->Intersect( rayLRB, hitInfoLRB,
nodeLB );
if( ( nodeRB != 0 ) && if( ( nodeRB != 0 ) && ( nodeRB != nodeLB ) )
( nodeRB != nodeLB ) ) hittedLRB |= m_accelerator->Intersect( rayLRB, hitInfoLRB,
hittedLRB |= m_accelerator->Intersect( rayLRB, hitInfoLRB, nodeRB ); nodeRB );
if( hittedLRB ) if( hittedLRB )
cLRB = CCOLORRGB( shadeHit( bgColorY, rayLRB, hitInfoLRB, false, 0, false ) ); {
cLRB = CCOLORRGB( shadeHit( bgColorY, rayLRB, hitInfoLRB,
false, 0, false ) );
}
else else
{ {
hitInfoLRB.m_tHit = std::numeric_limits<float>::infinity(); hitInfoLRB.m_tHit = std::numeric_limits<float>::infinity();
@ -1498,9 +1506,7 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
cLRB_old[x] = cLRB; cLRB_old[x] = cLRB;
// Trace and shade cLTC // Trace and shade cLTC
// /////////////////////////////////////////////////////////////
CCOLORRGB cLTC = BlendColor( cLT , cC ); CCOLORRGB cLTC = BlendColor( cLT , cC );
if( hitPacket[ iLT ].m_hitresult || hittedC ) if( hitPacket[ iLT ].m_hitresult || hittedC )
@ -1517,18 +1523,17 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
if( hittedC ) if( hittedC )
hitted = centerHitInfo.pHitObject->Intersect( rayLTC, hitInfoLTC ); hitted = centerHitInfo.pHitObject->Intersect( rayLTC, hitInfoLTC );
else else if( hitPacket[ iLT ].m_hitresult )
if( hitPacket[ iLT ].m_hitresult ) hitted = hitPacket[ iLT ].m_HitInfo.pHitObject->Intersect(
hitted = hitPacket[ iLT ].m_HitInfo.pHitObject->Intersect( rayLTC, rayLTC,
hitInfoLTC ); hitInfoLTC );
if( hitted ) if( hitted )
cLTC = CCOLORRGB( shadeHit( bgColorY, rayLTC, hitInfoLTC, false, 0, false ) ); cLTC = CCOLORRGB( shadeHit( bgColorY, rayLTC, hitInfoLTC, false,
0, false ) );
} }
// Trace and shade cRTC // Trace and shade cRTC
// /////////////////////////////////////////////////////////////
CCOLORRGB cRTC = BlendColor( cRT , cC ); CCOLORRGB cRTC = BlendColor( cRT , cC );
if( hitPacket[ iRT ].m_hitresult || hittedC ) if( hitPacket[ iRT ].m_hitresult || hittedC )
@ -1545,18 +1550,16 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
if( hittedC ) if( hittedC )
hitted = centerHitInfo.pHitObject->Intersect( rayRTC, hitInfoRTC ); hitted = centerHitInfo.pHitObject->Intersect( rayRTC, hitInfoRTC );
else else if( hitPacket[ iRT ].m_hitresult )
if( hitPacket[ iRT ].m_hitresult )
hitted = hitPacket[ iRT ].m_HitInfo.pHitObject->Intersect( rayRTC, hitted = hitPacket[ iRT ].m_HitInfo.pHitObject->Intersect( rayRTC,
hitInfoRTC ); hitInfoRTC );
if( hitted ) if( hitted )
cRTC = CCOLORRGB( shadeHit( bgColorY, rayRTC, hitInfoRTC, false, 0, false ) ); cRTC = CCOLORRGB( shadeHit( bgColorY, rayRTC, hitInfoRTC, false,
0, false ) );
} }
// Trace and shade cLBC // Trace and shade cLBC
// /////////////////////////////////////////////////////////////
CCOLORRGB cLBC = BlendColor( cLB , cC ); CCOLORRGB cLBC = BlendColor( cLB , cC );
if( hitPacket[ iLB ].m_hitresult || hittedC ) if( hitPacket[ iLB ].m_hitresult || hittedC )
@ -1573,18 +1576,16 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
if( hittedC ) if( hittedC )
hitted = centerHitInfo.pHitObject->Intersect( rayLBC, hitInfoLBC ); hitted = centerHitInfo.pHitObject->Intersect( rayLBC, hitInfoLBC );
else else if( hitPacket[ iLB ].m_hitresult )
if( hitPacket[ iLB ].m_hitresult )
hitted = hitPacket[ iLB ].m_HitInfo.pHitObject->Intersect( rayLBC, hitted = hitPacket[ iLB ].m_HitInfo.pHitObject->Intersect( rayLBC,
hitInfoLBC ); hitInfoLBC );
if( hitted ) if( hitted )
cLBC = CCOLORRGB( shadeHit( bgColorY, rayLBC, hitInfoLBC, false, 0, false ) ); cLBC = CCOLORRGB( shadeHit( bgColorY, rayLBC, hitInfoLBC, false,
0, false ) );
} }
// Trace and shade cRBC // Trace and shade cRBC
// /////////////////////////////////////////////////////////////
CCOLORRGB cRBC = BlendColor( cRB , cC ); CCOLORRGB cRBC = BlendColor( cRB , cC );
if( hitPacket[ iRB ].m_hitresult || hittedC ) if( hitPacket[ iRB ].m_hitresult || hittedC )
@ -1601,19 +1602,16 @@ void C3D_RENDER_RAYTRACING::render_preview( GLubyte *ptrPBO )
if( hittedC ) if( hittedC )
hitted = centerHitInfo.pHitObject->Intersect( rayRBC, hitInfoRBC ); hitted = centerHitInfo.pHitObject->Intersect( rayRBC, hitInfoRBC );
else else if( hitPacket[ iRB ].m_hitresult )
if( hitPacket[ iRB ].m_hitresult )
hitted = hitPacket[ iRB ].m_HitInfo.pHitObject->Intersect( rayRBC, hitted = hitPacket[ iRB ].m_HitInfo.pHitObject->Intersect( rayRBC,
hitInfoRBC ); hitInfoRBC );
if( hitted ) if( hitted )
cRBC = CCOLORRGB( shadeHit( bgColorY, rayRBC, hitInfoRBC, false, 0, false ) ); cRBC = CCOLORRGB( shadeHit( bgColorY, rayRBC, hitInfoRBC, false,
0, false ) );
} }
// Set pixel colors // Set pixel colors
// /////////////////////////////////////////////////////////////
GLubyte *ptr = &ptrPBO[ (4 * x + m_blockPositionsFast[iBlock].x + GLubyte *ptr = &ptrPBO[ (4 * x + m_blockPositionsFast[iBlock].x +
m_realBufferSize.x * m_realBufferSize.x *
(m_blockPositionsFast[iBlock].y + 4 * y)) * 4 ]; (m_blockPositionsFast[iBlock].y + 4 * y)) * 4 ];
@ -1742,7 +1740,8 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor,
else 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); const float shadow_inc_factor = 1.0f / (float)(shadow_number_of_samples);
for( unsigned int i = 0; i < shadow_number_of_samples; ++i ) for( unsigned int i = 0; i < shadow_number_of_samples; ++i )
@ -1756,8 +1755,8 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor,
else else
{ {
const SFVEC3F unifVector = UniformRandomHemisphereDirection(); const SFVEC3F unifVector = UniformRandomHemisphereDirection();
const SFVEC3F disturbed_vector_to_light = glm::normalize( vectorToLight + const SFVEC3F disturbed_vector_to_light =
unifVector * glm::normalize( vectorToLight + unifVector *
m_boardAdapter.m_raytrace_spread_shadows ); m_boardAdapter.m_raytrace_spread_shadows );
rayToLight.Init( hitPoint, disturbed_vector_to_light ); 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 // !TODO: there are multiple ways that this tests can be
// optimized. Eg: by packing rays or to test against the // optimized. Eg: by packing rays or to test against the
// latest hit object. // latest hit object.
if( m_accelerator->IntersectP( rayToLight, distToLight ) ) if( m_accelerator->IntersectP( rayToLight, distToLight ) )
{ {
shadow_att_factor_light -= shadow_inc_factor; shadow_att_factor_light -= shadow_inc_factor;
@ -1808,13 +1806,12 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor,
if( !m_isPreview ) if( !m_isPreview )
{ {
// Reflections // Reflections
// /////////////////////////////////////////////////////////////////////
if( ( objMaterial->GetReflection() > 0.0f ) && if( ( objMaterial->GetReflection() > 0.0f ) &&
m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_REFLECTIONS ) && m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_REFLECTIONS ) &&
( aRecursiveLevel < objMaterial->GetReflectionsRecursiveLevel() ) ) ( 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); 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) ); outColor += (sum_color / SFVEC3F( (float)reflection_number_of_samples) );
} }
// Refractions // Refractions
// /////////////////////////////////////////////////////////////////////
const float objTransparency = aHitInfo.pHitObject->GetModelTransparency(); const float objTransparency = aHitInfo.pHitObject->GetModelTransparency();
if( ( objTransparency > 0.0f ) && 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 // This increase the start point by a "fixed" factor so it will work the
// same for all distances // 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); SFVEC3F sum_color = SFVEC3F(0.0f);
@ -1906,7 +1903,8 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor,
else else
{ {
// apply some randomize to the refracted vector // apply some randomize to the refracted vector
const SFVEC3F randomizeRefractedVector = glm::normalize( refractedVector + const SFVEC3F randomizeRefractedVector =
glm::normalize( refractedVector +
UniformRandomHemisphereDirection() * UniformRandomHemisphereDirection() *
m_boardAdapter.m_raytrace_spread_refractions ); m_boardAdapter.m_raytrace_spread_refractions );
@ -1916,7 +1914,6 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor,
HITINFO refractedHit; HITINFO refractedHit;
refractedHit.m_tHit = std::numeric_limits<float>::infinity(); refractedHit.m_tHit = std::numeric_limits<float>::infinity();
SFVEC3F refractedColor = aBgColor; SFVEC3F refractedColor = aBgColor;
if( m_accelerator->Intersect( refractedRay, refractedHit ) ) 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 ) * const SFVEC3F absorbance = ( SFVEC3F(1.0f) - diffuseColorObj ) *
(1.0f - objTransparency ) * (1.0f - objTransparency ) *
objMaterial->GetAbsorvance() * // Adjust falloff factor objMaterial->GetAbsorvance() *
refractedHit.m_tHit; refractedHit.m_tHit;
const SFVEC3F transparency = 1.0f / ( absorbance + 1.0f ); 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) + outColor = outColor * (1.0f - objTransparency) +
objTransparency * sum_color / SFVEC3F( (float)refractions_number_of_samples); objTransparency * sum_color /
SFVEC3F( (float)refractions_number_of_samples);
} }
else else
{ {
@ -2010,13 +2008,12 @@ static float distance( const SFVEC2UI& a, const SFVEC2UI& b )
return hypotf( dx, dy ); return hypotf( dx, dy );
} }
void C3D_RENDER_RAYTRACING::initialize_block_positions() void C3D_RENDER_RAYTRACING::initialize_block_positions()
{ {
m_realBufferSize = SFVEC2UI( 0 ); m_realBufferSize = SFVEC2UI( 0 );
// Calc block positions for fast preview mode // Calc block positions for fast preview mode
// /////////////////////////////////////////////////////////////////////
m_blockPositionsFast.clear(); m_blockPositionsFast.clear();
unsigned int i = 0; 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' // Calc block positions for regular rendering. Choose an 'inside out'
// style of rendering // style of rendering
// /////////////////////////////////////////////////////////////////////
m_blockPositions.clear(); m_blockPositions.clear();
const int blocks_x = m_realBufferSize.x / RAYPACKET_DIM; const int blocks_x = m_realBufferSize.x / RAYPACKET_DIM;
const int blocks_y = m_realBufferSize.y / 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(); opengl_init_pbo();
} }
BOARD_ITEM *C3D_RENDER_RAYTRACING::IntersectBoardItem( const RAY &aRay ) BOARD_ITEM *C3D_RENDER_RAYTRACING::IntersectBoardItem( const RAY &aRay )
{ {
HITINFO hitInfo; HITINFO hitInfo;
hitInfo.m_tHit = std::numeric_limits<float>::infinity(); hitInfo.m_tHit = std::numeric_limits<float>::infinity();
if( m_accelerator ) if( m_accelerator )
{
if( m_accelerator->Intersect( aRay, hitInfo ) ) if( m_accelerator->Intersect( aRay, hitInfo ) )
{ {
if( hitInfo.pHitObject ) if( hitInfo.pHitObject )
return hitInfo.pHitObject->GetBoardItem(); return hitInfo.pHitObject->GetBoardItem();
} }
}
return nullptr; return nullptr;
} }

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -56,6 +56,7 @@ typedef enum
RT_RENDER_STATE_MAX RT_RENDER_STATE_MAX
} RT_RENDER_STATE; } RT_RENDER_STATE;
class C3D_RENDER_RAYTRACING : public C3D_RENDER_BASE class C3D_RENDER_RAYTRACING : public C3D_RENDER_BASE
{ {
public: public:
@ -69,7 +70,8 @@ public:
int GetWaitForEditingTimeOut() override; 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 ); BOARD_ITEM *IntersectBoardItem( const RAY &aRay );
@ -106,6 +108,43 @@ private:
// Materials // Materials
void setupMaterials(); 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 struct
{ {
CBLINN_PHONG_MATERIAL m_Paste; CBLINN_PHONG_MATERIAL m_Paste;
@ -128,13 +167,6 @@ private:
bool m_isPreview; 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 /// State used on quality render
RT_RENDER_STATE m_rt_render_state; RT_RENDER_STATE m_rt_render_state;
@ -151,6 +183,7 @@ private:
CDIRECTIONALLIGHT *m_camera_light; CDIRECTIONALLIGHT *m_camera_light;
bool m_opengl_support_vertex_buffer_object; bool m_opengl_support_vertex_buffer_object;
GLuint m_pboId; GLuint m_pboId;
GLuint m_pboDataSize; GLuint m_pboDataSize;
@ -193,36 +226,12 @@ private:
unsigned int m_xoffset; unsigned int m_xoffset;
unsigned int m_yoffset; 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 /// Stores materials of the 3D models
MAP_MODEL_MATERIALS m_model_materials; MAP_MODEL_MATERIALS m_model_materials;
void initialize_block_positions(); // Statistics
unsigned int m_stats_converted_dummy_to_plane;
void render( GLubyte* ptrPBO, REPORTER* aStatusReporter ); unsigned int m_stats_converted_roundsegment2d_to_roundsegment;
void render_preview( GLubyte *ptrPBO );
}; };
#define USE_SRGB_SPACE #define USE_SRGB_SPACE

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -33,7 +33,10 @@
#include "ray.h" #include "ray.h"
#include "hitinfo.h" #include "hitinfo.h"
/// A base light class to derive to implement other light classes
/**
* A base light class to derive to implement other light classes.
*/
class CLIGHT class CLIGHT
{ {
public: public:
@ -42,12 +45,13 @@ public:
virtual ~CLIGHT() {} virtual ~CLIGHT() {}
/** /**
* @brief GetLightParameters - Get parameters from this light * Get parameters from this light.
*
* @param aHitPoint: input hit position * @param aHitPoint: input hit position
* @param aOutVectorToLight: a vector that points from the hit * @param aOutVectorToLight a vector that points from the hit
* position in direction to the light * position in direction to the light
* @param aOutLightColor: the color of this light * @param aOutLightColor the color of this light
* @param aOutDistance: the distance from the point to the light * @param aOutDistance the distance from the point to the light
*/ */
virtual void GetLightParameters( const SFVEC3F &aHitPoint, virtual void GetLightParameters( const SFVEC3F &aHitPoint,
SFVEC3F &aOutVectorToLight, SFVEC3F &aOutVectorToLight,
@ -62,11 +66,11 @@ protected:
}; };
/// Point light based on: /**
/// http://ogldev.atspace.co.uk/www/tutorial20/tutorial20.html * Point light based on http://ogldev.atspace.co.uk/www/tutorial20/tutorial20.html.
*/
class CPOINTLIGHT : public CLIGHT class CPOINTLIGHT : public CLIGHT
{ {
public: public:
CPOINTLIGHT( const SFVEC3F &aPos, const SFVEC3F &aColor ) CPOINTLIGHT( const SFVEC3F &aPos, const SFVEC3F &aColor )
{ {
@ -79,7 +83,6 @@ public:
} }
// Imported functions from CLIGHT // Imported functions from CLIGHT
void GetLightParameters( const SFVEC3F &aHitPoint, void GetLightParameters( const SFVEC3F &aHitPoint,
SFVEC3F &aOutVectorToLight, SFVEC3F &aOutVectorToLight,
SFVEC3F &aOutLightColor, SFVEC3F &aOutLightColor,
@ -110,7 +113,9 @@ private:
}; };
/// Directional light - a light based only on a direction vector /**
* A light based only on a direction vector.
*/
class CDIRECTIONALLIGHT : public CLIGHT class CDIRECTIONALLIGHT : public CLIGHT
{ {
public: public:
@ -123,13 +128,12 @@ public:
} }
/** /**
* @brief SetDirection - Set directional light orientation * @brief SetDirection Set directional light orientation
* @param aDir: vector from the light * @param aDir: vector from the light
*/ */
void SetDirection( const SFVEC3F &aDir ) { m_inv_direction = -aDir; } void SetDirection( const SFVEC3F &aDir ) { m_inv_direction = -aDir; }
// Imported functions from CLIGHT // Imported functions from CLIGHT
void GetLightParameters( const SFVEC3F &aHitPoint, void GetLightParameters( const SFVEC3F &aHitPoint,
SFVEC3F &aOutVectorToLight, SFVEC3F &aOutVectorToLight,
SFVEC3F &aOutLightColor, SFVEC3F &aOutLightColor,
@ -143,7 +147,7 @@ public:
} }
private: private:
SFVEC3F m_inv_direction; ///< oposite direction of the light SFVEC3F m_inv_direction; ///< opposite direction of the light
SFVEC3F m_color; ///< light color SFVEC3F m_color; ///< light color
}; };
@ -151,7 +155,11 @@ private:
typedef std::list< CLIGHT * > LIST_LIGHT; 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 class CLIGHTCONTAINER
{ {
public: public:
@ -178,7 +186,6 @@ public:
} }
} }
/** /**
* @brief Add - Add a light to the container * @brief Add - Add a light to the container
* @param aLight * @param aLight

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * 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 AMBIENT_FACTOR (1.0f / 6.0f)
#define SPECULAR_FACTOR 1.0f #define SPECULAR_FACTOR 1.0f
CMATERIAL::CMATERIAL() CMATERIAL::CMATERIAL()
{ {
m_ambientColor = SFVEC3F( 0.2f, 0.2f, 0.2f ); 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-- // http://www.fooplot.com/#W3sidHlwZSI6MCwiZXEiOiJzaW4oc2luKHNpbih4KSoxLjkpKjEuNSkiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyItMC45NjIxMDU3MDgwNzg1MjYyIiwiNy45NzE0MjYyNjc2MDE0MyIsIi0yLjUxNzYyMDM1MTQ4MjQ0OSIsIjIuOTc5OTM3Nzg3Mzk3NTMwMyJdLCJzaXplIjpbNjQ2LDM5Nl19XQ--
// Implement a texture as the "measling crazing blistering" method of FR4 // 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 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 y = glm::sin( glm::sin( hitPos.y ) * 1.5f ) * 0.03f;
const float z = -(x + y) + glm::sin( hitPos.z ) * 0.06f; 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; SFVEC3F hitPos = aHitInfo.m_HitPoint * m_scale;
const float noise = (s_perlinNoise.noise( hitPos.x + boardNormal.y + aRay.m_Origin.x * 0.2f, const float noise =
hitPos.y + boardNormal.x ) - 0.5f) * 2.0f; ( 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 x = scratchPattern * 0.14f;
const float y = (noise + noise * scratchPattern) * 0.14f; const float y = (noise + noise * scratchPattern) * 0.14f;
@ -209,8 +213,10 @@ SFVEC3F CCOPPERNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) cons
return SFVEC3F( x, y, - ( x + y ) ) + boardNormal * 0.25f; return SFVEC3F( x, y, - ( x + y ) ) + boardNormal * 0.25f;
} }
else else
{
return SFVEC3F( 0.0f ); return SFVEC3F( 0.0f );
} }
}
CSOLDERMASKNORMAL::CSOLDERMASKNORMAL( const CPROCEDURALGENERATOR *aCopperNormalGenerator ) CSOLDERMASKNORMAL::CSOLDERMASKNORMAL( const CPROCEDURALGENERATOR *aCopperNormalGenerator )
@ -228,8 +234,10 @@ SFVEC3F CSOLDERMASKNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo )
return copperNormal * 0.05f; return copperNormal * 0.05f;
} }
else else
{
return SFVEC3F(0.0f); return SFVEC3F(0.0f);
} }
}
SFVEC3F CPLATEDCOPPERNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) const SFVEC3F CPLATEDCOPPERNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo ) const
@ -344,7 +352,8 @@ SFVEC3F CSILKSCREENNORMAL::Generate( const RAY &aRay, const HITINFO &aHitInfo )
hitPos.y * 1.2f, hitPos.y * 1.2f,
hitPos.z ); 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; t = t * t * t * 0.1f;
return t; return t;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -45,21 +45,16 @@ public:
} }
/** /**
* @brief Generate - Generates a 3D vector based on the ray and * Generates a 3D vector based on the ray and* hit information depending on the implementation.
* hit information depending on the implementation *
* @param aRay: the camera ray that hits the object * @param aRay the camera ray that hits the object
* @param aHitInfo: the hit information * @param aHitInfo the hit information
* @return the result of the procedural * @return the result of the procedural
*/ */
virtual SFVEC3F Generate( const RAY &aRay, virtual SFVEC3F Generate( const RAY &aRay, const HITINFO &aHitInfo ) const = 0;
const HITINFO &aHitInfo ) const = 0;
protected:
}; };
// Procedural generation of the board normals
class CBOARDNORMAL : public CPROCEDURALGENERATOR class CBOARDNORMAL : public CPROCEDURALGENERATOR
{ {
public: public:
@ -70,14 +65,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: private:
float m_scale; float m_scale;
}; };
// Procedural generation of the copper normals
/**
* Procedural generation of the copper normals.
*/
class CCOPPERNORMAL : public CPROCEDURALGENERATOR class CCOPPERNORMAL : public CPROCEDURALGENERATOR
{ {
public: public:
@ -93,14 +90,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: private:
const CPROCEDURALGENERATOR *m_board_normal_generator; const CPROCEDURALGENERATOR *m_board_normal_generator;
float m_scale; float m_scale;
}; };
class CPLATEDCOPPERNORMAL : public CPROCEDURALGENERATOR class CPLATEDCOPPERNORMAL : public CPROCEDURALGENERATOR
{ {
public: public:
@ -118,14 +115,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: private:
float m_scale; float m_scale;
}; };
// Procedural generation of the solder mask
/**
* Procedural generation of the solder mask.
*/
class CSOLDERMASKNORMAL : public CPROCEDURALGENERATOR class CSOLDERMASKNORMAL : public CPROCEDURALGENERATOR
{ {
public: public:
@ -136,15 +134,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: private:
const CPROCEDURALGENERATOR *m_copper_normal_generator; const CPROCEDURALGENERATOR *m_copper_normal_generator;
}; };
// Procedural generation of the plastic normals /**
* Procedural generation of the plastic normals.
*/
class CPLASTICNORMAL : public CPROCEDURALGENERATOR class CPLASTICNORMAL : public CPROCEDURALGENERATOR
{ {
public: public:
@ -159,15 +158,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: private:
float m_scale; float m_scale;
}; };
// Procedural generation of the shiny plastic normals /**
* Procedural generation of the shiny plastic normals.
*/
class CPLASTICSHINENORMAL : public CPROCEDURALGENERATOR class CPLASTICSHINENORMAL : public CPROCEDURALGENERATOR
{ {
public: public:
@ -189,7 +189,9 @@ private:
float m_scale; float m_scale;
}; };
// Procedural generation of the shiny brushed metal /**
* Procedural generation of the shiny brushed metal.
*/
class CMETALBRUSHEDNORMAL : public CPROCEDURALGENERATOR class CMETALBRUSHEDNORMAL : public CPROCEDURALGENERATOR
{ {
public: public:
@ -204,13 +206,13 @@ 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: private:
float m_scale; float m_scale;
}; };
class CSILKSCREENNORMAL : public CPROCEDURALGENERATOR class CSILKSCREENNORMAL : public CPROCEDURALGENERATOR
{ {
public: public:
@ -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: private:
float m_scale; float m_scale;
}; };
/// A base material class that can be used to derive a material implementation
/**
* Base material class that can be used to derive other material implementations.
*/
class CMATERIAL class CMATERIAL
{ {
public: public:
static void SetDefaultNrRefractionsSamples( unsigned int aNrRefractions ) { m_default_nrsamples_refractions = aNrRefractions; } static void SetDefaultNrRefractionsSamples( unsigned int aNrRefractions )
static void SetDefaultNrReflectionsSamples( unsigned int aNrReflections ) { m_default_nrsamples_reflections = aNrReflections; } {
m_default_nrsamples_refractions = aNrRefractions;
}
static void SetDefaultRefractionsLevel( unsigned int aRefractionLevel ) { m_default_refractions_recursive_levels = aRefractionLevel; } static void SetDefaultNrReflectionsSamples( unsigned int aNrReflections )
static void SetDefaultReflectionsLevel( unsigned int aReflectionLevel ) { m_default_reflections_recursive_levels = aReflectionLevel; } {
m_default_nrsamples_reflections = aNrReflections;
}
private: static void SetDefaultRefractionsLevel( unsigned int aRefractionLevel )
static int m_default_nrsamples_refractions; {
static int m_default_nrsamples_reflections; m_default_refractions_recursive_levels = aRefractionLevel;
static int m_default_refractions_recursive_levels; }
static int m_default_reflections_recursive_levels;
static void SetDefaultReflectionsLevel( unsigned int aReflectionLevel )
{
m_default_reflections_recursive_levels = aReflectionLevel;
}
public:
CMATERIAL(); CMATERIAL();
CMATERIAL( const SFVEC3F &aAmbient, CMATERIAL( const SFVEC3F &aAmbient,
const SFVEC3F &aEmissive, const SFVEC3F &aEmissive,
@ -273,27 +284,44 @@ public:
unsigned int GetRefractionsRecursiveLevel() const { return m_refractions_recursive_levels; } unsigned int GetRefractionsRecursiveLevel() const { return m_refractions_recursive_levels; }
void SetAbsorvance( float aAbsorvanceFactor ) { m_absorbance = aAbsorvanceFactor; } void SetAbsorvance( float aAbsorvanceFactor ) { m_absorbance = aAbsorvanceFactor; }
void SetNrRefractionsSamples( unsigned int aNrRefractions ) { m_refraction_nr_samples = aNrRefractions; } void SetNrRefractionsSamples( unsigned int aNrRefractions )
void SetNrReflectionsSamples( unsigned int aNrReflections ) { m_reflections_nr_samples = aNrReflections; } {
void SetReflectionsRecursiveLevel( unsigned int aReflectionsLevel ) { m_reflections_recursive_levels = aReflectionsLevel; } m_refraction_nr_samples = aNrRefractions;
void SetRefractionsRecursiveLevel( unsigned int aRefractionsLevel ) { m_refractions_recursive_levels = aRefractionsLevel; } }
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 * Set if the material can receive shadows.
* @param aCastShadows - true yes it can, false not it cannot *
* @param aCastShadows true yes it can, false not it cannot
*/ */
void SetCastShadows( bool aCastShadows ) { m_cast_shadows = aCastShadows; } void SetCastShadows( bool aCastShadows ) { m_cast_shadows = aCastShadows; }
bool GetCastShadows() const { return m_cast_shadows; } bool GetCastShadows() const { return m_cast_shadows; }
/** /**
* @brief Shade - Shades an intersection point * Shade an intersection point.
* @param aRay: the camera ray that hits the object *
* @param aHitInfo: the hit information * @param aRay the camera ray that hits the object
* @param NdotL: the dot product between Normal and Light * @param aHitInfo the hit information
* @param aDiffuseObjColor: diffuse object color * @param NdotL the dot product between Normal and Light
* @param aDirToLight: a vector of the incident light direction * @param aDiffuseObjColor diffuse object color
* @param aLightColor: the light 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 * @param aShadowAttenuationFactor 0.0f total in shadow, 1.0f completely not in shadow
* @return the resultant color * @return the resultant color
*/ */
@ -305,7 +333,11 @@ public:
const SFVEC3F &aLightColor, const SFVEC3F &aLightColor,
float aShadowAttenuationFactor ) const = 0; 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; } const CPROCEDURALGENERATOR *GetNormalPerturbator() const { return m_normal_perturbator; }
void PerturbeNormal( SFVEC3F &aNormal, const RAY &aRay, const HITINFO &aHitInfo ) const; void PerturbeNormal( SFVEC3F &aNormal, const RAY &aRay, const HITINFO &aHitInfo ) const;
@ -320,16 +352,32 @@ protected:
SFVEC3F m_emissiveColor; SFVEC3F m_emissiveColor;
SFVEC3F m_specularColor; SFVEC3F m_specularColor;
float m_shinness; float m_shinness;
float m_transparency; ///< 1.0 is completely transparent, 0.0 completely opaque
float m_absorbance; ///< absorvance factor for the transparent material ///< 1.0 is completely transparent, 0.0 completely opaque.
float m_reflection; ///< 1.0 completely reflective, 0.0 no reflective float m_transparency;
bool m_cast_shadows; ///< true if this object will block the light float m_absorbance; ///< absorbance factor for the transparent material.
unsigned int m_refraction_nr_samples; ///< nr of rays that will be interpolated for this material if it is a transparent float m_reflection; ///< 1.0 completely reflective, 0.0 no reflective.
unsigned int m_reflections_nr_samples; ///< nr of rays that will be interpolated for this material if it is reflective bool m_cast_shadows; ///< true if this object will block the light.
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 ///< 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; 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;
}; };

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2017 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2017 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * 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[1] = m_Dir.y < 0.0f;
m_dirIsNeg[2] = m_Dir.z < 0.0f; m_dirIsNeg[2] = m_Dir.z < 0.0f;
// ray slope // ray slope
// "Fast Ray / Axis-Aligned Bounding Box Overlap Tests using Ray Slopes" // "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; m_Classification = RAY_CLASSIFICATION::MMP;
} }
else//( m_Dir.z >= 0 ) else
{ {
m_Classification = RAY_CLASSIFICATION::MMO; m_Classification = RAY_CLASSIFICATION::MMO;
} }
} }
else//( m_Dir.y >= 0 ) else
{ {
if( m_Dir.z < 0 ) if( m_Dir.z < 0 )
{ {
@ -107,7 +106,7 @@ void RAY::Init( const SFVEC3F& o, const SFVEC3F& d )
if( m_Dir.y == 0 ) if( m_Dir.y == 0 )
m_Classification = RAY_CLASSIFICATION::MOM; m_Classification = RAY_CLASSIFICATION::MOM;
} }
else//( m_Dir.z >= 0 ) else
{ {
if( ( m_Dir.y == 0 ) && ( m_Dir.z == 0 ) ) if( ( m_Dir.y == 0 ) && ( m_Dir.z == 0 ) )
m_Classification = RAY_CLASSIFICATION::MOO; 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 ) if( m_Dir.y < 0 )
{ {
@ -130,7 +129,7 @@ void RAY::Init( const SFVEC3F& o, const SFVEC3F& d )
if( m_Dir.x == 0 ) if( m_Dir.x == 0 )
m_Classification = RAY_CLASSIFICATION::OMM; m_Classification = RAY_CLASSIFICATION::OMM;
} }
else//( m_Dir.z >= 0 ) else
{ {
if( ( m_Dir.x == 0 ) && ( m_Dir.z == 0 ) ) if( ( m_Dir.x == 0 ) && ( m_Dir.z == 0 ) )
m_Classification = RAY_CLASSIFICATION::OMO; m_Classification = RAY_CLASSIFICATION::OMO;
@ -142,7 +141,7 @@ void RAY::Init( const SFVEC3F& o, const SFVEC3F& d )
m_Classification = RAY_CLASSIFICATION::PMP; m_Classification = RAY_CLASSIFICATION::PMP;
} }
} }
else//( m_Dir.y >= 0 ) else
{ {
if( m_Dir.z < 0 ) if( m_Dir.z < 0 )
{ {
@ -155,7 +154,7 @@ void RAY::Init( const SFVEC3F& o, const SFVEC3F& d )
else else
m_Classification = RAY_CLASSIFICATION::PPM; m_Classification = RAY_CLASSIFICATION::PPM;
} }
else//( m_Dir.z > 0 ) else
{ {
if( m_Dir.x == 0 ) if( m_Dir.x == 0 )
{ {
@ -213,8 +212,9 @@ bool IntersectSegment( const SFVEC2F &aStartA, const SFVEC2F &aEnd_minus_startA,
} }
// !TODO: not tested /// @todo: not tested
bool RAY::IntersectSphere( const SFVEC3F &aCenter, float aRadius, float &aOutT0, float &aOutT1 ) const bool RAY::IntersectSphere( const SFVEC3F &aCenter, float aRadius, float &aOutT0,
float &aOutT1 ) const
{ {
/* /*
// Ray-sphere intersection: algebraic // Ray-sphere intersection: algebraic
@ -295,8 +295,7 @@ bool RAYSEG2D::IntersectSegment( const SFVEC2F &aStart,
const SFVEC2F &aEnd_minus_start, const SFVEC2F &aEnd_minus_start,
float *aOutT ) const float *aOutT ) const
{ {
float rxs = m_End_minus_start.x * float rxs = m_End_minus_start.x * aEnd_minus_start.y - m_End_minus_start.y *
aEnd_minus_start.y - m_End_minus_start.y *
aEnd_minus_start.x; aEnd_minus_start.x;
if( std::abs( rxs ) > glm::epsilon<float>() ) if( std::abs( rxs ) > glm::epsilon<float>() )
@ -335,7 +334,9 @@ float RAYSEG2D::DistanceToPointSquared( const SFVEC2F &aPoint ) const
return glm::dot( p, p ); return glm::dot( p, p );
if( m_DOT_End_minus_start <= c1 ) if( m_DOT_End_minus_start <= c1 )
{
p = aPoint - m_End; p = aPoint - m_End;
}
else else
{ {
const float b = c1 / m_DOT_End_minus_start; const float b = c1 / m_DOT_End_minus_start;
@ -373,15 +374,13 @@ bool RAYSEG2D::IntersectCircle( const SFVEC2F &aCenter,
if( discriminantsqr < FLT_EPSILON ) if( discriminantsqr < FLT_EPSILON )
return false; return false;
// Otherwise check and make sure that the intersections occur on the ray (t // Otherwise check and make sure that the intersections occur on the ray (t
// > 0) and return the closer one // > 0) and return the closer one
const float discriminant = std::sqrt( discriminantsqr ); const float discriminant = std::sqrt( discriminantsqr );
const float t1 = ( -qd - discriminant ); const float t1 = ( -qd - discriminant );
const float t2 = ( -qd + discriminant ); const float t2 = ( -qd + discriminant );
if( (( t1 < 0.0f ) || ( t1 > m_Length ) ) && if( ( ( t1 < 0.0f ) || ( t1 > m_Length ) ) && ( ( t2 < 0.0f ) || ( t2 > m_Length ) ) )
(( t2 < 0.0f ) || ( t2 > m_Length ) ) )
return false; // Neither intersection was in the ray's half line. return false; // Neither intersection was in the ray's half line.
// Convert the intersection to a normalized // Convert the intersection to a normalized

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2017 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2017 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -133,7 +133,8 @@ struct RAYSEG2D
float DistanceToPointSquared( const SFVEC2F &aPoint ) const; 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 * t - value 0.0 ... 1.0
*/ */
SFVEC2F atNormalized( float t ) const { return m_Start + m_End_minus_start * t; } SFVEC2F atNormalized( float t ) const { return m_Start + m_End_minus_start * t; }

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt> * Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -96,25 +96,26 @@ RAYPACKET::RAYPACKET( const CCAMERA &aCamera,
const SFVEC3F &aDirectionDisplacementFactor ) const SFVEC3F &aDirectionDisplacementFactor )
{ {
unsigned int i = 0; unsigned int i = 0;
for( unsigned int y = 0; y < RAYPACKET_DIM; ++y ) for( unsigned int y = 0; y < RAYPACKET_DIM; ++y )
{
for( unsigned int x = 0; x < RAYPACKET_DIM; ++x ) for( unsigned int x = 0; x < RAYPACKET_DIM; ++x )
{ {
SFVEC3F rayOrigin; SFVEC3F rayOrigin;
SFVEC3F rayDir; SFVEC3F rayDir;
aCamera.MakeRay( SFVEC2I( aWindowsPosition.x + x, aCamera.MakeRay( SFVEC2I( aWindowsPosition.x + x, aWindowsPosition.y + y ),
aWindowsPosition.y + y ),
rayOrigin, rayDir ); rayOrigin, rayDir );
const SFVEC3F randVector = SFVEC3F( Fast_RandFloat() * aDirectionDisplacementFactor.x, const SFVEC3F randVector = SFVEC3F( Fast_RandFloat() * aDirectionDisplacementFactor.x,
Fast_RandFloat() * aDirectionDisplacementFactor.y, Fast_RandFloat() * aDirectionDisplacementFactor.y,
Fast_RandFloat() * aDirectionDisplacementFactor.z ); Fast_RandFloat() * aDirectionDisplacementFactor.z );
m_ray[i].Init( rayOrigin, m_ray[i].Init( rayOrigin, glm::normalize( rayDir + randVector ) );
glm::normalize( rayDir + randVector ) );
i++; i++;
} }
}
wxASSERT( i == RAYPACKET_RAYS_PER_PACKET ); wxASSERT( i == RAYPACKET_RAYS_PER_PACKET );
@ -171,6 +172,7 @@ void RAYPACKET_InitRays( const CCAMERA &aCamera,
} }
} }
void RAYPACKET_InitRays_with2DDisplacement( const CCAMERA &aCamera, void RAYPACKET_InitRays_with2DDisplacement( const CCAMERA &aCamera,
const SFVEC2F &aWindowsPosition, const SFVEC2F &aWindowsPosition,
const SFVEC2F &a2DWindowsPosDisplacementFactor, const SFVEC2F &a2DWindowsPosDisplacementFactor,