Ejemplo n.º 1
0
CEntity* CEntityPool::GetEntityFromPool(bool &outIsActive, EntityId forcedPoolId /*= 0*/)
{
	FUNCTION_PROFILER(GetISystem(), PROFILE_ENTITY);

	CEntity* pPoolEntity = NULL;

	if (forcedPoolId > 0)
	{
		pPoolEntity = GetPoolEntityWithPoolId(outIsActive, forcedPoolId);
	}

	if (!pPoolEntity)
	{
		pPoolEntity = GetPoolEntityFromInactiveSet();
		if (pPoolEntity)
			outIsActive = false;
	}

	if (!pPoolEntity)
	{
		pPoolEntity = GetPoolEntityFromActiveSet();
		if (pPoolEntity)
			outIsActive = true;
	}

	if (!pPoolEntity)
	{
		CRY_ASSERT_MESSAGE(false, "CEntityPool::GetEntityFromPool() Creating new entity for pool usage at run-time. Pool was too small!");
		EntityWarning("[Entity Pool] Pool \'%s\' was too small. A new entity had to be created at run-time. Consider increasing the pool size.", m_sName.c_str());

#ifdef ENTITY_POOL_DEBUGGING
		m_bDebug_HasExpanded = true;
#endif //ENTITY_POOL_DEBUGGING

		// Make sure not to go above the max size
		if (m_uMaxSize > 0 && m_InactivePoolIds.size() + m_ActivePoolIds.size() < m_uMaxSize)
		{
			// Make a new one
			if (!CreatePoolEntity(pPoolEntity, false))
			{
				CRY_ASSERT_MESSAGE(false, "CEntityPool::GetEntityFromPool() Failed when creating a new pool entity.");
			}
		}
		else
		{
			CRY_ASSERT_MESSAGE(false, "CEntityPool::GetEntityFromPool() Have to create a new pool entity but am already at max size!");
			EntityWarning("[Entity Pool] Pool \'%s\' has reached its max size and a new entity was requested. The new entity was not created!", m_sName.c_str());
		}

		outIsActive = false;
	}

	return pPoolEntity;
}
Ejemplo n.º 2
0
void CEntityObject::OnXForm( CEntity* pEntity )
{
	UpdateWorldTM(pEntity);

	if (!m_worldTM.IsValid())
	{
		EntityWarning("CEntityObject::OnXForm: Invalid world matrix: %s", pEntity->GetEntityTextDescription());
		return;
	}

	if (pLight)
	{
		ILightSource* pLightSource = pLight;
		// Update light positions.
		CDLight* pDLight = &pLightSource->GetLightProperties();

		pDLight->SetPosition( m_worldTM.GetTranslation());
		pDLight->SetMatrix(m_worldTM);
		pDLight->m_sName     = pEntity->GetName(); // For debugging only.
		pDLight->m_nEntityId = pEntity->GetId();
		pEntity->UpdateLightClipBounds(*pDLight);
		pLightSource->SetMatrix(m_worldTM);
		pLight->SetSrcEntity(pEntity);
	}
	else if (pChildRenderNode)
	{
		pChildRenderNode->SetMatrix( m_worldTM );
	}
}
Ejemplo n.º 3
0
CEntity* CEntityPool::GetPoolEntityFromActiveSet()
{
	FUNCTION_PROFILER(GetISystem(), PROFILE_ENTITY);

	assert(!gEnv->IsEditor());

	CEntity* pPoolEntity = NULL;

	assert(m_pEntityPoolManager);
	CEntitySystem* pEntitySystem = m_pEntityPoolManager->GetEntitySystem();

	const uint32 uActiveSize = m_ActivePoolIds.size();
	const bool   bAtMax      = (m_uMaxSize > 0 && uActiveSize >= m_uMaxSize);
	m_ReturnToPoolWeights.clear();
	m_ReturnToPoolWeights.reserve(m_ActivePoolIds.size());

	// Go through the active list and ask if any are available for removal
	TPoolIdsVec::iterator itPoolSlot    = m_ActivePoolIds.begin();
	TPoolIdsVec::iterator itPoolSlotEnd = m_ActivePoolIds.end();
	for (; itPoolSlot != itPoolSlotEnd; ++itPoolSlot)
	{
		CEntity* pEntity = (CEntity*)pEntitySystem->GetEntity(itPoolSlot->usingId);
		if (!pEntity)
		{
			CRY_ASSERT_MESSAGE(pEntity, "NULL Pool Entity in Active set");
			continue;
		}

		SReturnToPoolWeight returnToPoolWeight;
		returnToPoolWeight.pEntity = pEntity;
		returnToPoolWeight.weight  = m_pEntityPoolManager->GetReturnToPoolWeight(pEntity, bAtMax);
		m_ReturnToPoolWeights.push_back(returnToPoolWeight);
	}

	// Sort and use top if weight > 0
	if (!m_ReturnToPoolWeights.empty())
	{
		std::sort(m_ReturnToPoolWeights.begin(), m_ReturnToPoolWeights.end());
		SReturnToPoolWeight &bestEntry = m_ReturnToPoolWeights.front();

		if (bestEntry.weight > FLT_EPSILON)
		{
			pPoolEntity = bestEntry.pEntity;

#ifdef ENTITY_POOL_DEBUGGING
			if (bAtMax)
			{
				++m_iDebug_TakenFromActiveForced;
				EntityWarning("[Entity Pool] Pool \'%s\' has reached its max size and a new entity was requested. An entity from the active set was forced to be reused: \'%s\' (%d)",
				              m_sName.c_str(), pPoolEntity->GetName(), m_iDebug_TakenFromActiveForced);
			}
#endif //ENTITY_POOL_DEBUGGING
		}
	}

	return pPoolEntity;
}
Ejemplo n.º 4
0
bool CScriptProxy::GotoState( const char* sStateName )
{
	int nStateId = m_pScript->GetStateId( sStateName );
	if (nStateId >= 0)
	{
		GotoState( nStateId );
	}
	else
	{
		EntityWarning( "GotoState called with unknown state %s, in entity %s",sStateName,m_pEntity->GetEntityTextDescription());
		return false;
	}
	return true;
}
Ejemplo n.º 5
0
void CEntityClassRegistry::LoadClassDescription( XmlNodeRef &root,bool bOnlyNewClasses )
{
	assert( root != (IXmlNode*)NULL );
	if (root->isTag("Entity"))
	{
		const char *sName = root->getAttr("Name");
		if (*sName == 0)
			return; // Empty name.

		const char *sScript = root->getAttr("Script");

		IEntityClass *pClass = FindClass( sName );
		if (!pClass)
		{
			// New class.
			SEntityClassDesc cd;
			cd.flags = 0;
			cd.sName = sName;
			cd.sScriptFile = sScript;

			bool bInvisible = false;
			if (root->getAttr("Invisible",bInvisible))
			{
				if (bInvisible)
					cd.flags |= ECLF_INVISIBLE;
			}

			bool bBBoxSelection = false;
			if (root->getAttr("BBoxSelection",bBBoxSelection))
			{
				if (bBBoxSelection)
					cd.flags |= ECLF_BBOX_SELECTION;
			}

			RegisterStdClass( cd );
		}
		else
		{
			// This class already registered.
			if (!bOnlyNewClasses)
			{
				EntityWarning( "[CEntityClassRegistry] LoadClassDescription failed, Entity Class name %s already registered",sName );
			}
		}
	}
}
Ejemplo n.º 6
0
IEntityClass* CEntityClassRegistry::RegisterStdClass( const SEntityClassDesc &entityClassDesc )
{
	// Creates a new entity class.
	CEntityClass *pClass = new CEntityClass;
	pClass->SetName(entityClassDesc.sName);
	pClass->SetFlags(entityClassDesc.flags);
	pClass->SetScriptFile(entityClassDesc.sScriptFile);
	pClass->SetUserProxyCreateFunc(entityClassDesc.pUserProxyCreateFunc, entityClassDesc.pUserProxyData);
	pClass->SetPropertyHandler(entityClassDesc.pPropertyHandler);
	pClass->SetEventHandler(entityClassDesc.pEventHandler);
	pClass->SetScriptFileHandler(entityClassDesc.pScriptFileHandler);
	pClass->SetEditorClassInfo(entityClassDesc.editorClassInfo);
	pClass->SetClassAttributes(entityClassDesc.classAttributes);
	pClass->SetEntityAttributes(entityClassDesc.entityAttributes);

	// Check if need to create entity script.
	if (entityClassDesc.sScriptFile[0] || entityClassDesc.pScriptTable)
	{
		// Create a new entity script.
		CEntityScript *pScript = new CEntityScript;
		bool ok = false;
		if(entityClassDesc.sScriptFile[0])
			ok = pScript->Init(entityClassDesc.sName,entityClassDesc.sScriptFile);
		else 
			ok = pScript->Init(entityClassDesc.sName, entityClassDesc.pScriptTable);
		
		if(!ok)
		{
			EntityWarning( "EntityScript %s failed to initialize",entityClassDesc.sScriptFile );
			pScript->Release();
			pClass->Release();
			return NULL;
		}
		pClass->SetEntityScript( pScript );
	}

	if (!RegisterEntityClass( pClass ))
	{
		// Register class failed.
		pClass->Release();
		return NULL;
	}
	return pClass;
}
Ejemplo n.º 7
0
bool CEntityClassRegistry::RegisterEntityClass( IEntityClass *pClass )
{
	assert( pClass != NULL );

	bool	newClass = false;
	if ((pClass->GetFlags() & ECLF_MODIFY_EXISTING) == 0)
	{
		IEntityClass *pOldClass = FindClass(pClass->GetName());
		if (pOldClass)
		{
			EntityWarning( "CEntityClassRegistry::RegisterEntityClass failed, class with name %s already registered",
				pOldClass->GetName() );
			return false;
		}
		newClass = true;
	}
	m_mapClassName[pClass->GetName()] = pClass;
	NotifyListeners(newClass ? ECRE_CLASS_REGISTERED : ECRE_CLASS_MODIFIED, pClass);
	return true;
}
Ejemplo n.º 8
0
bool CEntityPool::ContainsEntityClass(IEntityClass* pClass) const
{
	FUNCTION_PROFILER(GetISystem(), PROFILE_ENTITY);

	bool bClassValid = false;

	assert(m_pEntityPoolManager);

	TPoolDefinitionIds::const_iterator itDefinitionId    = m_PoolDefinitionIds.begin();
	TPoolDefinitionIds::const_iterator itDefinitionIdEnd = m_PoolDefinitionIds.end();
	for (; !bClassValid && itDefinitionId != itDefinitionIdEnd; ++itDefinitionId)
	{
		const TEntityPoolDefinitionId definitionId = *itDefinitionId;

		const CEntityPoolDefinition* pDefinition = m_pEntityPoolManager->GetEntityPoolDefinition(definitionId);
		bClassValid = pDefinition && pDefinition->ContainsEntityClass(pClass);

#ifdef ENTITY_POOL_SIGNATURE_TESTING
		if (bClassValid && CVar::es_TestPoolSignatures != 0)
		{
			assert(m_pEntityPoolManager);
			CEntitySystem* pEntitySystem = m_pEntityPoolManager->GetEntitySystem();

			// Perform signature test on it to be sure by really spawning one
			bClassValid = pDefinition->TestEntityClassSignature(pEntitySystem, pClass, m_Signature);
			if (bClassValid)
			{
				CryLog("[Entity Pool] DEBUG: Signature passed for class \'%s\' to use Pool \'%s\'", pClass->GetName(), m_sName.c_str());
			}
			else
			{
				EntityWarning("[Entity Pool] WARNING: DEBUG: Signature test failed for class \'%s\' using Pool \'%s\'", pClass->GetName(), m_sName.c_str());
				continue;
			}
		}
#endif //ENTITY_POOL_SIGNATURE_TESTING
	}

	return bClassValid;
}
Ejemplo n.º 9
0
bool CEntityPool::CreatePool(const CEntityPoolDefinition &definition)
{
	FUNCTION_PROFILER(GetISystem(), PROFILE_ENTITY);

	assert(!gEnv->IsEditor());

	MEMSTAT_CONTEXT_FMT(EMemStatContextTypes::MSC_Other, EMemStatContextFlags::MSF_Instance, "Create Pool %s", definition.GetName().c_str());

	m_sDefaultClass     = definition.GetDefaultClass();
	m_sName             = definition.GetName();
	m_bDefinitionHasAI |= definition.HasAI();
	m_uMaxSize          = definition.GetMaxSize();
	const uint32 uCount = definition.GetDesiredPoolCount();

	m_InactivePoolIds.reserve(uCount);

	CEntity* pPoolEntity = NULL;
	bool     bResult     = (CreatePoolEntity(pPoolEntity) && m_Signature.CalculateFromEntity(pPoolEntity));
	if (bResult)
	{
		// Already created one, so create the remaining..
		for (uint32 i = 1; i < uCount; ++i)
		{
			bResult &= CreatePoolEntity(pPoolEntity);
		}

		m_PoolDefinitionIds.push_back(definition.GetId());
	}

	if (!bResult)
	{
		EntityWarning("CEntityPool::CreatePool() Failed when prepairing the Pool for the default class \'%s\'", m_sDefaultClass.c_str());
	}

	return bResult;
}
Ejemplo n.º 10
0
void CEntityObject::Render( CEntity* pEntity,SRendParams &rParams,int nRndFlags,CRenderProxy* pRenderProxy, const SRenderingPassInfo &passInfo )
{
	if (!bWorldTMValid)
	{
		UpdateWorldTM(pEntity);
	}

	// Override with custom slot material.
	IMaterial* pPrevMtl = rParams.pMaterial;
	if (pMaterial)
		rParams.pMaterial = pMaterial;

	int32 nOldObjectFlags = rParams.dwFObjFlags;
	rParams.dwFObjFlags |= dwFObjFlags;


	if (flags & ENTITY_SLOT_RENDER_AFTER_POSTPROCESSING)
	{
		rParams.dwFObjFlags |= FOB_RENDER_AFTER_POSTPROCESSING;
	}

#ifdef SEG_WORLD
	rParams.nCustomFlags |= (1 << (COB_SW_SHIFT + pEntity->GetSwObjDebugFlag()));
#endif // SEG_WORLD

	//////////////////////////////////////////////////////////////////////////

	rParams.pInstance = this;

	const bool bIsInCameraSpace = (flags & ENTITY_SLOT_RENDER_NEAREST) != 0;

	// Draw static object.
	if (pStatObj)
	{
		rParams.pMatrix      = &m_worldTM;
		rParams.dwFObjFlags |= FOB_TRANS_MASK;
		rParams.pFoliage     = pFoliage;

		rParams.nSubObjHideMask = nSubObjHideMask;

		// make sure object motion blur can be applied to this object
		if (bObjectMoved)
		{
			rParams.dwFObjFlags |= FOB_DYNAMIC_OBJECT;
			bObjectMoved         = false;
		}

		Matrix34 entityTM;
		if (bIsInCameraSpace)
		{
			rParams.pMatrix = &entityTM;
			entityTM        = m_worldTM;

			// Camera space
			if (m_pCameraSpacePos)
			{
				// Use camera space relative position
				entityTM.SetTranslation(*m_pCameraSpacePos);
			}
			else
			{
				// We don't have camera space relative position, so calculate it out from world space
				// (This will not have the precision advantages of camera space rendering)
				entityTM.AddTranslation(-gEnv->pSystem->GetViewCamera().GetPosition());
			}
		}

		if (rParams.pMatrix->IsValid())
			pStatObj->Render( rParams, passInfo );
		else
			EntityWarning("CEntityObject::Render: Invalid world matrix: %s", pEntity->GetEntityTextDescription());
	}
	else if (pCharacter)
	{
		QuatTS   Offset;
		Matrix34 PhysLocation(pEntity->GetWorldTM());
		if (m_pXForm)
			Offset = QuatTS(m_pXForm->localTM);
		else
		{
			//CRY_FIXME(03,12,2009,"Animation & Rendering of entities needs to be re-written to avoid derivation of local offset due to float inaccuracy - Richard Semmens");

			if (!Matrix34::IsEquivalent(PhysLocation,m_worldTM))
			{
				Matrix34 invPhysLocation = PhysLocation.GetInverted();

				Matrix34 matOffset = invPhysLocation * m_worldTM;

				Offset = QuatTS(matOffset);
			}
			else
			{
				Offset.SetIdentity();
			}
		}

		if (bIsInCameraSpace)
		{
			// Camera space
			if (m_pCameraSpacePos)
			{
				// Use camera space relative position
				const Matrix33 camRot = Matrix33(gEnv->pSystem->GetViewCamera().GetViewMatrix());
				PhysLocation.SetTranslation(*m_pCameraSpacePos * camRot);
			}
			else
			{
				// We don't have camera space relative position, so calculate it out from world space
				// (This will not have the precision advantages of camera space rendering)
				PhysLocation.AddTranslation(-gEnv->pSystem->GetViewCamera().GetPosition());
			}
			Offset.SetIdentity();
		}

		rParams.pMatrix = &PhysLocation;
		//rParams.pInstance = pCharacter;

		// Disable hand-placed (static) decals on characters
		rParams.dwFObjFlags |= FOB_DYNAMIC_OBJECT;

		pCharacter->Render(rParams, Offset, passInfo);

		const uint32 renderProxyFlags = pRenderProxy->GetFlags();
		if (!passInfo.IsShadowPass() || (renderProxyFlags & CRenderProxy::FLAG_ANIMATE_OFFSCREEN_SHADOW))
		{
			// If We render character, make sure it is also gets animation activated.
			if (!pEntity->m_bInActiveList)
				pEntity->ActivateForNumUpdates(8);
		}
	}
	else if (pChildRenderNode)
	{
		rParams.pMatrix = &m_worldTM;
		//rParams.pInstance = pChildRenderNode;

		pChildRenderNode->m_dwRndFlags = nRndFlags;
		pChildRenderNode->Render( rParams, passInfo );
	}

	rParams.pMaterial   = pPrevMtl;
	rParams.dwFObjFlags = nOldObjectFlags;

	if (!passInfo.IsShadowPass())   // Should also ignore rendering into the recursion.
	{
		if (pFoliage)
		{
			pFoliage->SetFlags(pFoliage->GetFlags() & ~IFoliage::FLAG_FROZEN | -(int)(rParams.nMaterialLayers & MTL_LAYER_FROZEN) & IFoliage::FLAG_FROZEN);
			static ICVar* g_pWindActivationDist = gEnv->pConsole->GetCVar("e_FoliageWindActivationDist");
			float         maxdist               = g_pWindActivationDist ? g_pWindActivationDist->GetFVal() : 0.0f;
			Vec3          pos                   = m_worldTM.GetTranslation();
			if (pStatObj && (gEnv->pSystem->GetViewCamera().GetPosition() - pos).len2() < sqr(maxdist) && gEnv->p3DEngine->GetWind(AABB(pos),false).len2() > 101.0f)
				pStatObj->PhysicalizeFoliage(pEntity->GetPhysics(),m_worldTM,pFoliage,0,4);
		}
	}
}
Ejemplo n.º 11
0
CEntity* CEntityPool::GetPoolEntityWithPoolId(bool &outIsActive, EntityId forcedPoolId)
{
	FUNCTION_PROFILER(GetISystem(), PROFILE_ENTITY);

	assert(!gEnv->IsEditor());

	CEntity* pPoolEntity = NULL;

	assert(m_pEntityPoolManager);
	CEntitySystem* pEntitySystem = m_pEntityPoolManager->GetEntitySystem();

	bool bFound = false;
	if (!bFound)
	{
		TPoolIdsVec::iterator itPoolSlot    = m_InactivePoolIds.begin();
		TPoolIdsVec::iterator itPoolSlotEnd = m_InactivePoolIds.end();
		for (; itPoolSlot != itPoolSlotEnd; ++itPoolSlot)
		{
			if (itPoolSlot->poolId == forcedPoolId)
			{
				pPoolEntity = (CEntity*)pEntitySystem->GetEntity(itPoolSlot->poolId);
				CRY_ASSERT_MESSAGE(pPoolEntity != NULL, "Found forcedPoolId in Inactive set, but it is NULL");

				outIsActive = false;
				bFound      = true;
				break;
			}
		}
	}
	if (!bFound)
	{
		TPoolIdsVec::iterator itPoolSlot    = m_ActivePoolIds.begin();
		TPoolIdsVec::iterator itPoolSlotEnd = m_ActivePoolIds.end();
		for (; itPoolSlot != itPoolSlotEnd; ++itPoolSlot)
		{
			if (itPoolSlot->poolId == forcedPoolId)
			{
				CEntity* pEntity = (CEntity*)pEntitySystem->GetEntity(itPoolSlot->poolId);
				assert(pEntity);
				if (!pEntity)
				{
					CRY_ASSERT_MESSAGE(false, "Found invalid pool entity (entity NULL).");
					EntityWarning("Found invalid pool entity (entity NULL).");
					continue;
				}

				// Don't use active ones
				if (m_pEntityPoolManager->GetReturnToPoolWeight(pEntity, true) <= 0.0f)
				{
					CRY_ASSERT_MESSAGE(false, "Found forcedPoolId in Active set, but it cannot be used");
				}
				else
				{
					pPoolEntity = pEntity;
				}

				outIsActive = true;
				bFound      = true;
				break;
			}
		}
	}

	return pPoolEntity;
}