void CTargetMgr::CheckForIntersect(float &fDistAway) { m_hTarget = LTNULL; m_ActivationData.Init(); uint32 dwUsrFlags = 0; const float fMaxDist = 100000.0f; // Cast ray from the camera to see if there is an object to activate... LTRotation rRot; LTVector vPos; HLOCALOBJ hCamera = g_pPlayerMgr->GetCamera(); g_pLTClient->GetObjectPos(hCamera, &vPos); g_pLTClient->GetObjectRotation(hCamera, &rRot); m_ActivationData.m_vPos = vPos; m_ActivationData.m_rRot = rRot; IntersectQuery IQuery; IntersectInfo IInfo; IQuery.m_From = vPos; IQuery.m_To = IQuery.m_From + (rRot.Forward() * fMaxDist); // NOTE the use of the CHECK_FROM_POINT_INSIDE_OBJECTS flag. This flag will // make sure that any objects that m_From is inside are considered IQuery.m_Flags = CHECK_FROM_POINT_INSIDE_OBJECTS | INTERSECT_HPOLY | INTERSECT_OBJECTS | IGNORE_NONSOLID; IQuery.m_FilterActualIntersectFn = ActivateFilterFn; IQuery.m_pActualIntersectUserData = (void*)&IQuery; IQuery.m_PolyFilterFn = DoVectorPolyFilterFn; // [KLS 8/3/02] - ActivateFilterFn may save an object to use that may not be // the best activation choice (i.e., a fallback choice). However, if a // better choice isn't found, the fallback choice should be used. That // fallback choice is stored in g_adFallbackActivationObject so we clear // it here... g_adFallbackActivationObject.Init(); if (g_pLTClient->IntersectSegment(&IQuery, &IInfo)) { m_ActivationData.m_vIntersect = IInfo.m_Point; if (IsMainWorld(IInfo.m_hObject)) { if (IInfo.m_hPoly != INVALID_HPOLY) { SurfaceType eType = GetSurfaceType(IInfo.m_hPoly); SURFACE *pSurf = g_pSurfaceMgr->GetSurface(eType); // See if the surface we tried to activate has an activation // sound...If so, the user can activate it... if (pSurf && pSurf->szActivationSnd[0] && pSurf->fActivationSndRadius > 0) { m_hTarget = IInfo.m_hObject; m_ActivationData.m_hTarget = m_hTarget; m_ActivationData.m_nSurfaceType = eType; } } } else { LTVector vObjPos = m_ActivationData.m_vIntersect; vObjPos -= vPos; if (vObjPos.Mag() <= fMaxDist) { m_hTarget = IInfo.m_hObject; m_ActivationData.m_hTarget = m_hTarget; } } // Calculate how far away the object is... LTVector vDist = m_ActivationData.m_vIntersect - vPos; fDistAway = vDist.Mag(); } // [KLS 8/3/02] - Use the fallback object if we have one and we didn't // find another object more suitable object... bool bCanUseFallback = (m_ActivationData.m_hTarget ? false : true); if (!bCanUseFallback) { // We can still use the fallback object if it isn't the world or a // world model... if (IsMainWorld(m_ActivationData.m_hTarget) || OT_WORLDMODEL == GetObjectType(m_ActivationData.m_hTarget)) { bCanUseFallback = true; } } if ( bCanUseFallback && g_adFallbackActivationObject.m_hTarget ) { // Ok we hit the fallback object reset some of our target data LTVector vObjPos; g_pLTClient->GetObjectPos(g_adFallbackActivationObject.m_hTarget, &vObjPos); m_ActivationData.m_vIntersect = vObjPos; vObjPos -= vPos; if (vObjPos.Mag() <= fMaxDist) { m_hTarget = g_adFallbackActivationObject.m_hTarget; m_ActivationData.m_hTarget = m_hTarget; } // Calculate how far away the object is... LTVector vDist = m_ActivationData.m_vIntersect - vPos; fDistAway = vDist.Mag(); } }
void CTargetMgr::CheckForIntersect(float &fDistAway) { m_hTarget = NULL; m_ActivationData.Init(); // Cast ray from the camera to see if there is an object to activate... LTRotation const& rRot = g_pPlayerMgr->GetPlayerCamera()->GetCameraRotation( );; LTVector const& vPos = g_pPlayerMgr->GetPlayerCamera()->GetCameraPos( ); m_ActivationData.m_vPos = vPos; m_ActivationData.m_rRot = rRot; IntersectQuery IQuery; IntersectInfo IInfo; IQuery.m_From = vPos; IQuery.m_To = IQuery.m_From + (rRot.Forward() * kMaxDistance); // NOTE the use of the CHECK_FROM_POINT_INSIDE_OBJECTS flag. This flag will // make sure that any objects that m_From is inside are considered IQuery.m_Flags = CHECK_FROM_POINT_INSIDE_OBJECTS | INTERSECT_HPOLY | INTERSECT_OBJECTS | IGNORE_NONSOLID; IQuery.m_FilterActualIntersectFn = ActivateFilterFn; IQuery.m_pActualIntersectUserData = (void*)&IQuery; IQuery.m_PolyFilterFn = NULL; // [KLS 8/3/02] - ActivateFilterFn may save an object to use that may not be // the best activation choice (i.e., a fallback choice). However, if a // better choice isn't found, the fallback choice should be used. That // fallback choice is stored in g_adFallbackActivationObject so we clear // it here... g_adFallbackActivationObject.Init(); if (g_pLTClient->IntersectSegment(IQuery, &IInfo)) { m_ActivationData.m_vIntersect = IInfo.m_Point; bool bHitSky = false; if (IsMainWorld(IInfo.m_hObject)) { if (IInfo.m_hPoly != INVALID_HPOLY) { SurfaceType eType = GetSurfaceType(IInfo.m_hPoly); HSURFACE hSurf = g_pSurfaceDB->GetSurface(eType); // See if the surface we tried to activate has an activation // sound...If so, the user can activate it... if (hSurf) { HRECORD hActSnd = g_pSurfaceDB->GetRecordLink(hSurf,SrfDB_Srf_rActivationSnd); if (hActSnd && g_pSoundDB->GetFloat(hActSnd,SndDB_fOuterRadius) > 0) { m_hTarget = IInfo.m_hObject; m_ActivationData.m_hTarget = m_hTarget; m_ActivationData.m_nSurfaceType = eType; m_ActivationData.m_hActivateSnd = hActSnd; } bHitSky = (ST_SKY == eType); } } } else { LTVector vObjPos = m_ActivationData.m_vIntersect; vObjPos -= vPos; if (vObjPos.Mag() <= kMaxDistance) { m_hTarget = IInfo.m_hObject; m_ActivationData.m_hTarget = m_hTarget; } } // Calculate how far away the object is... LTVector vDist = m_ActivationData.m_vIntersect - vPos; if (bHitSky) fDistAway = kMaxDistance; else fDistAway = vDist.Mag(); } // [KLS 8/3/02] - Use the fallback object if we have one and we didn't // find another object more suitable object... bool bCanUseFallback = (m_ActivationData.m_hTarget ? false : true); if (!bCanUseFallback) { // We can still use the fallback object if it isn't the world or a // world model... if (IsMainWorld(m_ActivationData.m_hTarget) || OT_WORLDMODEL == GetObjectType(m_ActivationData.m_hTarget)) { bCanUseFallback = true; } } if ( bCanUseFallback && g_adFallbackActivationObject.m_hTarget ) { // Ok we hit the fallback object reset some of our target data LTVector vObjPos; g_pLTClient->GetObjectPos(g_adFallbackActivationObject.m_hTarget, &vObjPos); m_ActivationData.m_vIntersect = vObjPos; vObjPos -= vPos; if (vObjPos.Mag() <= kMaxDistance) { m_hTarget = g_adFallbackActivationObject.m_hTarget; m_ActivationData.m_hTarget = m_hTarget; } // Calculate how far away the object is... LTVector vDist = m_ActivationData.m_vIntersect - vPos; fDistAway = vDist.Mag(); } }