コード例 #1
0
bool intersection(Vector4 start1, Vector4 end1, Vector4 start2, Vector4 end2, Vector4 *out_intersection)
{
    Vector4 dir1 = Vector4Subtract(end1, start1);
    Vector4 dir2 = Vector4Subtract(end2, start2);
    
    //считаем уравнения прямых проходящих через отрезки
    float a1 = -dir1.y;
    float b1 = +dir1.x;
    float d1 = -(a1*start1.x + b1*start1.y);
    
    float a2 = -dir2.y;
    float b2 = +dir2.x;
    float d2 = -(a2*start2.x + b2*start2.y);
    
    //подставляем концы отрезков, для выяснения в каких полуплоскотях они
    float seg1_line2_start = a2*start1.x + b2*start1.y + d2;
    float seg1_line2_end = a2*end1.x + b2*end1.y + d2;
    
    float seg2_line1_start = a1*start2.x + b1*start2.y + d1;
    float seg2_line1_end = a1*end2.x + b1*end2.y + d1;
    
    //если концы одного отрезка имеют один знак, значит он в одной полуплоскости и пересечения нет.
    if (seg1_line2_start * seg1_line2_end >= 0 || seg2_line1_start * seg2_line1_end >= 0)
        return false;
    
    float u = seg1_line2_start / (seg1_line2_start - seg1_line2_end);
    *out_intersection = Vector4Add(start1, Vector4MultiplyScalar(dir1, u));
    
    return true;
}
コード例 #2
0
ファイル: octgrid.cpp プロジェクト: wdings23/gl-projects
void octGridGetVisibleNodes( tOctGrid const* pOctGrid,
                             CCamera const* pCamera,
                             std::vector<tOctNode const*>& aVisibleNodes )
{
    // determine the extent of the frustum
    tVector4 topLeftNear = { 9999.0f, -9999.0f, 9999.0f };
    tVector4 bottomRightFar = { -9999.0f, 9999.0f, -9999.0f };
    
    getExtent( &topLeftNear, &bottomRightFar, &pCamera->mFarBottomLeft );
    getExtent( &topLeftNear, &bottomRightFar, &pCamera->mFarBottomRight );
    getExtent( &topLeftNear, &bottomRightFar, &pCamera->mFarTopLeft );
    getExtent( &topLeftNear, &bottomRightFar, &pCamera->mFarTopRight );
    
    getExtent( &topLeftNear, &bottomRightFar, &pCamera->mNearBottomLeft );
    getExtent( &topLeftNear, &bottomRightFar, &pCamera->mNearBottomRight );
    getExtent( &topLeftNear, &bottomRightFar, &pCamera->mNearTopLeft );
    getExtent( &topLeftNear, &bottomRightFar, &pCamera->mNearTopRight );
    
    tVector4 nodeSize =
    {
        pOctGrid->mDimension.fX / (float)pOctGrid->miNumNodesInDimension,
        pOctGrid->mDimension.fY / (float)pOctGrid->miNumNodesInDimension,
        pOctGrid->mDimension.fZ / (float)pOctGrid->miNumNodesInDimension,
        1.0
    };
    
    tVector4 gridNearTopLeft =
    {
        -nodeSize.fX * (float)pOctGrid->miNumNodesInDimension * 0.5f,
        nodeSize.fY * (float)pOctGrid->miNumNodesInDimension * 0.5f,
        -nodeSize.fZ * (float)pOctGrid->miNumNodesInDimension * 0.5f,
        1.0f
    };
    
    tVector4 gridFarBottomRight =
    {
        nodeSize.fX * (float)pOctGrid->miNumNodesInDimension * 0.5f,
        -nodeSize.fY * (float)pOctGrid->miNumNodesInDimension * 0.5f,
        nodeSize.fZ * (float)pOctGrid->miNumNodesInDimension * 0.5f,
        1.0f
    };
    
    // get the octnode indices in the grid
    float fLeft = topLeftNear.fX / nodeSize.fX;
    float fRight = bottomRightFar.fX / nodeSize.fX;
    
    float fTop = topLeftNear.fY / nodeSize.fY;
    float fBottom = bottomRightFar.fY / nodeSize.fY;
    
    float fNear = topLeftNear.fZ / nodeSize.fZ;
    float fFar = bottomRightFar.fZ / nodeSize.fZ;
    
    // X
    int iLeft = (int)ceilf( fLeft );
    int iRight = (int)ceilf( fRight );
    
    // Y
    int iTop = (int)ceilf( fTop );
    int iBottom = (int)ceilf( fBottom );
    
    // Z
    int iNear = (int)ceilf( fNear );
    int iFar = (int)ceilf( fFar );
    
    // floor for sign correctness
    if( fLeft < 0.0 )
    {
        iLeft = (int)floorf( fLeft );
    }
    
    if( fRight < 0.0 )
    {
        iRight = (int)floorf( fRight );
    }
    
    if( fTop < 0.0 )
    {
        iTop = (int)floorf( fTop );
    }
    
    if( fBottom < 0.0 )
    {
        iBottom = (int)floorf( fBottom );
    }
    
    if( fNear < 0.0 )
    {
        iNear = (int)floorf( fNear );
    }
    
    if( fFar < 0.0 )
    {
        iFar = (int)floorf( fFar );
    }
    
    // grid index extent
    int iGridLeft = (int)floorf( gridNearTopLeft.fX / nodeSize.fX );
    int iGridRight = (int)ceilf( gridFarBottomRight.fX / nodeSize.fX );
    
    int iGridTop = (int)ceilf( gridNearTopLeft.fY / nodeSize.fY );
    int iGridBottom = (int)ceilf( gridFarBottomRight.fY / nodeSize.fY );
    
    int iGridNear = (int)floorf( gridNearTopLeft.fZ / nodeSize.fZ );
    int iGridFar = (int)ceilf( gridFarBottomRight.fZ / nodeSize.fZ );
    
    // clamp
    if( iLeft < iGridLeft )
    {
        iLeft = iGridLeft;
    }
    
    if( iRight >= iGridRight )
    {
        iRight = iGridRight - 1;
    }
    
    if( iBottom < iGridBottom )
    {
        iBottom = iGridBottom;
    }
    
    if( iTop >= iGridTop )
    {
        iTop = iGridTop - 1;
    }
    
    if( iNear < iGridNear )
    {
        iNear = iGridNear;
    }
    
    if( iFar >= iGridFar )
    {
        iFar = iGridFar - 1;
    }
    
    int iNumNodes = pOctGrid->miNumNodesInDimension;
    int iHalfNumNodes = iNumNodes >> 1;
    
    // shift to (0, num nodes)
    iLeft += iHalfNumNodes;
    iRight += iHalfNumNodes;
    iTop += iHalfNumNodes;
    iBottom += iHalfNumNodes;
    iNear += iHalfNumNodes;
    iFar += iHalfNumNodes;
    
    // check for nodes in boundary
    tOctNode const* aNodes = pOctGrid->maNodes;
    for( int iZ = iNear; iZ <= iFar; iZ++ )
    {
        for( int iY = iBottom; iY <= iTop; iY++ )
        {
            for( int iX = iLeft; iX <= iRight; iX++ )
            {
                int iIndex = iZ * iNumNodes * iNumNodes + iY * iNumNodes + iX;
                tOctNode const* pOctNode = &aNodes[iIndex];
                bool bInFrustum = pCamera->cubeInFrustum( pOctNode->mpCenter, pOctNode->mfSize );
                if( bInFrustum )
                {
                    aVisibleNodes.push_back( pOctNode );
                    //OUTPUT( "%d OCTNODE IN FRUSTUM ( %f, %f, %f )\n", (int)aVisibleNodes.size(), pOctNode->mpCenter->fX, pOctNode->mpCenter->fY, pOctNode->mpCenter->fZ );
                }
                
            }   // for x = left to right
            
        }   // for y = bottom to top
    
    }   // for z = near to far
    
#if 0
    aVisibleNodes.clear();
    
    // camera direction
    tVector4 const* pCamPos = pCamera->getPosition();
    tVector4 const* pLookAt = pCamera->getLookAt();
    tVector4 dir;
    Vector4Subtract( &dir, pLookAt, pCamPos );
    Vector4Normalize( &dir, &dir );
    
    tVector4 const* aCenters = pOctGrid->maNodeCenters;
    float fNodeSize = pOctGrid->maNodes[0].mfSize;
    
    // brute force for now
    for( int iZ = 0; iZ < iNumNodes; iZ++ )
    {
        for( int iY = 0; iY < iNumNodes; iY++ )
        {
            for( int iX = 0; iX < iNumNodes; iX++ )
            {
                bool bInFrustum = pCamera->cubeInFrustum( aCenters, fNodeSize );
                ++aCenters;
                
                if( bInFrustum )
                {
                    int iIndex = iZ * iNumNodes * iNumNodes + iY * iNumNodes + iX;
                    WTFASSERT2( iIndex < pOctGrid->miNumNodes, "nodes out of bounds while getting visible" );
                    aVisibleNodes.push_back( &pOctGrid->maNodes[iIndex] );
                }
                
            }   // for x = 0 to num nodes
        
        }   // for y = 0 to num nodes
        
    }   // for z = 0 to num nodes
#endif // #if 0
    
}