void CPlayerStateSwim_WaterTestProxy::RayTestBottomLevel( const CPlayer& player, const Vec3& referencePosition, float maxRelevantDepth ) { FUNCTION_PROFILER(gEnv->pSystem, PROFILE_GAME); const float terrainWorldZ = gEnv->p3DEngine->GetTerrainElevation(referencePosition.x, referencePosition.y); int rayFlags = geom_colltype_player<<rwi_colltype_bit | rwi_stop_at_pierceable; int entityFlags = ent_terrain|ent_static|ent_sleeping_rigid|ent_rigid; const float padding = 0.2f; // NOTE: Terrain is above m_referencePos, so m_referencePos is probably inside a voxel or something. const float fPosWorldDiff = referencePosition.z - terrainWorldZ; float rayLength = (float)__fsel(fPosWorldDiff, min(maxRelevantDepth, fPosWorldDiff), maxRelevantDepth) + (padding * 2.0f); //We should not have entered this function if still waiting for the last result CRY_ASSERT(m_bottomLevelRayID == 0); m_bottomLevelRayID = g_pGame->GetRayCaster().Queue( player.IsClient() ? RayCastRequest::HighPriority : RayCastRequest::MediumPriority, RayCastRequest(referencePosition + Vec3(0,0,padding), Vec3(0,0,-rayLength), entityFlags, rayFlags, 0, 0), functor(*this, &CPlayerStateSwim_WaterTestProxy::OnRayCastBottomLevelDataReceived)); }
void CCinematicInput::UpdateWeapons() { CWeapon* pPrimaryWeapon = GetWeapon(eWeapon_Primary); CWeapon* pSecondaryWeapon = GetWeapon(eWeapon_Secondary); const bool doUpdate = (pPrimaryWeapon != NULL) || (pSecondaryWeapon != NULL); if (doUpdate) { const CCamera& camera = gEnv->pSystem->GetViewCamera(); const Vec3 viewPosition = camera.GetPosition(); const Vec3 viewDirection = camera.GetViewdir(); // Update raycast if (m_aimingRayID == 0) { IEntity *pIgnoredEntity = gEnv->pEntitySystem->GetEntity(m_weapons[eWeapon_Primary].m_parentId); IEntity *pIgnoredEntity2 = gEnv->pEntitySystem->GetEntity(m_weapons[eWeapon_Secondary].m_parentId); int ignoreCount = 0; IPhysicalEntity *pIgnoredEntityPhysics[2] = { NULL, NULL }; if (pIgnoredEntity) { pIgnoredEntityPhysics[ignoreCount] = pIgnoredEntity->GetPhysics(); ignoreCount += pIgnoredEntityPhysics[ignoreCount] ? 1 : 0; } if (pIgnoredEntity2 && (pIgnoredEntity2 != pIgnoredEntity)) { pIgnoredEntityPhysics[ignoreCount] = pIgnoredEntity2->GetPhysics(); ignoreCount += pIgnoredEntityPhysics[ignoreCount] ? 1 : 0; } m_aimingRayID = g_pGame->GetRayCaster().Queue( RayCastRequest::HighestPriority, RayCastRequest(viewPosition, viewDirection * CINEMATIC_INPUT_MAX_AIM_DISTANCE, ent_all|ent_water, rwi_stop_at_pierceable|rwi_ignore_back_faces, pIgnoredEntityPhysics, ignoreCount), functor(*this, &CCinematicInput::OnRayCastDataReceived)); } // Update weapon orientation const Vec3 aimTargetPosition = viewPosition + (viewDirection * m_aimingDistance); if (pPrimaryWeapon != NULL) { UpdateWeaponOrientation( pPrimaryWeapon->GetEntity(), aimTargetPosition ); } if (pSecondaryWeapon != NULL) { UpdateWeaponOrientation( pSecondaryWeapon->GetEntity(), aimTargetPosition ); } } }
//-------------------------------------------------------------------------------------------------- // Name: QueueMaterialEffect // Desc: Queues material effect and sets off a deferred linetest for later processing //-------------------------------------------------------------------------------------------------- void CExplosionGameEffect::QueueMaterialEffect(SExplosionContainer &explosionContainer) { ExplosionInfo explosionInfo = explosionContainer.m_explosionInfo; // If an effect was already specified, don't use MFX if(explosionInfo.pParticleEffect) return; const int intersectionObjTypes = ent_all|ent_water; const unsigned int intersectionFlags = rwi_stop_at_pierceable|rwi_colltype_any; CRY_ASSERT(explosionContainer.m_mfxInfo.m_rayId == 0); if(explosionInfo.impact) { Vec3 explosionDir = explosionInfo.impact_velocity.normalized(); explosionContainer.m_mfxInfo.m_rayId = g_pGame->GetRayCaster().Queue( RayCastRequest::HighPriority, RayCastRequest(explosionInfo.pos-explosionDir*0.1f, explosionDir, intersectionObjTypes, intersectionFlags), functor(explosionContainer.m_mfxInfo, &SDeferredMfxExplosion::OnRayCastDataReceived)); } else { const Vec3 explosionDir(0.0f, 0.0f, -g_pGameCVars->g_explosion_materialFX_raycastLength); explosionContainer.m_mfxInfo.m_rayId = g_pGame->GetRayCaster().Queue( RayCastRequest::HighPriority, RayCastRequest(explosionInfo.pos, explosionDir, intersectionObjTypes, intersectionFlags), functor(explosionContainer.m_mfxInfo, &SDeferredMfxExplosion::OnRayCastDataReceived)); } explosionContainer.m_mfxInfo.m_state = eDeferredMfxExplosionState_Dispatched; }
void StalkerModule::QueueLineOfSightRay(Agent& stalker, IAIObject* target, StalkerInstance& instance) { PhysSkipList skipList; stalker.GetPhysicalSkipEntities(skipList); if (IAIActor* aiActor = target->CastToIAIActor()) aiActor->GetPhysicalSkipEntities(skipList); instance.rayID = g_pGame->GetRayCaster().Queue( RayCastRequest::HighPriority, RayCastRequest(target->GetPos(), stalker.GetPos() - target->GetPos(), ent_terrain|ent_static|ent_rigid|ent_sleeping_rigid, ((geom_colltype_ray << rwi_colltype_bit) | rwi_colltype_any | (10 & rwi_pierceability_mask)), &skipList[0], skipList.size()), functor(*this, &StalkerModule::LineOfSightRayComplete)); }
const Vec3& CPlayerRotation::SLeanAndPeekInfo::GetLeanLimit( const Vec3 &startPos, const Vec3 &dir, int objTypes, int flags, IPhysicalEntity **pSkipEnts /*= NULL*/, int nSkipEnts /*= 0*/ ) { //Only queue ray cast if not waiting for another one if (m_queuedRayID == 0) { m_queuedRayID = g_pGame->GetRayCaster().Queue( RayCastRequest::MediumPriority, RayCastRequest(startPos, dir, objTypes, flags, pSkipEnts, nSkipEnts), functor(*this, &SLeanAndPeekInfo::OnRayCastDataReceived)); } return m_lastLimit; }
void CWeaponCheck::CastRays() { IActor* pActor = gEnv->pGame->GetIGameFramework()->GetClientActor(); CPlayer* pPlayer = pActor ? static_cast<CPlayer*>(pActor) : NULL; if( !pPlayer ) { m_closestDist = 10000.f; return; } m_closestDist = m_closestCastDist; m_closestCastDist = 10000.f; m_numFramesWaiting = m_numResults = 0; const CCamera& camera = gEnv->pRenderer->GetCamera(); Vec3 camPos = camera.GetPosition(); Ang3 angles = camera.GetAngles(); Vec3 rayDirs[Stereo3D::Weapon::MAX_RAY_IDS] = { gEnv->pRenderer->GetCamera().GetViewdir(), Quat::CreateRotationXYZ(Ang3(angles.y - camera.GetFov() * 0.25f,angles.z - camera.GetHorizontalFov() * 0.25f,angles.x)).GetColumn1(), Quat::CreateRotationXYZ(Ang3(angles.y,angles.z + camera.GetHorizontalFov() * 0.25f,angles.x)).GetColumn1(), Quat::CreateRotationXYZ(Ang3(angles.y,angles.z - camera.GetHorizontalFov() * 0.25f,angles.x)).GetColumn1(), Quat::CreateRotationXYZ(Ang3(angles.y - camera.GetFov() * 0.25f,angles.z + camera.GetHorizontalFov() * 0.25f,angles.x)).GetColumn1(), }; IPhysicalEntity *pTargetPhysics = pPlayer->GetEntity()->GetPhysics(); for ( int i = 0; i < Stereo3D::Weapon::MAX_RAY_IDS; ++i ) { if ( m_rayIDs[i] != Stereo3D::Weapon::INVALID_RAY_ID ) { g_pGame->GetRayCaster().Cancel(m_rayIDs[i]); } m_rayIDs[i] = g_pGame->GetRayCaster().Queue(RayCastRequest::MediumPriority, RayCastRequest(camPos, rayDirs[i] * 3, ent_all, rwi_stop_at_pierceable|rwi_ignore_back_faces, pTargetPhysics ? &pTargetPhysics : 0, pTargetPhysics ? 1 : 0), functor(*this, &CWeaponCheck::OnRayCastResult)); } }
void CDeferredExplosionEffect::RequestRayCast( CDeferredExplosionEffect::EDeferredEffectType effectType, const Vec3 &startPos, const Vec3 &dir, float distance, float effectMaxDistance, int objTypes, int flags, IPhysicalEntity **pSkipEnts, int nSkipEnts ) { FreeOldestRequestIfNeeded(); SQueuedRayInfo requestedRay; requestedRay.effectType = effectType; requestedRay.effectMaxDistance = effectMaxDistance; requestedRay.distance = distance; requestedRay.explosionPos = startPos; requestedRay.request = ++m_requestCounter; requestedRay.rayID = g_pGame->GetRayCaster().Queue( RayCastRequest::HighPriority, RayCastRequest(startPos, dir * distance, objTypes, flags, pSkipEnts, nSkipEnts), functor(*this, &CDeferredExplosionEffect::OnRayCastDataReceived)); m_queuedRays.push_back(requestedRay); }
void CLaserBeam::UpdateLaser(const CLaserBeam::SLaserUpdateDesc& laserUpdateDesc) { if(m_pLaserParams && m_laserOn) { IEntity* pLaserEntity = CreateLaserEntity(); if (pLaserEntity) { m_lastLaserUpdatePosition = laserUpdateDesc.m_laserPos; m_lastLaserUpdateDirection = laserUpdateDesc.m_laserDir; m_laserUpdateTimer += laserUpdateDesc.m_frameTime; UpdateLaserGeometry(*pLaserEntity); if(m_laserUpdateTimer < LASER_UPDATE_TIME) return; m_laserUpdateTimer = Random(0.0f, LASER_UPDATE_TIME * 0.4f); if ((laserUpdateDesc.m_ownerCloaked && !laserUpdateDesc.m_weaponZoomed) || laserUpdateDesc.m_bOwnerHidden) { pLaserEntity->Hide(true); return; } pLaserEntity->Hide(false); const float range = m_pLaserParams->laser_range[GetIndexFromGeometrySlot()]; // Use the same flags as the AI system uses for visbility. const int objects = ent_terrain|ent_static|ent_rigid|ent_sleeping_rigid|ent_independent; //ent_living; const int flags = (geom_colltype_ray << rwi_colltype_bit) | rwi_colltype_any | (10 & rwi_pierceability_mask) | (geom_colltype14 << rwi_colltype_bit); //If we did not get a result, just cancel it, we will queue a new one again RayCastRequest::Priority requestPriority = RayCastRequest::MediumPriority; if (m_queuedRayId != 0) { g_pGame->GetRayCaster().Cancel(m_queuedRayId); m_queuedRayId = 0; requestPriority = RayCastRequest::HighPriority; } IItemSystem* pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem(); IPhysicalEntity* pSkipEntity = NULL; uint8 numSkips = 0; CItem* pItem = static_cast<CItem*>(pItemSystem->GetItem(m_ownerEntityId)); if(pItem) { if(pItem->IsAccessory()) { CItem* pParentItem = static_cast<CItem*>(pItemSystem->GetItem(pItem->GetParentId())); if(pParentItem) { pItem = pParentItem; } } IEntity* pOwnerEnt = 0; CWeapon* pWeapon = static_cast<CWeapon*>(pItem->GetIWeapon()); if (pWeapon && pWeapon->GetHostId() != 0) { pOwnerEnt = gEnv->pEntitySystem->GetEntity(pWeapon->GetHostId()); } else { pOwnerEnt = pItem->GetOwner(); } if(pOwnerEnt) { IPhysicalEntity* pOwnerPhysics = pOwnerEnt->GetPhysics(); if(pOwnerPhysics) { pSkipEntity = pOwnerPhysics; numSkips++; } } } m_queuedRayId = g_pGame->GetRayCaster().Queue( requestPriority, RayCastRequest(laserUpdateDesc.m_laserPos, laserUpdateDesc.m_laserDir*range, objects, flags, &pSkipEntity, numSkips), functor(*this, &CLaserBeam::OnRayCastDataReceived)); } } else if (!m_pLaserParams) { GameWarning("LASER PARAMS: Item of type CLaser is missing it's laser params!"); } }
QueuedRayID CCameraRayScan::ShootRay(const Vec3 &rayPos, const Vec3 &rayDir, int objTypes /*= g_objTypes*/, int geomFlags /*= g_geomFlags*/, IPhysicalEntity **pSkipEnts /*= NULL*/, int numSkipEnts /*= 0*/) { return g_pGame->GetRayCaster().Queue(RayCastRequest::MediumPriority, RayCastRequest(rayPos, rayDir, objTypes, geomFlags, pSkipEnts, numSkipEnts), functor(*this, &CCameraRayScan::OnRayCastResult)); }
void CPlayerVisTable::DoVisibilityCheck(const Vec3& localPlayerPosn, SVisTableEntry& visInfo, VisEntryIndex visIndex) { Vec3 vecToTarget; IEntity * pEntity = gEnv->pEntitySystem->GetEntity(visInfo.entityId); if(pEntity) { IPhysicalEntity* pTargetPhysEnt = pEntity->GetPhysics(); SDeferredLinetestBuffer& targetBuffer = m_linetestBuffers[GetCurrentLinetestBufferTargetIndex()]; if(targetBuffer.m_numLinetestsCurrentlyProcessing < kMaxVisTableLinetestsPerFrame) { visInfo.framesSinceLastCheck = 0; SDeferredLinetestReceiver * processingEntry = GetAvailableDeferredLinetestReceiver(targetBuffer); assert(processingEntry); Vec3 targetPosn = pEntity->GetWorldPos(); if (visInfo.flags & eVF_CheckAgainstCenter) { AABB targetBbox; pEntity->GetWorldBounds(targetBbox); if (!targetBbox.IsEmpty()) { targetPosn = targetBbox.GetCenter(); } float radius = min(min(targetBbox.max.x-targetBbox.min.x, targetBbox.max.y-targetBbox.min.y), targetBbox.max.z-targetBbox.min.z); targetPosn += (localPlayerPosn-targetPosn).GetNormalized() * radius * 0.25f; } targetPosn.z += visInfo.heightOffset; vecToTarget = targetPosn - localPlayerPosn; processingEntry->visTableIndex = visIndex; ray_hit hit; const int rayFlags = rwi_colltype_any(geom_colltype_solid&(~geom_colltype_player)) | rwi_ignore_noncolliding | rwi_pierceability(PIERCE_GLASS); m_numLinetestsThisFrame++; targetBuffer.m_numLinetestsCurrentlyProcessing++; visInfo.flags |= eVF_Pending; visInfo.flags &= ~eVF_CheckAgainstCenter; processingEntry->visBufferIndex = m_currentBufferTarget; const int numEntries = kMaxNumIgnoreEntities + 1; IPhysicalEntity* pSkipEnts[numEntries]; int numSkipEnts = 0; if(pTargetPhysEnt) { pSkipEnts[numSkipEnts] = pTargetPhysEnt; numSkipEnts++; } if (m_currentNumIgnoreEntities) { for(int i = 0; i < m_currentNumIgnoreEntities; ++i) { SIgnoreEntity& ignoreEnt = m_globalIgnoreEntities[i]; CRY_ASSERT(ignoreEnt.id); IEntity* pIgnoreEntity = gEnv->pEntitySystem->GetEntity(ignoreEnt.id); IPhysicalEntity* pIgnorePhysicsEntity = pIgnoreEntity ? pIgnoreEntity->GetPhysics() : NULL; if (pIgnorePhysicsEntity) { pSkipEnts[numSkipEnts] = pIgnorePhysicsEntity; numSkipEnts++; } } } CRY_ASSERT(processingEntry->queuedRayID == 0); processingEntry->queuedRayID = g_pGame->GetRayCaster().Queue( RayCastRequest::HighPriority, RayCastRequest(localPlayerPosn, vecToTarget, ent_terrain|ent_static|ent_sleeping_rigid|ent_rigid, rayFlags, pSkipEnts, numSkipEnts, 2), functor(*processingEntry, &SDeferredLinetestReceiver::OnDataReceived)); #if ALLOW_VISTABLE_DEBUGGING m_debugDraw.UpdateDebugTarget(visInfo.entityId, targetPosn, ((visInfo.flags & eVF_Visible) != 0)); #endif } } else { visInfo.flags |= eVF_Remove; } }