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.
*
* 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
* modify it under the terms of the GNU General Public License
@ -32,8 +32,8 @@
* Original copyright notice:
*
* Perlin_Noise
* Here you could find the code for "Perlin noise in C++11", for more informations visit the project webpage:
* http://solarianprogrammer.com/2012/07/18/perlin-noise-cpp-11/
* Here you could find the code for "Perlin noise in C++11", for more information visit the
* project webpage at http://solarianprogrammer.com/2012/07/18/perlin-noise-cpp-11/
* You could use this program under the terms of GPL v3, for more details see:
* http://www.gnu.org/copyleft/gpl.html
* Copyright 2012 Sol from www.solarianprogrammer.com
@ -79,7 +79,7 @@ PerlinNoise::PerlinNoise()
std::copy_n( p.begin(), oldsize, p.begin() + oldsize );
}
// Generate a new permutation vector based on the value of seed
PerlinNoise::PerlinNoise( unsigned int seed )
{
p.resize( 256 );
@ -90,7 +90,7 @@ PerlinNoise::PerlinNoise( unsigned int seed )
// Initialize a random engine with seed
std::default_random_engine engine( seed );
// Suffle using the above random engine
// Shuffle using the above random engine
std::shuffle( p.begin(), p.end(), engine );
// Duplicate the permutation vector
@ -99,6 +99,7 @@ PerlinNoise::PerlinNoise( unsigned int seed )
std::copy_n( p.begin(), oldsize, p.begin() + oldsize );
}
float PerlinNoise::noise( float x, float y, float z ) const
{
// Find the unit cube that contains the point

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* 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
* modify it under the terms of the GNU General Public License
@ -33,7 +33,7 @@
*
* Perlin_Noise
* "Here you could find the code for "Perlin noise in C++11",
* for more informations visit the project webpage:
* for more information visit the project webpage:
* http://solarianprogrammer.com/2012/07/18/perlin-noise-cpp-11/
* You could use this program under the terms of GPL v3, for more details see:
* http://www.gnu.org/copyleft/gpl.html
@ -54,14 +54,15 @@
class PerlinNoise
{
// The permutation vector
std::vector<int> p;
public:
// Initialize with the reference values for the permutation vector
/**
* Initialize with the reference values for the permutation vector.
*/
PerlinNoise();
// Generate a new permutation vector based on the value of seed
/**
* Generate a new permutation vector based on the value of seed.
*/
PerlinNoise( unsigned int seed );
// Returns between 0.0f and 1.0f
@ -73,6 +74,9 @@ private:
float lerp( float t, float a, float b ) const;
float grad( int hash, float x, float y, float z ) const;
float grad( int hash, float x, float y ) const;
// The permutation vector
std::vector<int> p;
};
#endif

View File

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

View File

@ -2,7 +2,7 @@
* 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) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -27,14 +27,14 @@
* @brief This BVH implementation is based on the source code implementation
* from the book "Physically Based Rendering" (v2 and v3)
*
* Adaptions performed for kicad:
* Adaptions performed for KiCad:
* - Types and class types adapted to KiCad project
* - Convert some source to build in the C++ specification of KiCad
* - Code style to match KiCad
* - Asserts converted
* - Use compare functions/structures for std::partition and std::nth_element
*
* The original source code has the following licence:
* The original source code has the following license:
*
* "pbrt source code is Copyright(c) 1998-2015
* Matt Pharr, Greg Humphreys, and Wenzel Jakob.
@ -252,13 +252,11 @@ CBVH_PBRT::CBVH_PBRT( const CGENERICCONTAINER &aObjectContainer,
}
// Convert the objects list to vector of objects
// /////////////////////////////////////////////////////////////////////////
aObjectContainer.ConvertTo( m_primitives );
wxASSERT( aObjectContainer.GetList().size() == m_primitives.size() );
// Initialize _primitiveInfo_ array for primitives
// /////////////////////////////////////////////////////////////////////////
std::vector<BVHPrimitiveInfo> primitiveInfo( m_primitives.size() );
for( size_t i = 0; i < m_primitives.size(); ++i )
@ -331,8 +329,7 @@ struct ComparePoints
int dim;
bool operator()( const BVHPrimitiveInfo &a,
const BVHPrimitiveInfo &b ) const
bool operator()( const BVHPrimitiveInfo &a, const BVHPrimitiveInfo &b ) const
{
return a.centroid[dim] < b.centroid[dim];
}
@ -357,7 +354,10 @@ struct CompareToBucket
{
CompareToBucket( int split, int num, int d, const CBBOX &b )
: centroidBounds(b)
{ splitBucket = split; nBuckets = num; dim = d; }
{
splitBucket = split;
nBuckets = num; dim = d;
}
bool operator()(const BVHPrimitiveInfo &p) const;
@ -389,7 +389,10 @@ struct HLBVH_SAH_Evaluator
{
HLBVH_SAH_Evaluator( int split, int num, int d, const CBBOX &b )
: centroidBounds(b)
{ minCostSplitBucket = split; nBuckets = num; dim = d; }
{
minCostSplitBucket = split;
nBuckets = num; dim = d;
}
bool operator()(const BVHBuildNode *node) const;
@ -497,8 +500,7 @@ BVHBuildNode *CBVH_PBRT::recursiveBuild ( std::vector<BVHPrimitiveInfo> &primiti
{
int primitiveNr = primitiveInfo[i].primitiveNumber;
wxASSERT( (primitiveNr >= 0) &&
(primitiveNr < (int)m_primitives.size()) );
wxASSERT( ( primitiveNr >= 0 ) && ( primitiveNr < (int) m_primitives.size() ) );
const COBJECT *obj = static_cast<const COBJECT *>( m_primitives[ primitiveNr ] );
@ -524,8 +526,7 @@ BVHBuildNode *CBVH_PBRT::recursiveBuild ( std::vector<BVHPrimitiveInfo> &primiti
CompareToMid( dim, pmid ) );
mid = midPtr - &primitiveInfo[0];
wxASSERT( (mid >= start) &&
(mid <= end) );
wxASSERT( ( mid >= start ) && ( mid <= end ) );
if( (mid != start) && (mid != end) )
break;
@ -593,7 +594,7 @@ BVHBuildNode *CBVH_PBRT::recursiveBuild ( std::vector<BVHPrimitiveInfo> &primiti
// Compute costs for splitting after each bucket
float cost[nBuckets - 1];
for( int i = 0; i < (nBuckets - 1); ++i )
for( int i = 0; i < ( nBuckets - 1 ); ++i )
{
CBBOX b0, b1;
@ -640,10 +641,8 @@ BVHBuildNode *CBVH_PBRT::recursiveBuild ( std::vector<BVHPrimitiveInfo> &primiti
}
}
// Either create leaf or split primitives at selected SAH
// bucket
if( (nPrimitives > m_maxPrimsInNode) ||
(minCost < (float)nPrimitives) )
// Either create leaf or split primitives at selected SAH bucket
if( ( nPrimitives > m_maxPrimsInNode ) || ( minCost < (float) nPrimitives ) )
{
BVHPrimitiveInfo *pmid =
std::partition( &primitiveInfo[start],
@ -654,8 +653,7 @@ BVHBuildNode *CBVH_PBRT::recursiveBuild ( std::vector<BVHPrimitiveInfo> &primiti
centroidBounds ) );
mid = pmid - &primitiveInfo[0];
wxASSERT( (mid >= start) &&
(mid <= end) );
wxASSERT( ( mid >= start ) && ( mid <= end ) );
}
else
{
@ -724,9 +722,9 @@ BVHBuildNode *CBVH_PBRT::HLBVHBuild( const std::vector<BVHPrimitiveInfo> &primit
const SFVEC3F centroidOffset = bounds.Offset( primitiveInfo[i].centroid );
wxASSERT( (centroidOffset.x >= 0.0f) && (centroidOffset.x <= 1.0f) );
wxASSERT( (centroidOffset.y >= 0.0f) && (centroidOffset.y <= 1.0f) );
wxASSERT( (centroidOffset.z >= 0.0f) && (centroidOffset.z <= 1.0f) );
wxASSERT( ( centroidOffset.x >= 0.0f ) && ( centroidOffset.x <= 1.0f ) );
wxASSERT( ( centroidOffset.y >= 0.0f ) && ( centroidOffset.y <= 1.0f ) );
wxASSERT( ( centroidOffset.z >= 0.0f ) && ( centroidOffset.z <= 1.0f ) );
mortonPrims[i].mortonCode = EncodeMorton3( centroidOffset *
SFVEC3F( (float)mortonScale ) );
@ -744,9 +742,9 @@ BVHBuildNode *CBVH_PBRT::HLBVHBuild( const std::vector<BVHPrimitiveInfo> &primit
{
const uint32_t mask = 0b00111111111111000000000000000000;
if( (end == (int)mortonPrims.size()) ||
( (mortonPrims[start].mortonCode & mask) !=
(mortonPrims[end].mortonCode & mask) ) )
if( ( end == (int) mortonPrims.size() )
|| ( ( mortonPrims[start].mortonCode & mask )
!= ( mortonPrims[end].mortonCode & mask ) ) )
{
// Add entry to _treeletsToBuild_ for this treelet
const int numPrimitives = end - start;
@ -754,7 +752,7 @@ BVHBuildNode *CBVH_PBRT::HLBVHBuild( const std::vector<BVHPrimitiveInfo> &primit
// !TODO: implement a memory arena
BVHBuildNode *nodes = static_cast<BVHBuildNode *>( malloc( maxBVHNodes *
sizeof( BVHBuildNode ) ) );
sizeof( BVHBuildNode ) ) );
m_addresses_pointer_to_mm_free.push_back( nodes );
@ -825,12 +823,11 @@ BVHBuildNode *CBVH_PBRT::HLBVHBuild( const std::vector<BVHPrimitiveInfo> &primit
}
BVHBuildNode *CBVH_PBRT::emitLBVH(
BVHBuildNode *&buildNodes,
const std::vector<BVHPrimitiveInfo> &primitiveInfo,
MortonPrimitive *mortonPrims, int nPrimitives, int *totalNodes,
CONST_VECTOR_OBJECT &orderedPrims,
int *orderedPrimsOffset, int bit)
BVHBuildNode *CBVH_PBRT::emitLBVH( BVHBuildNode *&buildNodes,
const std::vector<BVHPrimitiveInfo> &primitiveInfo,
MortonPrimitive *mortonPrims, int nPrimitives, int *totalNodes,
CONST_VECTOR_OBJECT &orderedPrims,
int *orderedPrimsOffset, int bit )
{
wxASSERT( nPrimitives > 0 );
wxASSERT( totalNodes != NULL );
@ -838,7 +835,7 @@ BVHBuildNode *CBVH_PBRT::emitLBVH(
wxASSERT( nPrimitives > 0 );
wxASSERT( mortonPrims != NULL );
if( (bit == -1) || (nPrimitives < m_maxPrimsInNode) )
if( ( bit == -1 ) || ( nPrimitives < m_maxPrimsInNode ) )
{
// Create and return leaf node of LBVH treelet
(*totalNodes)++;
@ -850,7 +847,7 @@ BVHBuildNode *CBVH_PBRT::emitLBVH(
int firstPrimOffset = *orderedPrimsOffset;
*orderedPrimsOffset += nPrimitives;
wxASSERT( (firstPrimOffset + (nPrimitives - 1)) < (int)orderedPrims.size() );
wxASSERT( ( firstPrimOffset + ( nPrimitives - 1 ) ) < (int) orderedPrims.size() );
for( int i = 0; i < nPrimitives; ++i )
{
@ -871,11 +868,10 @@ BVHBuildNode *CBVH_PBRT::emitLBVH(
int mask = 1 << bit;
// Advance to next subtree level if there's no LBVH split for this bit
if( (mortonPrims[0].mortonCode & mask) ==
(mortonPrims[nPrimitives - 1].mortonCode & mask) )
return emitLBVH( buildNodes, primitiveInfo, mortonPrims, nPrimitives,
totalNodes, orderedPrims, orderedPrimsOffset,
bit - 1 );
if( ( mortonPrims[0].mortonCode & mask ) ==
( mortonPrims[nPrimitives - 1].mortonCode & mask ) )
return emitLBVH( buildNodes, primitiveInfo, mortonPrims, nPrimitives, totalNodes,
orderedPrims, orderedPrimsOffset, bit - 1 );
// Find LBVH split point for this dimension
int searchStart = 0;
@ -887,13 +883,13 @@ BVHBuildNode *CBVH_PBRT::emitLBVH(
const int mid = (searchStart + searchEnd) / 2;
if( (mortonPrims[searchStart].mortonCode & mask) ==
(mortonPrims[mid].mortonCode & mask) )
if( ( mortonPrims[searchStart].mortonCode & mask ) ==
( mortonPrims[mid].mortonCode & mask ) )
searchStart = mid;
else
{
wxASSERT( (mortonPrims[mid].mortonCode & mask) ==
(mortonPrims[searchEnd].mortonCode & mask) );
wxASSERT( ( mortonPrims[mid].mortonCode & mask ) ==
( mortonPrims[searchEnd].mortonCode & mask ) );
searchEnd = mid;
}
}
@ -911,11 +907,11 @@ BVHBuildNode *CBVH_PBRT::emitLBVH(
BVHBuildNode *lbvh[2];
lbvh[0] = emitLBVH( buildNodes, primitiveInfo, mortonPrims, splitOffset,
totalNodes, orderedPrims, orderedPrimsOffset, bit - 1 );
totalNodes, orderedPrims, orderedPrimsOffset, bit - 1 );
lbvh[1] = emitLBVH( buildNodes, primitiveInfo, &mortonPrims[splitOffset],
nPrimitives - splitOffset, totalNodes, orderedPrims,
orderedPrimsOffset, bit - 1 );
nPrimitives - splitOffset, totalNodes, orderedPrims,
orderedPrimsOffset, bit - 1 );
const int axis = bit % 3;
@ -926,10 +922,8 @@ BVHBuildNode *CBVH_PBRT::emitLBVH(
}
BVHBuildNode *CBVH_PBRT::buildUpperSAH(
std::vector<BVHBuildNode *> &treeletRoots,
int start, int end,
int *totalNodes )
BVHBuildNode *CBVH_PBRT::buildUpperSAH( std::vector<BVHBuildNode *> &treeletRoots,
int start, int end, int *totalNodes )
{
wxASSERT( totalNodes != NULL );
wxASSERT( start < end );
@ -940,7 +934,6 @@ BVHBuildNode *CBVH_PBRT::buildUpperSAH(
if( nNodes == 1 )
return treeletRoots[start];
(*totalNodes)++;
BVHBuildNode *node = static_cast<BVHBuildNode *>( malloc( sizeof( BVHBuildNode ) ) );
@ -997,14 +990,13 @@ BVHBuildNode *CBVH_PBRT::buildUpperSAH(
const float centroid = ( treeletRoots[i]->bounds.Min()[dim] +
treeletRoots[i]->bounds.Max()[dim] ) *
0.5f;
int b =
nBuckets * ( (centroid - centroidBounds.Min()[dim] ) /
(centroidBounds.Max()[dim] - centroidBounds.Min()[dim] ) );
int b = nBuckets * ( (centroid - centroidBounds.Min()[dim] ) /
(centroidBounds.Max()[dim] - centroidBounds.Min()[dim] ) );
if( b == nBuckets )
b = nBuckets - 1;
wxASSERT( (b >= 0) && (b < nBuckets) );
wxASSERT( ( b >= 0 ) && ( b < nBuckets ) );
buckets[b].count++;
buckets[b].bounds.Union( treeletRoots[i]->bounds );
@ -1095,7 +1087,7 @@ int CBVH_PBRT::flattenBVHTree( BVHBuildNode *node, uint32_t *offset )
}
else
{
// Creater interior flattened BVH node
// Create interior flattened BVH node
linearNode->axis = node->splitAxis;
linearNode->nPrimitives = 0;
flattenBVHTree( node->children[0], offset );
@ -1108,6 +1100,7 @@ int CBVH_PBRT::flattenBVHTree( BVHBuildNode *node, uint32_t *offset )
#define MAX_TODOS 64
bool CBVH_PBRT::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const
{
if( !m_nodes )
@ -1137,8 +1130,7 @@ bool CBVH_PBRT::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const
// Intersect ray with primitives in leaf BVH node
for( int i = 0; i < node->nPrimitives; ++i )
{
if( m_primitives[node->primitivesOffset + i]->Intersect( aRay,
aHitInfo ) )
if( m_primitives[node->primitivesOffset + i]->Intersect( aRay, aHitInfo ) )
{
aHitInfo.m_acc_node_info = nodeNum;
hit = true;
@ -1172,10 +1164,9 @@ bool CBVH_PBRT::Intersect( const RAY &aRay, HITINFO &aHitInfo ) const
return hit;
}
// !TODO: this may be optimized
bool CBVH_PBRT::Intersect( const RAY &aRay,
HITINFO &aHitInfo,
unsigned int aAccNodeInfo ) const
/// @todo This may be optimized
bool CBVH_PBRT::Intersect( const RAY& aRay, HITINFO& aHitInfo, unsigned int aAccNodeInfo ) const
{
if( !m_nodes )
return false;
@ -1197,15 +1188,14 @@ bool CBVH_PBRT::Intersect( const RAY &aRay,
const bool hitted = node->bounds.Intersect( aRay, &hitBox );
if( hitted && (hitBox < aHitInfo.m_tHit) )
if( hitted && ( hitBox < aHitInfo.m_tHit ) )
{
if( node->nPrimitives > 0 )
{
// Intersect ray with primitives in leaf BVH node
for( int i = 0; i < node->nPrimitives; ++i )
{
if( m_primitives[node->primitivesOffset + i]->Intersect( aRay,
aHitInfo ) )
if( m_primitives[node->primitivesOffset + i]->Intersect( aRay, aHitInfo ) )
{
//aHitInfo.m_acc_node_info = nodeNum;
hit = true;
@ -1260,7 +1250,7 @@ bool CBVH_PBRT::IntersectP( const RAY &aRay, float aMaxDistance ) const
const bool hitted = node->bounds.Intersect( aRay, &hitBox );
if( hitted && (hitBox < aMaxDistance) )
if( hitted && ( hitBox < aMaxDistance ) )
{
if( node->nPrimitives > 0 )
{
@ -1269,9 +1259,9 @@ bool CBVH_PBRT::IntersectP( const RAY &aRay, float aMaxDistance ) const
{
const COBJECT *obj = m_primitives[node->primitivesOffset + i];
if( obj->GetMaterial()->GetCastShadows() )
if( obj->IntersectP( aRay, aMaxDistance ) )
return true;
if( obj->GetMaterial()->GetCastShadows()
&& obj->IntersectP( aRay, aMaxDistance ) )
return true;
}
}
else

View File

@ -2,7 +2,7 @@
* 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) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -111,7 +111,7 @@ class CBVH_PBRT : public CGENERICACCELERATOR
{
public:
CBVH_PBRT( const CGENERICCONTAINER& aObjectContainer, int aMaxPrimsInNode = 4,
SPLITMETHOD aSplitMethod = SPLITMETHOD::SAH );
SPLITMETHOD aSplitMethod = SPLITMETHOD::SAH );
~CBVH_PBRT();
@ -148,8 +148,7 @@ private:
int end,
int *totalNodes );
int flattenBVHTree( BVHBuildNode *node,
uint32_t *offset );
int flattenBVHTree( BVHBuildNode *node, uint32_t *offset );
// BVH Private Data
const int m_maxPrimsInNode;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
* 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) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -54,7 +54,8 @@ typedef enum
RT_RENDER_STATE_POST_PROCESS_BLUR_AND_FINISH,
RT_RENDER_STATE_FINISH,
RT_RENDER_STATE_MAX
}RT_RENDER_STATE;
} RT_RENDER_STATE;
class C3D_RENDER_RAYTRACING : public C3D_RENDER_BASE
{
@ -69,7 +70,8 @@ public:
int GetWaitForEditingTimeOut() override;
void Reload( REPORTER* aStatusReporter, REPORTER* aWarningReporter, bool aOnlyLoadCopperAndShapes );
void Reload( REPORTER* aStatusReporter, REPORTER* aWarningReporter,
bool aOnlyLoadCopperAndShapes );
BOARD_ITEM *IntersectBoardItem( const RAY &aRay );
@ -106,6 +108,43 @@ private:
// Materials
void setupMaterials();
SFVEC3F shadeHit( const SFVEC3F &aBgColor,
const RAY &aRay,
HITINFO &aHitInfo,
bool aIsInsideObject,
unsigned int aRecursiveLevel,
bool is_testShadow ) const;
/**
* Create one or more 3D objects form a 2D object and Z positions.
*
* It tries to optimize some types of objects that will be faster to trace than the
* CLAYERITEM object.
*/
void create_3d_object_from( CCONTAINER &aDstContainer,
const COBJECT2D *aObject2D,
float aZMin, float aZMax,
const CMATERIAL *aMaterial,
const SFVEC3F &aObjColor );
void add_3D_vias_and_pads_to_container();
void insert3DViaHole( const VIA* aVia );
void insert3DPadHole( const PAD* aPad );
void load_3D_models( CCONTAINER &aDstContainer, bool aSkipMaterialInformation );
void add_3D_models( CCONTAINER &aDstContainer,
const S3DMODEL *a3DModel,
const glm::mat4 &aModelMatrix,
float aFPOpacity,
bool aSkipMaterialInformation,
BOARD_ITEM *aBoardItem );
MODEL_MATERIALS *get_3D_model_material( const S3DMODEL *a3DModel );
void initialize_block_positions();
void render( GLubyte* ptrPBO, REPORTER* aStatusReporter );
void render_preview( GLubyte *ptrPBO );
struct
{
CBLINN_PHONG_MATERIAL m_Paste;
@ -115,7 +154,7 @@ private:
CBLINN_PHONG_MATERIAL m_Copper;
CBLINN_PHONG_MATERIAL m_NonPlatedCopper;
CBLINN_PHONG_MATERIAL m_Floor;
}m_materials;
} m_materials;
CBOARDNORMAL m_board_normal_perturbator;
CCOPPERNORMAL m_copper_normal_perturbator;
@ -128,13 +167,6 @@ private:
bool m_isPreview;
SFVEC3F shadeHit( const SFVEC3F &aBgColor,
const RAY &aRay,
HITINFO &aHitInfo,
bool aIsInsideObject,
unsigned int aRecursiveLevel,
bool is_testShadow ) const;
/// State used on quality render
RT_RENDER_STATE m_rt_render_state;
@ -151,6 +183,7 @@ private:
CDIRECTIONALLIGHT *m_camera_light;
bool m_opengl_support_vertex_buffer_object;
GLuint m_pboId;
GLuint m_pboDataSize;
@ -193,36 +226,12 @@ private:
unsigned int m_xoffset;
unsigned int m_yoffset;
// Statistics
unsigned int m_stats_converted_dummy_to_plane;
unsigned int m_stats_converted_roundsegment2d_to_roundsegment;
void create_3d_object_from( CCONTAINER &aDstContainer,
const COBJECT2D *aObject2D,
float aZMin, float aZMax,
const CMATERIAL *aMaterial,
const SFVEC3F &aObjColor );
void add_3D_vias_and_pads_to_container();
void insert3DViaHole( const VIA* aVia );
void insert3DPadHole( const PAD* aPad );
void load_3D_models( CCONTAINER &aDstContainer, bool aSkipMaterialInformation );
void add_3D_models( CCONTAINER &aDstContainer,
const S3DMODEL *a3DModel,
const glm::mat4 &aModelMatrix,
float aFPOpacity,
bool aSkipMaterialInformation,
BOARD_ITEM *aBoardItem );
MODEL_MATERIALS *get_3D_model_material( const S3DMODEL *a3DModel );
/// Stores materials of the 3D models
MAP_MODEL_MATERIALS m_model_materials;
void initialize_block_positions();
void render( GLubyte* ptrPBO, REPORTER* aStatusReporter );
void render_preview( GLubyte *ptrPBO );
// Statistics
unsigned int m_stats_converted_dummy_to_plane;
unsigned int m_stats_converted_roundsegment2d_to_roundsegment;
};
#define USE_SRGB_SPACE

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
* 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) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -56,7 +56,6 @@ void RAY::Init( const SFVEC3F& o, const SFVEC3F& d )
m_dirIsNeg[1] = m_Dir.y < 0.0f;
m_dirIsNeg[2] = m_Dir.z < 0.0f;
// ray slope
// "Fast Ray / Axis-Aligned Bounding Box Overlap Tests using Ray Slopes"
@ -94,12 +93,12 @@ void RAY::Init( const SFVEC3F& o, const SFVEC3F& d )
{
m_Classification = RAY_CLASSIFICATION::MMP;
}
else//( m_Dir.z >= 0 )
else
{
m_Classification = RAY_CLASSIFICATION::MMO;
}
}
else//( m_Dir.y >= 0 )
else
{
if( m_Dir.z < 0 )
{
@ -107,7 +106,7 @@ void RAY::Init( const SFVEC3F& o, const SFVEC3F& d )
if( m_Dir.y == 0 )
m_Classification = RAY_CLASSIFICATION::MOM;
}
else//( m_Dir.z >= 0 )
else
{
if( ( m_Dir.y == 0 ) && ( m_Dir.z == 0 ) )
m_Classification = RAY_CLASSIFICATION::MOO;
@ -120,7 +119,7 @@ void RAY::Init( const SFVEC3F& o, const SFVEC3F& d )
}
}
}
else//( m_Dir.x >= 0 )
else
{
if( m_Dir.y < 0 )
{
@ -130,7 +129,7 @@ void RAY::Init( const SFVEC3F& o, const SFVEC3F& d )
if( m_Dir.x == 0 )
m_Classification = RAY_CLASSIFICATION::OMM;
}
else//( m_Dir.z >= 0 )
else
{
if( ( m_Dir.x == 0 ) && ( m_Dir.z == 0 ) )
m_Classification = RAY_CLASSIFICATION::OMO;
@ -142,7 +141,7 @@ void RAY::Init( const SFVEC3F& o, const SFVEC3F& d )
m_Classification = RAY_CLASSIFICATION::PMP;
}
}
else//( m_Dir.y >= 0 )
else
{
if( m_Dir.z < 0 )
{
@ -155,7 +154,7 @@ void RAY::Init( const SFVEC3F& o, const SFVEC3F& d )
else
m_Classification = RAY_CLASSIFICATION::PPM;
}
else//( m_Dir.z > 0 )
else
{
if( m_Dir.x == 0 )
{
@ -196,14 +195,14 @@ bool IntersectSegment( const SFVEC2F &aStartA, const SFVEC2F &aEnd_minus_startA,
SFVEC2F pq = aStartB - aStartA;
float t = (pq.x * aEnd_minus_startB.y - pq.y * aEnd_minus_startB.x) * inv_rxs;
float t = ( pq.x * aEnd_minus_startB.y - pq.y * aEnd_minus_startB.x ) * inv_rxs;
if( (t < 0.0f) || (t > 1.0f) )
if( ( t < 0.0f ) || ( t > 1.0f ) )
return false;
float u = (pq.x * aEnd_minus_startA.y - pq.y * aEnd_minus_startA.x) * inv_rxs;
float u = ( pq.x * aEnd_minus_startA.y - pq.y * aEnd_minus_startA.x ) * inv_rxs;
if( (u < 0.0f) || (u > 1.0f) )
if( ( u < 0.0f ) || ( u > 1.0f ) )
return false;
return true;
@ -213,8 +212,9 @@ bool IntersectSegment( const SFVEC2F &aStartA, const SFVEC2F &aEnd_minus_startA,
}
// !TODO: not tested
bool RAY::IntersectSphere( const SFVEC3F &aCenter, float aRadius, float &aOutT0, float &aOutT1 ) const
/// @todo: not tested
bool RAY::IntersectSphere( const SFVEC3F &aCenter, float aRadius, float &aOutT0,
float &aOutT1 ) const
{
/*
// Ray-sphere intersection: algebraic
@ -279,13 +279,13 @@ RAYSEG2D::RAYSEG2D( const SFVEC2F& s, const SFVEC2F& e )
m_End_minus_start = e - s;
m_Length = glm::length( m_End_minus_start );
m_Dir = glm::normalize( m_End_minus_start );
m_InvDir = (1.0f / m_Dir);
m_InvDir = ( 1.0f / m_Dir );
if( fabs(m_Dir.x) < FLT_EPSILON )
m_InvDir.x = NextFloatDown(FLT_MAX);
if( fabs( m_Dir.x ) < FLT_EPSILON )
m_InvDir.x = NextFloatDown( FLT_MAX );
if( fabs(m_Dir.y) < FLT_EPSILON )
m_InvDir.y = NextFloatDown(FLT_MAX);
if( fabs( m_Dir.y ) < FLT_EPSILON )
m_InvDir.y = NextFloatDown( FLT_MAX );
m_DOT_End_minus_start = glm::dot( m_End_minus_start, m_End_minus_start );
}
@ -295,8 +295,7 @@ bool RAYSEG2D::IntersectSegment( const SFVEC2F &aStart,
const SFVEC2F &aEnd_minus_start,
float *aOutT ) const
{
float rxs = m_End_minus_start.x *
aEnd_minus_start.y - m_End_minus_start.y *
float rxs = m_End_minus_start.x * aEnd_minus_start.y - m_End_minus_start.y *
aEnd_minus_start.x;
if( std::abs( rxs ) > glm::epsilon<float>() )
@ -305,14 +304,14 @@ bool RAYSEG2D::IntersectSegment( const SFVEC2F &aStart,
const SFVEC2F pq = aStart - m_Start;
const float t = (pq.x * aEnd_minus_start.y - pq.y * aEnd_minus_start.x) * inv_rxs;
const float t = ( pq.x * aEnd_minus_start.y - pq.y * aEnd_minus_start.x ) * inv_rxs;
if( (t < 0.0f) || (t > 1.0f) )
if( ( t < 0.0f ) || ( t > 1.0f ) )
return false;
float u = (pq.x * m_End_minus_start.y - pq.y * m_End_minus_start.x) * inv_rxs;
float u = ( pq.x * m_End_minus_start.y - pq.y * m_End_minus_start.x ) * inv_rxs;
if( (u < 0.0f) || (u > 1.0f) )
if( ( u < 0.0f ) || ( u > 1.0f ) )
return false;
*aOutT = t;
@ -335,7 +334,9 @@ float RAYSEG2D::DistanceToPointSquared( const SFVEC2F &aPoint ) const
return glm::dot( p, p );
if( m_DOT_End_minus_start <= c1 )
{
p = aPoint - m_End;
}
else
{
const float b = c1 / m_DOT_End_minus_start;
@ -373,16 +374,14 @@ bool RAYSEG2D::IntersectCircle( const SFVEC2F &aCenter,
if( discriminantsqr < FLT_EPSILON )
return false;
// Otherwise check and make sure that the intersections occur on the ray (t
// > 0) and return the closer one
const float discriminant = std::sqrt( discriminantsqr );
const float t1 = (-qd - discriminant);
const float t2 = (-qd + discriminant);
const float t1 = ( -qd - discriminant );
const float t2 = ( -qd + discriminant );
if( (( t1 < 0.0f ) || ( t1 > m_Length ) ) &&
(( t2 < 0.0f ) || ( t2 > m_Length ) ) )
return false;// Neither intersection was in the ray's half line.
if( ( ( t1 < 0.0f ) || ( t1 > m_Length ) ) && ( ( t2 < 0.0f ) || ( t2 > m_Length ) ) )
return false; // Neither intersection was in the ray's half line.
// Convert the intersection to a normalized
*aOutT0 = t1 / m_Length;
@ -391,8 +390,8 @@ bool RAYSEG2D::IntersectCircle( const SFVEC2F &aCenter,
SFVEC2F hitPointT1 = at( t1 );
SFVEC2F hitPointT2 = at( t2 );
*aOutNormalT0 = (hitPointT1 - aCenter) / aRadius;
*aOutNormalT1 = (hitPointT2 - aCenter) / aRadius;
*aOutNormalT0 = ( hitPointT1 - aCenter ) / aRadius;
*aOutNormalT1 = ( hitPointT2 - aCenter ) / aRadius;
return true;
}
@ -401,5 +400,5 @@ bool RAYSEG2D::IntersectCircle( const SFVEC2F &aCenter,
void RAY::debug() const
{
wxLogDebug( "O(%f, %f, %f) D(%f, %f, %f)\n", m_Origin.x, m_Origin.y, m_Origin.z,
m_Dir.x, m_Dir.y, m_Dir.z );
m_Dir.x, m_Dir.y, m_Dir.z );
}

View File

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

View File

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