3D-Viewer: raytracing, implement an outline board cut
it cut board items that are outside and on the edge of the board. Allows castellations render.
This commit is contained in:
parent
18fdcbe61e
commit
b06db80151
|
@ -170,7 +170,7 @@ class BOARD_ADAPTER
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief GetEpoxyThickness3DU - Get the current epoxy thickness
|
* @brief GetEpoxyThickness3DU - Get the current epoxy thickness
|
||||||
* @return thickness in 3d unities
|
* @return thickness in 3d units
|
||||||
*/
|
*/
|
||||||
float GetEpoxyThickness3DU() const noexcept
|
float GetEpoxyThickness3DU() const noexcept
|
||||||
{
|
{
|
||||||
|
@ -179,7 +179,7 @@ class BOARD_ADAPTER
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief GetNonCopperLayerThickness3DU - Get the current non copper layers thickness
|
* @brief GetNonCopperLayerThickness3DU - Get the current non copper layers thickness
|
||||||
* @return thickness in 3d unities of non copperlayers
|
* @return thickness in 3d units of non copperlayers
|
||||||
*/
|
*/
|
||||||
float GetNonCopperLayerThickness3DU() const noexcept
|
float GetNonCopperLayerThickness3DU() const noexcept
|
||||||
{
|
{
|
||||||
|
@ -188,7 +188,7 @@ class BOARD_ADAPTER
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief GetCopperThickness3DU - Get the current copper layer thickness
|
* @brief GetCopperThickness3DU - Get the current copper layer thickness
|
||||||
* @return thickness in 3d unities of copperlayers
|
* @return thickness in 3d units of copperlayers
|
||||||
*/
|
*/
|
||||||
float GetCopperThickness3DU() const noexcept
|
float GetCopperThickness3DU() const noexcept
|
||||||
{
|
{
|
||||||
|
@ -197,13 +197,13 @@ class BOARD_ADAPTER
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief GetCopperThicknessBIU - Get the current copper layer thickness
|
* @brief GetCopperThicknessBIU - Get the current copper layer thickness
|
||||||
* @return thickness in board unities
|
* @return thickness in board units
|
||||||
*/
|
*/
|
||||||
int GetHolePlatingThicknessBIU() const noexcept;
|
int GetHolePlatingThicknessBIU() const noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief GetBoardSizeBIU - Get the board size
|
* @brief GetBoardSizeBIU - Get the board size
|
||||||
* @return size in BIU unities
|
* @return size in BIU units
|
||||||
*/
|
*/
|
||||||
wxSize GetBoardSizeBIU() const noexcept
|
wxSize GetBoardSizeBIU() const noexcept
|
||||||
{
|
{
|
||||||
|
@ -211,8 +211,8 @@ class BOARD_ADAPTER
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief GetBoardPosBIU - Get the board size
|
* @brief GetBoardPosBIU - Get the board center
|
||||||
* @return size in BIU unities
|
* @return position in BIU units
|
||||||
*/
|
*/
|
||||||
wxPoint GetBoardPosBIU() const noexcept
|
wxPoint GetBoardPosBIU() const noexcept
|
||||||
{
|
{
|
||||||
|
@ -336,7 +336,7 @@ class BOARD_ADAPTER
|
||||||
/**
|
/**
|
||||||
* @brief GetLayerTopZpos3DU - Get the top z position
|
* @brief GetLayerTopZpos3DU - Get the top z position
|
||||||
* @param aLayerId: layer id
|
* @param aLayerId: layer id
|
||||||
* @return position in 3D unities
|
* @return position in 3D units
|
||||||
*/
|
*/
|
||||||
float GetLayerTopZpos3DU( PCB_LAYER_ID aLayerId ) const noexcept
|
float GetLayerTopZpos3DU( PCB_LAYER_ID aLayerId ) const noexcept
|
||||||
{
|
{
|
||||||
|
@ -346,7 +346,7 @@ class BOARD_ADAPTER
|
||||||
/**
|
/**
|
||||||
* @brief GetLayerBottomZpos3DU - Get the bottom z position
|
* @brief GetLayerBottomZpos3DU - Get the bottom z position
|
||||||
* @param aLayerId: layer id
|
* @param aLayerId: layer id
|
||||||
* @return position in 3D unities
|
* @return position in 3D units
|
||||||
*/
|
*/
|
||||||
float GetLayerBottomZpos3DU( PCB_LAYER_ID aLayerId ) const noexcept
|
float GetLayerBottomZpos3DU( PCB_LAYER_ID aLayerId ) const noexcept
|
||||||
{
|
{
|
||||||
|
|
|
@ -59,6 +59,11 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CBBOX2D &GetBBox() const
|
||||||
|
{
|
||||||
|
return m_bbox;
|
||||||
|
}
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
const LIST_OBJECT2D &GetList() const { return m_objects; }
|
const LIST_OBJECT2D &GetList() const { return m_objects; }
|
||||||
|
|
|
@ -370,6 +370,21 @@ void C3D_RENDER_RAYTRACING::createItemsFromContainer( const CBVHCONTAINER2D *aCo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( !m_antioutlineBoard2dObjects->GetList().empty() )
|
||||||
|
{
|
||||||
|
CONST_LIST_OBJECT2D intersectionList;
|
||||||
|
|
||||||
|
m_antioutlineBoard2dObjects->GetListObjectsIntersects(
|
||||||
|
object2d_A->GetBBox(), intersectionList );
|
||||||
|
|
||||||
|
if( !intersectionList.empty() )
|
||||||
|
{
|
||||||
|
for( const COBJECT2D *obj : intersectionList )
|
||||||
|
{
|
||||||
|
object2d_B->push_back( obj );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const MAP_CONTAINER_2D& mapLayers = m_boardAdapter.GetMapLayers();
|
const MAP_CONTAINER_2D& mapLayers = m_boardAdapter.GetMapLayers();
|
||||||
|
|
||||||
|
@ -440,6 +455,8 @@ void C3D_RENDER_RAYTRACING::createItemsFromContainer( const CBVHCONTAINER2D *aCo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void buildBoardBoundingBoxPoly( const BOARD* aBoard, SHAPE_POLY_SET& aOutline );
|
||||||
|
|
||||||
void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter,
|
void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter,
|
||||||
REPORTER* aWarningReporter,
|
REPORTER* aWarningReporter,
|
||||||
bool aOnlyLoadCopperAndShapes )
|
bool aOnlyLoadCopperAndShapes )
|
||||||
|
@ -470,8 +487,10 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter,
|
||||||
// /////////////////////////////////////////////////////////////////////////
|
// /////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
delete m_outlineBoard2dObjects;
|
delete m_outlineBoard2dObjects;
|
||||||
|
delete m_antioutlineBoard2dObjects;
|
||||||
|
|
||||||
m_outlineBoard2dObjects = new CCONTAINER2D;
|
m_outlineBoard2dObjects = new CCONTAINER2D;
|
||||||
|
m_antioutlineBoard2dObjects = new CBVHCONTAINER2D;
|
||||||
|
|
||||||
if( !aOnlyLoadCopperAndShapes )
|
if( !aOnlyLoadCopperAndShapes )
|
||||||
{
|
{
|
||||||
|
@ -488,6 +507,29 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter,
|
||||||
divFactor = m_boardAdapter.GetStats_Med_Hole_Diameter3DU() * 8.0f;
|
divFactor = m_boardAdapter.GetStats_Med_Hole_Diameter3DU() * 8.0f;
|
||||||
|
|
||||||
SHAPE_POLY_SET boardPolyCopy = m_boardAdapter.GetBoardPoly();
|
SHAPE_POLY_SET boardPolyCopy = m_boardAdapter.GetBoardPoly();
|
||||||
|
|
||||||
|
// Calculate an antiboard outline
|
||||||
|
|
||||||
|
SHAPE_POLY_SET antiboardPoly;
|
||||||
|
|
||||||
|
buildBoardBoundingBoxPoly( m_boardAdapter.GetBoard(), antiboardPoly );
|
||||||
|
|
||||||
|
antiboardPoly.BooleanSubtract( boardPolyCopy, SHAPE_POLY_SET::PM_FAST );
|
||||||
|
antiboardPoly.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||||
|
|
||||||
|
for( int iOutlinePolyIdx = 0; iOutlinePolyIdx < antiboardPoly.OutlineCount(); iOutlinePolyIdx++ )
|
||||||
|
{
|
||||||
|
Convert_path_polygon_to_polygon_blocks_and_dummy_blocks(
|
||||||
|
antiboardPoly,
|
||||||
|
*m_antioutlineBoard2dObjects,
|
||||||
|
m_boardAdapter.BiuTo3Dunits(),
|
||||||
|
divFactor,
|
||||||
|
*dynamic_cast<const BOARD_ITEM*>( m_boardAdapter.GetBoard() ),
|
||||||
|
iOutlinePolyIdx );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_antioutlineBoard2dObjects->BuildBVH();
|
||||||
|
|
||||||
boardPolyCopy.Fracture( SHAPE_POLY_SET::PM_FAST );
|
boardPolyCopy.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||||
|
|
||||||
for( int iOutlinePolyIdx = 0; iOutlinePolyIdx < outlineCount; iOutlinePolyIdx++ )
|
for( int iOutlinePolyIdx = 0; iOutlinePolyIdx < outlineCount; iOutlinePolyIdx++ )
|
||||||
|
@ -537,6 +579,23 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( !m_antioutlineBoard2dObjects->GetList().empty() )
|
||||||
|
{
|
||||||
|
CONST_LIST_OBJECT2D intersectionList;
|
||||||
|
|
||||||
|
m_antioutlineBoard2dObjects->GetListObjectsIntersects(
|
||||||
|
object2d_A->GetBBox(),
|
||||||
|
intersectionList );
|
||||||
|
|
||||||
|
if( !intersectionList.empty() )
|
||||||
|
{
|
||||||
|
for( const COBJECT2D *obj : intersectionList )
|
||||||
|
{
|
||||||
|
object2d_B->push_back( obj );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( object2d_B->empty() )
|
if( object2d_B->empty() )
|
||||||
{
|
{
|
||||||
delete object2d_B;
|
delete object2d_B;
|
||||||
|
@ -545,14 +604,6 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter,
|
||||||
|
|
||||||
if( object2d_B == CSGITEM_EMPTY )
|
if( object2d_B == CSGITEM_EMPTY )
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
create_3d_object_from( m_object_container, object2d_A,
|
|
||||||
m_boardAdapter.GetLayerBottomZpos3DU( F_Cu ),
|
|
||||||
m_boardAdapter.GetLayerBottomZpos3DU( B_Cu ),
|
|
||||||
&m_materials.m_EpoxyBoard,
|
|
||||||
g_epoxyColor );
|
|
||||||
#else
|
|
||||||
|
|
||||||
CLAYERITEM *objPtr = new CLAYERITEM( object2d_A,
|
CLAYERITEM *objPtr = new CLAYERITEM( object2d_A,
|
||||||
m_boardAdapter.GetLayerBottomZpos3DU( F_Cu ),
|
m_boardAdapter.GetLayerBottomZpos3DU( F_Cu ),
|
||||||
m_boardAdapter.GetLayerBottomZpos3DU( B_Cu ) );
|
m_boardAdapter.GetLayerBottomZpos3DU( B_Cu ) );
|
||||||
|
@ -560,7 +611,6 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter,
|
||||||
objPtr->SetMaterial( &m_materials.m_EpoxyBoard );
|
objPtr->SetMaterial( &m_materials.m_EpoxyBoard );
|
||||||
objPtr->SetColor( ConvertSRGBToLinear( (SFVEC3F)m_boardAdapter.m_BoardBodyColor ) );
|
objPtr->SetColor( ConvertSRGBToLinear( (SFVEC3F)m_boardAdapter.m_BoardBodyColor ) );
|
||||||
m_object_container.Add( objPtr );
|
m_object_container.Add( objPtr );
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -601,6 +651,21 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter,
|
||||||
{
|
{
|
||||||
const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*hole);
|
const COBJECT2D *hole2d = static_cast<const COBJECT2D *>(*hole);
|
||||||
|
|
||||||
|
if( !m_antioutlineBoard2dObjects->GetList().empty() )
|
||||||
|
{
|
||||||
|
CONST_LIST_OBJECT2D intersectionList;
|
||||||
|
|
||||||
|
m_antioutlineBoard2dObjects->GetListObjectsIntersects(
|
||||||
|
hole2d->GetBBox(), intersectionList );
|
||||||
|
|
||||||
|
if( !intersectionList.empty() )
|
||||||
|
{
|
||||||
|
// Do not add cylinder if it intersects the edge of the board
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch( hole2d->GetObjectType() )
|
switch( hole2d->GetObjectType() )
|
||||||
{
|
{
|
||||||
case OBJECT2D_TYPE::FILLED_CIRCLE:
|
case OBJECT2D_TYPE::FILLED_CIRCLE:
|
||||||
|
@ -642,7 +707,7 @@ void C3D_RENDER_RAYTRACING::Reload( REPORTER* aStatusReporter,
|
||||||
if( aOnlyLoadCopperAndShapes && !IsCopperLayer( layer_id ) )
|
if( aOnlyLoadCopperAndShapes && !IsCopperLayer( layer_id ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Mask kayers are not processed here because they are a special case
|
// Mask layers are not processed here because they are a special case
|
||||||
if( (layer_id == B_Mask) || (layer_id == F_Mask) )
|
if( (layer_id == B_Mask) || (layer_id == F_Mask) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1099,6 +1164,8 @@ void C3D_RENDER_RAYTRACING::insert3DPadHole( const D_PAD* aPad )
|
||||||
if( !hasHole )
|
if( !hasHole )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
CONST_LIST_OBJECT2D antiOutlineIntersectionList;
|
||||||
|
|
||||||
const float topZ = m_boardAdapter.GetLayerBottomZpos3DU( F_Cu ) +
|
const float topZ = m_boardAdapter.GetLayerBottomZpos3DU( F_Cu ) +
|
||||||
m_boardAdapter.GetCopperThickness3DU();
|
m_boardAdapter.GetCopperThickness3DU();
|
||||||
|
|
||||||
|
@ -1112,6 +1179,7 @@ void C3D_RENDER_RAYTRACING::insert3DPadHole( const D_PAD* aPad )
|
||||||
|
|
||||||
int innerRadius = drillsize.x / 2;
|
int innerRadius = drillsize.x / 2;
|
||||||
int outerRadius = innerRadius + m_boardAdapter.GetHolePlatingThicknessBIU();
|
int outerRadius = innerRadius + m_boardAdapter.GetHolePlatingThicknessBIU();
|
||||||
|
|
||||||
CRING2D *ring = new CRING2D( center,
|
CRING2D *ring = new CRING2D( center,
|
||||||
innerRadius * m_boardAdapter.BiuTo3Dunits(),
|
innerRadius * m_boardAdapter.BiuTo3Dunits(),
|
||||||
outerRadius * m_boardAdapter.BiuTo3Dunits(),
|
outerRadius * m_boardAdapter.BiuTo3Dunits(),
|
||||||
|
@ -1120,6 +1188,40 @@ void C3D_RENDER_RAYTRACING::insert3DPadHole( const D_PAD* aPad )
|
||||||
m_containerWithObjectsToDelete.Add( ring );
|
m_containerWithObjectsToDelete.Add( ring );
|
||||||
|
|
||||||
object2d_A = ring;
|
object2d_A = ring;
|
||||||
|
|
||||||
|
// If the object (ring) is intersected by an antioutline board,
|
||||||
|
// it will use instease a CSG of two circles.
|
||||||
|
if( object2d_A && !m_antioutlineBoard2dObjects->GetList().empty() )
|
||||||
|
{
|
||||||
|
|
||||||
|
m_antioutlineBoard2dObjects->GetListObjectsIntersects(
|
||||||
|
object2d_A->GetBBox(),
|
||||||
|
antiOutlineIntersectionList );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !antiOutlineIntersectionList.empty() )
|
||||||
|
{
|
||||||
|
CFILLEDCIRCLE2D *innerCircle = new CFILLEDCIRCLE2D( center,
|
||||||
|
innerRadius * m_boardAdapter.BiuTo3Dunits(),
|
||||||
|
*aPad );
|
||||||
|
|
||||||
|
CFILLEDCIRCLE2D *outterCircle = new CFILLEDCIRCLE2D( center,
|
||||||
|
outerRadius * m_boardAdapter.BiuTo3Dunits(),
|
||||||
|
*aPad );
|
||||||
|
std::vector<const COBJECT2D *> *object2d_B = new std::vector<const COBJECT2D *>();
|
||||||
|
object2d_B->push_back( innerCircle );
|
||||||
|
|
||||||
|
CITEMLAYERCSG2D *itemCSG2d = new CITEMLAYERCSG2D( outterCircle,
|
||||||
|
object2d_B,
|
||||||
|
CSGITEM_FULL,
|
||||||
|
*aPad );
|
||||||
|
|
||||||
|
m_containerWithObjectsToDelete.Add( itemCSG2d );
|
||||||
|
m_containerWithObjectsToDelete.Add( innerCircle );
|
||||||
|
m_containerWithObjectsToDelete.Add( outterCircle );
|
||||||
|
|
||||||
|
object2d_A = itemCSG2d;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else // Oblong hole
|
else // Oblong hole
|
||||||
{
|
{
|
||||||
|
@ -1173,6 +1275,14 @@ void C3D_RENDER_RAYTRACING::insert3DPadHole( const D_PAD* aPad )
|
||||||
m_containerWithObjectsToDelete.Add( outerSeg );
|
m_containerWithObjectsToDelete.Add( outerSeg );
|
||||||
|
|
||||||
object2d_A = itemCSG2d;
|
object2d_A = itemCSG2d;
|
||||||
|
|
||||||
|
if( object2d_A && !m_antioutlineBoard2dObjects->GetList().empty() )
|
||||||
|
{
|
||||||
|
|
||||||
|
m_antioutlineBoard2dObjects->GetListObjectsIntersects(
|
||||||
|
object2d_A->GetBBox(),
|
||||||
|
antiOutlineIntersectionList );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1204,6 +1314,14 @@ void C3D_RENDER_RAYTRACING::insert3DPadHole( const D_PAD* aPad )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( !antiOutlineIntersectionList.empty() )
|
||||||
|
{
|
||||||
|
for( const COBJECT2D *obj : antiOutlineIntersectionList )
|
||||||
|
{
|
||||||
|
object2d_B->push_back( obj );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( object2d_B->empty() )
|
if( object2d_B->empty() )
|
||||||
{
|
{
|
||||||
delete object2d_B;
|
delete object2d_B;
|
||||||
|
|
|
@ -61,6 +61,7 @@ C3D_RENDER_RAYTRACING::C3D_RENDER_RAYTRACING( BOARD_ADAPTER& aAdapter, CCAMERA&
|
||||||
m_oldWindowsSize.x = 0;
|
m_oldWindowsSize.x = 0;
|
||||||
m_oldWindowsSize.y = 0;
|
m_oldWindowsSize.y = 0;
|
||||||
m_outlineBoard2dObjects = NULL;
|
m_outlineBoard2dObjects = NULL;
|
||||||
|
m_antioutlineBoard2dObjects = NULL;
|
||||||
m_firstHitinfo = NULL;
|
m_firstHitinfo = NULL;
|
||||||
m_shaderBuffer = NULL;
|
m_shaderBuffer = NULL;
|
||||||
m_camera_light = NULL;
|
m_camera_light = NULL;
|
||||||
|
@ -85,6 +86,9 @@ C3D_RENDER_RAYTRACING::~C3D_RENDER_RAYTRACING()
|
||||||
delete m_outlineBoard2dObjects;
|
delete m_outlineBoard2dObjects;
|
||||||
m_outlineBoard2dObjects = NULL;
|
m_outlineBoard2dObjects = NULL;
|
||||||
|
|
||||||
|
delete m_antioutlineBoard2dObjects;
|
||||||
|
m_antioutlineBoard2dObjects = NULL;
|
||||||
|
|
||||||
delete[] m_shaderBuffer;
|
delete[] m_shaderBuffer;
|
||||||
m_shaderBuffer = NULL;
|
m_shaderBuffer = NULL;
|
||||||
|
|
||||||
|
|
|
@ -160,6 +160,7 @@ private:
|
||||||
CCONTAINER2D m_containerWithObjectsToDelete;
|
CCONTAINER2D m_containerWithObjectsToDelete;
|
||||||
|
|
||||||
CCONTAINER2D *m_outlineBoard2dObjects;
|
CCONTAINER2D *m_outlineBoard2dObjects;
|
||||||
|
CBVHCONTAINER2D *m_antioutlineBoard2dObjects;
|
||||||
|
|
||||||
CGENERICACCELERATOR *m_accelerator;
|
CGENERICACCELERATOR *m_accelerator;
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,7 @@ bool CITEMLAYERCSG2D::Intersect( const RAYSEG2D &aSegRay,
|
||||||
float currentRayDist;
|
float currentRayDist;
|
||||||
SFVEC2F currentRayPos;
|
SFVEC2F currentRayPos;
|
||||||
SFVEC2F currentNormal;
|
SFVEC2F currentNormal;
|
||||||
|
RAYSEG2D currentRay = aSegRay;
|
||||||
|
|
||||||
if( m_objectA->IsPointInside( aSegRay.m_Start ) )
|
if( m_objectA->IsPointInside( aSegRay.m_Start ) )
|
||||||
{
|
{
|
||||||
|
@ -103,18 +104,20 @@ bool CITEMLAYERCSG2D::Intersect( const RAYSEG2D &aSegRay,
|
||||||
if( !m_objectA->Intersect( aSegRay, ¤tRayDist, ¤tNormal ) )
|
if( !m_objectA->Intersect( aSegRay, ¤tRayDist, ¤tNormal ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
currentRayPos = aSegRay.atNormalized( NextFloatDown( currentRayDist ) );
|
currentRayPos = aSegRay.atNormalized( currentRayDist + 0.01f );
|
||||||
|
|
||||||
|
currentRay = RAYSEG2D( currentRayPos, aSegRay.m_End );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentRayDist = 0.0f;
|
||||||
|
|
||||||
//wxASSERT( (currentRayDist >= 0.0f) && (currentRayDist <= 1.0f) );
|
//wxASSERT( (currentRayDist >= 0.0f) && (currentRayDist <= 1.0f) );
|
||||||
|
|
||||||
|
|
||||||
// move through the union of subtracted regions
|
// move through the union of subtracted regions
|
||||||
bool hitSubRegion = false;
|
|
||||||
|
|
||||||
if( m_objectB )
|
if( m_objectB )
|
||||||
{
|
{
|
||||||
while(1)
|
for( unsigned int l = 0; l < 4; ++l )
|
||||||
{
|
{
|
||||||
bool wasInsideSubVol = false;
|
bool wasInsideSubVol = false;
|
||||||
|
|
||||||
|
@ -123,60 +126,41 @@ bool CITEMLAYERCSG2D::Intersect( const RAYSEG2D &aSegRay,
|
||||||
{
|
{
|
||||||
if( ((const COBJECT2D *)(*m_objectB)[i])->IsPointInside( currentRayPos ) )
|
if( ((const COBJECT2D *)(*m_objectB)[i])->IsPointInside( currentRayPos ) )
|
||||||
{
|
{
|
||||||
hitSubRegion = true;
|
|
||||||
|
|
||||||
// ray point is inside a subtracted region, so move it to the end of the
|
// ray point is inside a subtracted region, so move it to the end of the
|
||||||
// subtracted region
|
// subtracted region
|
||||||
float hitDist;
|
float hitDist;
|
||||||
if( !((const COBJECT2D *)(*m_objectB)[i])->Intersect( aSegRay,
|
SFVEC2F tmpNormal;
|
||||||
|
if( !((const COBJECT2D *)(*m_objectB)[i])->Intersect( currentRay,
|
||||||
&hitDist,
|
&hitDist,
|
||||||
¤tNormal ) )
|
&tmpNormal ) )
|
||||||
return false; // ray hit main object but did not leave subtracted volume
|
return false; // ray hit main object but did not leave subtracted volume
|
||||||
|
|
||||||
wxASSERT( hitDist <= 1.0f );
|
wxASSERT( hitDist <= 1.0f );
|
||||||
|
|
||||||
if( hitDist > currentRayDist )
|
if( hitDist > currentRayDist )
|
||||||
currentRayDist = hitDist;
|
|
||||||
|
|
||||||
currentRayDist += 0.0001f;
|
|
||||||
|
|
||||||
// ray has left this specific subtracted object volume
|
|
||||||
currentRayPos = aSegRay.atNormalized( currentRayDist );
|
|
||||||
|
|
||||||
if( m_objectA->IsPointInside( currentRayPos ) )
|
|
||||||
{
|
{
|
||||||
wasInsideSubVol = true;
|
wasInsideSubVol = true;
|
||||||
|
|
||||||
break;
|
currentRayPos = currentRay.atNormalized( glm::min( hitDist + 0.0001f, 1.0f ) );
|
||||||
|
|
||||||
|
currentRayDist = 0.0001f;
|
||||||
|
|
||||||
|
currentRay = RAYSEG2D( currentRayPos, aSegRay.m_End );
|
||||||
|
|
||||||
|
currentNormal = tmpNormal * -1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !wasInsideSubVol )
|
if( !wasInsideSubVol )
|
||||||
break; // ray has succesfully passed through all subtracted regions
|
{
|
||||||
|
|
||||||
if( currentRayDist >= 1.0f )
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//ray is not inside any of the specific subtracted regions
|
|
||||||
|
|
||||||
if( hitSubRegion )
|
|
||||||
{
|
|
||||||
//if( !m_objectA->IsPointInside( currentRayPos ) )
|
|
||||||
// return false; // ray got right through the hole in the object!
|
|
||||||
|
|
||||||
currentNormal *= -1.0f;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//ray just hit the main object without hitting any holes
|
|
||||||
}
|
|
||||||
|
|
||||||
*aNormalOut = currentNormal;
|
*aNormalOut = currentNormal;
|
||||||
*aOutT = currentRayDist;
|
*aOutT = glm::min( glm::max( 1.0f - glm::length( currentRayPos - aSegRay.m_End ) / aSegRay.m_Length, 0.0f ), 1.0f );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -207,7 +207,7 @@ bool CPOLYGONBLOCK2D::IsPointInside( const SFVEC2F &aPoint ) const
|
||||||
// At this moment, the point is not inside a hole, so check if it is
|
// At this moment, the point is not inside a hole, so check if it is
|
||||||
// inside the polygon
|
// inside the polygon
|
||||||
for( unsigned int i = 0; i < m_outers_and_holes.m_Outers.size(); i++ )
|
for( unsigned int i = 0; i < m_outers_and_holes.m_Outers.size(); i++ )
|
||||||
if( !m_outers_and_holes.m_Outers.empty() )
|
if( !m_outers_and_holes.m_Outers[i].empty() )
|
||||||
if( polygon_IsPointInside( m_outers_and_holes.m_Outers[i], aPoint ) )
|
if( polygon_IsPointInside( m_outers_and_holes.m_Outers[i], aPoint ) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue