bool CAreaManager::QueryAreas(EntityId const nEntityID, Vec3 const& rPos, SAreaManagerResult *pResults, int nMaxResults, int& rNumResults)
{
    rNumResults = 0;

    if (pResults)
    {
        // Make sure the area grid is recompiled, if needed, before accessing it
        UpdateDirtyAreas();

        uint32 numAreas = 0;
        TAreaPointers const& rAreasAtPos(m_areaGrid.GetAreas(rPos));
        TAreaPointers::const_iterator IterAreas(rAreasAtPos.begin());
        TAreaPointers::const_iterator const IterAreasEnd(rAreasAtPos.end());

        for (; IterAreas != IterAreasEnd; ++IterAreas)
        {
            CArea* const pArea = *IterAreas;

#if defined(DEBUG_AREAMANAGER)
            CheckArea(pArea);
#endif // DEBUG_AREAMANAGER

            // check if Area is hidden
            IEntity const* const pAreaEntity = m_pEntitySystem->GetEntity(pArea->GetEntityID());

            if (pAreaEntity && !pAreaEntity->IsHidden())
            {
                Vec3 Closest3d(ZERO);
                float const fGreatestFadeDistance = pArea->GetGreatestFadeDistance();

                // This is optimized internally and might not recalculate but rather retrieve the cached data.
                float const fDistanceSq = pArea->CalcPointNearDistSq(nEntityID, rPos, Closest3d, false);
                bool const bIsPointWithin = (pArea->CalcPosType(nEntityID, rPos, false) == AREA_POS_TYPE_2DINSIDE_ZINSIDE);
                bool const isNear = ((fDistanceSq > 0.0f) && (fDistanceSq < fGreatestFadeDistance*fGreatestFadeDistance));

                if (isNear || bIsPointWithin)
                {
                    // still have room to put it in?
                    if (rNumResults == nMaxResults)
                        return false;

                    // found area that should go into the results
                    pResults[rNumResults].pArea = pArea;
                    pResults[rNumResults].fDistanceSq = fDistanceSq;
                    pResults[rNumResults].vPosOnHull = Closest3d;
                    pResults[rNumResults].bInside = bIsPointWithin;
                    pResults[rNumResults].bNear = isNear;

                    ++rNumResults;
                }
            }
        }

        return true;
    }

    return false;
}
Exemple #2
0
void CAreaManager::Update()
{
	FUNCTION_PROFILER(GetISystem(), PROFILE_ENTITY);

	// Update the area grid data structure.
	UpdateDirtyAreas();

	if (!m_mapEntitiesToUpdate.empty())
	{
#if defined(INCLUDE_ENTITYSYSTEM_PRODUCTION_CODE)
		float const debugPosX = 650.0f;
		float debugPosY = 500.0f;
		float const fColor[4] = {0.0f, 1.0f, 0.0f, 0.7f};
		bool const bDrawDebug = CVar::pDrawAreaDebug->GetIVal() != 0;

		if (bDrawDebug)
		{
			gEnv->pRenderer->Draw2dLabel(debugPosX, debugPosY, 1.35f, fColor, false, "Entities to update: %d\n",  static_cast<int>(m_mapEntitiesToUpdate.size()));
			debugPosY += 12.0f;
		}
#endif // INCLUDE_ENTITYSYSTEM_PRODUCTION_CODE

		TEntitiesToUpdateMap::iterator Iter(m_mapEntitiesToUpdate.begin());
		TEntitiesToUpdateMap::const_iterator const IterEnd(m_mapEntitiesToUpdate.end());

		for (; Iter != IterEnd; ++Iter)
		{
			assert(Iter->second > 0);
			--(Iter->second);

			IEntity const* const pEntity = g_pIEntitySystem->GetEntity(Iter->first);

			if (pEntity != NULL)
			{
				// Add a Z offset of at least 0.11 to be slightly above the offset of 0.1 set through "CShapeObject::GetShapeZOffset".
				Vec3 const oPos = pEntity->GetWorldPos() + Vec3(0.0f, 0.0f, 0.11f);
				UpdateEntity(oPos, pEntity);

#if defined(INCLUDE_ENTITYSYSTEM_PRODUCTION_CODE)
				if (bDrawDebug)
				{
					gEnv->pRenderer->Draw2dLabel(debugPosX + 10.0f, debugPosY, 1.35f, fColor, false, "Entity: %d (%s) Pos: (%.2f, %.2f, %.2f)\n", Iter->first, pEntity ? pEntity->GetName() : "NULL", oPos.x, oPos.y, oPos.z);
					debugPosY += 12.0f;
				}
#endif // INCLUDE_ENTITYSYSTEM_PRODUCTION_CODE
			}
		}

		m_mapEntitiesToUpdate.erase_if(IsDoneUpdating);
	}
}
Exemple #3
0
bool CAreaManager::QueryAudioAreas(Vec3 const& rPos, SAudioAreaInfo *pResults, size_t const nMaxResults, size_t& rNumResults)
{
	rNumResults = 0;

	if (pResults != NULL)
	{
		// Make sure the area grid is recompiled, if needed, before accessing it
		UpdateDirtyAreas();

		uint32 numAreas = 0;
		TAreaPointers const& rAreasAtPos(m_areaGrid.GetAreas(rPos));
		TAreaPointers::const_iterator IterAreas(rAreasAtPos.begin());
		TAreaPointers::const_iterator const IterAreasEnd(rAreasAtPos.end());

		for (; IterAreas != IterAreasEnd; ++IterAreas)
		{
			CArea* const pArea = *IterAreas;

#if defined(DEBUG_AREAMANAGER)
			if (!stl::find(m_apAreas, pArea))
			{
				CryFatalError("<AreaManager>: area in entity-area-cache not found in overall areas list!");
			}
#endif // DEBUG_AREAMANAGER

			// check if Area is hidden
			IEntity const* const pAreaEntity = m_pEntitySystem->GetEntity(pArea->GetEntityID());

			if (pAreaEntity && !pAreaEntity->IsHidden())
			{
				size_t const nAttachedEntities = pArea->GetEntityAmount();

				if (nAttachedEntities > 0)
				{
					for (size_t iEntity = 0; iEntity < nAttachedEntities; ++iEntity)
					{
						IEntity const* const pEntity = gEnv->pEntitySystem->GetEntity(pArea->GetEntityByIdx(iEntity));

						if (pEntity != NULL)
						{
							IEntityAudioProxy const* const pAudioProxy = (IEntityAudioProxy*)pEntity->GetProxy(ENTITY_PROXY_AUDIO);

							if (pAudioProxy != NULL)
							{
								TAudioEnvironmentID const nEnvironmentID = pAudioProxy->GetEnvironmentID();
								float const fEnvironmentFadeDistance = pAudioProxy->GetEnvironmentFadeDistance();

								if (nEnvironmentID != INVALID_AUDIO_ENVIRONMENT_ID)
								{
									// This is optimized internally and might not recalculate but rather retrieve the cached data.
									bool const bIsPointWithin = (pArea->CalcPosType(INVALID_ENTITYID, rPos, false) == AREA_POS_TYPE_2DINSIDE_ZINSIDE);
									float fEnvironmentAmount = 0.0f;
									if (!bIsPointWithin && (fEnvironmentFadeDistance > 0.0f))
									{
										Vec3 Closest3d(ZERO);
										float const fDistance = sqrt_tpl(pArea->CalcPointNearDistSq(INVALID_ENTITYID, rPos, Closest3d, false));
										if (fDistance <= fEnvironmentFadeDistance)
										{
											fEnvironmentAmount = 1.0f - (fDistance/fEnvironmentFadeDistance);
										}
									}
									else
									{
										fEnvironmentAmount = 1.0f;
									}

									if (fEnvironmentAmount > 0.0f)
									{
										// still have room to put it in?
										if (rNumResults == nMaxResults)
											return false;

										// found area that should go into the results
										pResults[rNumResults].pArea									= pArea;
										pResults[rNumResults].fEnvironmentAmount		= fEnvironmentAmount;
										pResults[rNumResults].nEnvironmentID				= nEnvironmentID;
										pResults[rNumResults].nEnvProvidingEntityID	= pEntity->GetId();

										++rNumResults;
									}
								}
							}
						}
					}
				}
			}
		}
		return true;
	}

	return false;
}