Exemplo n.º 1
0
bool i_IntersectSegment(IntersectQuery *pQuery, IntersectInfo *pInfo, WorldTree *pWorldTree)
{
    float InvVV, VP, testMag;

    ++g_nIntersectCalls;
	CountAdder cTicks_Intersect(&g_Ticks_Intersect);
        
    // Init..
    g_pCurQuery = pQuery;
    g_pIntersection = LTNULL;
    g_pWorldIntersection = LTNULL;
    g_hWorldPoly = INVALID_HPOLY;
	g_hModelNode = INVALID_MODEL_NODE;
    g_bProcessNonSolid = !(pQuery->m_Flags & IGNORE_NONSOLID);
    g_bProcessObjects = !!(pQuery->m_Flags & INTERSECT_OBJECTS);
	g_bCheckIfFromPointIsInsideObject = !!(pQuery->m_Flags & CHECK_FROM_POINT_INSIDE_OBJECTS);
	g_bProcessModelObbs = !!(pQuery->m_Flags & INTERSECT_MODELOBBS);
    g_IntersectionBestDistSqr = (pQuery->m_From - pQuery->m_To).MagSqr() + 1.0f;

    // Precalculate stuff to totally accelerate i_QuickSphereTest.
    g_VOrigin = pQuery->m_From;
    g_V = pQuery->m_To - pQuery->m_From;

    // Calc Direction
    g_VDir = g_V.Unit();  

    g_LineLen = g_V.Mag();
    g_V /= g_LineLen;
    
    // Was it too short?
    testMag = g_V.MagSqr();
    if (testMag < 0.5f || testMag > 2.0f) 
	{
        return false;
    }
    
    VP = g_V.Dot(pQuery->m_From);
    InvVV = 1.0f / g_V.MagSqr();
    g_VTimesInvVV = g_V * InvVV;
    g_VPTimesInvVV = VP * InvVV;

    if (pQuery->m_Flags & INTERSECT_HPOLY) 
	{
        g_FindIntersectionsFn = i_FindIntersectionsHPoly;
    }
    else 
	{
        g_FindIntersectionsFn = i_FindIntersections;
    }

    // Start at the world tree.
    pWorldTree->IntersectSegment((LTVector*)&pQuery->m_From, (LTVector*)&pQuery->m_To, i_ISCallback, LTNULL);

    // If an object was hit, use it!
    if (g_pIntersection) 
	{
        pInfo->m_Point = g_IntersectionPos;
        pInfo->m_Plane = g_IntersectionPlane;
        pInfo->m_hObject = (HOBJECT)g_pIntersection;
        pInfo->m_hPoly = g_hWorldPoly;
		pInfo->m_hNode = g_hModelNode;
        
        if (g_pWorldIntersection) 
		{
            pInfo->m_SurfaceFlags = g_pWorldIntersection->m_pPoly->GetSurface()->m_TextureFlags;
        }
        else 
		{
            pInfo->m_SurfaceFlags = 0;
        }

        return true;
    }
    else 
	{
        return false;
    }
}