Example #1
0
// This gets an AABB for the renderable, but it doesn't cause a parent's bones to be setup.
// This is used for placement in the leaves, but the more expensive version is used for culling.
void CalcRenderableWorldSpaceAABB_Fast( IClientRenderable *pRenderable, Vector &absMin, Vector &absMax )
{
	C_BaseEntity *pEnt = pRenderable->GetIClientUnknown()->GetBaseEntity();
	if ( pEnt && pEnt->IsFollowingEntity() )
	{
		C_BaseEntity *pParent = pEnt->GetMoveParent();
		Assert( pParent );

		// Get the parent's abs space world bounds.
		CalcRenderableWorldSpaceAABB_Fast( pParent, absMin, absMax );

		// Add the maximum of our local render bounds. This is making the assumption that we can be at any
		// point and at any angle within the parent's world space bounds.
		Vector vAddMins, vAddMaxs;
		pEnt->GetRenderBounds( vAddMins, vAddMaxs );
		// if our origin is actually farther away than that, expand again
		float radius = pEnt->GetLocalOrigin().Length();

		float flBloatSize = max( vAddMins.Length(), vAddMaxs.Length() );
		flBloatSize = max(flBloatSize, radius);
		absMin -= Vector( flBloatSize, flBloatSize, flBloatSize );
		absMax += Vector( flBloatSize, flBloatSize, flBloatSize );
	}
	else
	{
		// Start out with our own render bounds. Since we don't have a parent, this won't incur any nasty 
		CalcRenderableWorldSpaceAABB( pRenderable, absMin, absMax );
	}
}
//-----------------------------------------------------------------------------
// Add entity to frame think list
//-----------------------------------------------------------------------------
void CClientThinkList::AddEntityToFrameThinkList( ThinkEntry_t *pEntry, bool bAlwaysChain, int &nCount, ThinkEntry_t **ppFrameThinkList )
{
	// We may already have processed this owing to hierarchy rules
	if ( pEntry->m_nIterEnum == m_nIterEnum )
		return;

	// If we're not thinking this frame, we don't have to worry about thinking after our parents
	bool bThinkThisInterval = ( pEntry->m_flNextClientThink == CLIENT_THINK_ALWAYS ) ||
								( pEntry->m_flNextClientThink <= gpGlobals->curtime );

	// This logic makes it so that if a child thinks,
	// *all* hierarchical parents + grandparents will think first, even if some
	// of the parents don't need to think this frame
	if ( !bThinkThisInterval && !bAlwaysChain )
		return;

	// Respect hierarchy
	C_BaseEntity *pEntity = ClientEntityList().GetBaseEntityFromHandle( pEntry->m_hEnt );
	if ( pEntity )
	{
		C_BaseEntity *pParent = pEntity->GetMoveParent();
		if ( pParent && (pParent->GetThinkHandle() != INVALID_THINK_HANDLE) )
		{
			ThinkEntry_t *pParentEntry = GetThinkEntry( pParent->GetThinkHandle() );
			AddEntityToFrameThinkList( pParentEntry, true, nCount, ppFrameThinkList );
		}
	}

	if ( !bThinkThisInterval )
		return;

	// Add the entry into the list
	pEntry->m_nIterEnum = m_nIterEnum;
	ppFrameThinkList[nCount++] = pEntry;
}
void CGlowObjectManager::GlowObjectDefinition_t::DrawModel()
{
	C_BaseEntity *pEntity = m_hEntity.Get();
	if ( !pEntity )
		return;

	if ( pEntity->GetMoveParent() != NULL )
	{
		C_BaseAnimating *pBaseAnimating = pEntity->GetBaseAnimating();
		if ( pBaseAnimating )
		{
			pBaseAnimating->InvalidateBoneCache();
		}
	}

	pEntity->DrawModel( STUDIO_RENDER );

	C_BaseEntity *pAttachment = pEntity->FirstMoveChild();
	while ( pAttachment != NULL )
	{
		if ( !g_GlowObjectManager.HasGlowEffect( pAttachment ) && pAttachment->ShouldDraw() )
		{
			C_BaseAnimating *pBaseAnimating = pAttachment->GetBaseAnimating();
			if ( pBaseAnimating )
			{
				pBaseAnimating->InvalidateBoneCache();
			}

			pAttachment->DrawModel( STUDIO_RENDER );
		}

		pAttachment = pAttachment->NextMovePeer();
	}
}