void CObjectMotionBlurManager::ObjectMotionBlurDefinition_t::DrawModel()
{
	Vector vVelocity;
	m_pEntity->EstimateAbsVelocity( vVelocity );
	float flR = ( m_flVelocityScale * vVelocity.x + 128.0f ) / 256.0f;
	float flG = ( m_flVelocityScale * vVelocity.y + 128.0f ) / 256.0f;

	float flColor[3] = { flR, flG, 0.0f };
	render->SetColorModulation( flColor );

	C_BaseEntity *pAttachment;
	RenderableInstance_t instance;
	instance.m_nAlpha = 255;
	
	if ( mat_object_motion_blur_model_scale.GetFloat() != 1.0f )
	{
		m_pEntity->SetModelScale( mat_object_motion_blur_model_scale.GetFloat() );
		m_pEntity->InvalidateBoneCache();

		m_pEntity->DrawModel( STUDIO_RENDER | STUDIO_SKIP_FLEXES | STUDIO_DONOTMODIFYSTENCILSTATE | STUDIO_NOLIGHTING_OR_CUBEMAP | STUDIO_SKIP_DECALS, instance );
		pAttachment = m_pEntity->FirstMoveChild();

		while ( pAttachment != NULL )
		{
			if ( pAttachment->ShouldDraw() )
			{
				pAttachment->DrawModel( STUDIO_RENDER | STUDIO_SKIP_FLEXES | STUDIO_DONOTMODIFYSTENCILSTATE | STUDIO_NOLIGHTING_OR_CUBEMAP | STUDIO_SKIP_DECALS, instance );
			}
			pAttachment = pAttachment->NextMovePeer();
		}

		m_pEntity->SetModelScale( 1.0f );
		m_pEntity->InvalidateBoneCache();
	}

	flColor[2] = 1.0f;
	render->SetColorModulation( flColor );

	m_pEntity->DrawModel( STUDIO_RENDER | STUDIO_SKIP_FLEXES | STUDIO_DONOTMODIFYSTENCILSTATE | STUDIO_NOLIGHTING_OR_CUBEMAP | STUDIO_SKIP_DECALS, instance );
	pAttachment = m_pEntity->FirstMoveChild();

	while ( pAttachment != NULL )
	{
		if ( pAttachment->ShouldDraw() )
		{
			pAttachment->DrawModel( STUDIO_RENDER | STUDIO_SKIP_FLEXES | STUDIO_DONOTMODIFYSTENCILSTATE | STUDIO_NOLIGHTING_OR_CUBEMAP | STUDIO_SKIP_DECALS, instance );
		}
		pAttachment = pAttachment->NextMovePeer();
	}
}
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();
	}
}
void CMaterialModifyProxy::OnBind( void *pEntity )
{
	// Get the modified material vars from the entity input
	IClientRenderable *pRend = (IClientRenderable *)pEntity;
	if ( pRend )
	{
		C_BaseEntity *pBaseEntity = pRend->GetIClientUnknown()->GetBaseEntity();
		
		if ( pBaseEntity )
		{
			if( debug_materialmodifycontrol_client.GetBool() )
			{
//				DevMsg( 1, "%s\n", pBaseEntity->GetDebugName() );
			}
			int numChildren = 0;
			bool gotOne = false;
			for ( C_BaseEntity *pChild = pBaseEntity->FirstMoveChild(); pChild; pChild = pChild->NextMovePeer() )
			{
				numChildren++;
				C_MaterialModifyControl *pControl = dynamic_cast<C_MaterialModifyControl*>( pChild );
				if ( !pControl )
					continue;

				if( debug_materialmodifycontrol_client.GetBool() )
				{
//					DevMsg( 1, "pControl: 0x%p\n", pControl );
				}
				
				switch( pControl->GetModifyMode() )
				{
				case MATERIAL_MODIFY_MODE_NONE:
					break;
				case MATERIAL_MODIFY_MODE_SETVAR:
					gotOne = true;
					OnBindSetVar( pControl );
					break;
				case MATERIAL_MODIFY_MODE_ANIM_SEQUENCE:
					OnBindAnimatedTexture( pControl );
					break;
				case MATERIAL_MODIFY_MODE_FLOAT_LERP:
					OnBindFloatLerp( pControl );
					break;
				default:
					Assert( 0 );
					break;
				}
			}
			if( gotOne )
			{
//				DevMsg( 1, "numChildren: %d\n", numChildren );
			}
		}
	}

	if ( ToolsEnabled() )
	{
		ToolFramework_RecordMaterialParams( GetMaterial() );
	}
}
void CGlowObjectManager::GlowObjectDefinition_t::DrawModel()
{
	if ( m_hEntity.Get() )
	{
		m_hEntity->DrawModel( STUDIO_RENDER );
		C_BaseEntity *pAttachment = m_hEntity->FirstMoveChild();

		while ( pAttachment != NULL )
		{
			if ( !g_GlowObjectManager.HasGlowEffect( pAttachment ) && pAttachment->ShouldDraw() )
			{
				pAttachment->DrawModel( STUDIO_RENDER );
			}
			pAttachment = pAttachment->NextMovePeer();
		}
	}
}
void CGlowObjectManager::GlowObjectDefinition_t::DrawModel()
{
	RenderableInstance_t instance;
	instance.m_nAlpha = (uint8)( m_flGlowAlpha * 255.0f );

	m_pEntity->DrawModel( STUDIO_RENDER | STUDIO_SKIP_FLEXES | STUDIO_DONOTMODIFYSTENCILSTATE | STUDIO_NOLIGHTING_OR_CUBEMAP | STUDIO_SKIP_DECALS, instance );
	C_BaseEntity *pAttachment = m_pEntity->FirstMoveChild();

	while ( pAttachment != NULL )
	{
		if ( pAttachment->ShouldDraw() )
		{
			pAttachment->DrawModel( STUDIO_RENDER | STUDIO_SKIP_FLEXES | STUDIO_DONOTMODIFYSTENCILSTATE | STUDIO_NOLIGHTING_OR_CUBEMAP | STUDIO_SKIP_DECALS, instance );
		}
		pAttachment = pAttachment->NextMovePeer();
	}
}
//-----------------------------------------------------------------------------
// Does the dirty deed
//-----------------------------------------------------------------------------
void CMaterialModifyAnimatedProxy::OnBind( void *pEntity )
{
	assert ( m_AnimatedTextureVar );
	if( m_AnimatedTextureVar->GetType() != MATERIAL_VAR_TYPE_TEXTURE )
		return;

	ITexture *pTexture;
	pTexture = m_AnimatedTextureVar->GetTextureValue();

	// Get the modified material vars from the entity input
	IClientRenderable *pRend = (IClientRenderable *)pEntity;
	if ( pRend )
	{
		C_BaseEntity *pBaseEntity = pRend->GetIClientUnknown()->GetBaseEntity();
		if ( pBaseEntity )
		{
			for ( C_BaseEntity *pChild = pBaseEntity->FirstMoveChild(); pChild; pChild = pChild->NextMovePeer() )
			{
				C_MaterialModifyControl *pControl = dynamic_cast<C_MaterialModifyControl*>( pChild );
				if ( !pControl )
					continue;

				if ( !pControl->HasNewAnimationCommands() )
					continue;

				// Read the data from the modify entity
				materialanimcommands_t sCommands;
				pControl->GetAnimationCommands( &sCommands );

				m_iFrameStart = sCommands.iFrameStart;
				m_iFrameEnd = sCommands.iFrameEnd;
				m_bCustomWrap = sCommands.bWrap;
				m_flCustomFramerate = sCommands.flFrameRate;
				m_bReachedEnd = false;

				m_flStartTime = gpGlobals->curtime;

				pControl->ClearAnimationCommands();
			}
		}
	}

	// Init all the vars based on whether we're using the base material settings, 
	// or the custom ones from the entity input.
	int numFrames;
	bool bWrapAnimation;
	float flFrameRate;
	int iLastFrame;

	// Do we have a custom frame section from the server?
	if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
	{
		if ( m_iFrameEnd == MATERIAL_MODIFY_ANIMATION_UNSET )
		{
			m_iFrameEnd = pTexture->GetNumAnimationFrames();
		}

		numFrames = (m_iFrameEnd - m_iFrameStart) + 1;
		bWrapAnimation = m_bCustomWrap;
		flFrameRate = m_flCustomFramerate;
		iLastFrame = (m_iFrameEnd - 1);
	}
	else
	{
		numFrames = pTexture->GetNumAnimationFrames();
		bWrapAnimation = m_WrapAnimation;
		flFrameRate = m_FrameRate;
		iLastFrame = (numFrames - 1);
	}

	// Have we already reached the end? If so, stay there.
	if ( m_bReachedEnd && !bWrapAnimation )
	{
		m_AnimatedTextureFrameNumVar->SetIntValue( iLastFrame );
		return;
	}

	// NOTE: Must not use relative time based methods here
	// because the bind proxy can be called many times per frame.
	// Prevent multiple Wrap callbacks to be sent for no wrap mode
	float startTime;
	if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
	{
		startTime = m_flStartTime;
	}
	else
	{
		startTime = GetAnimationStartTime(pEntity);
	}
	float deltaTime = gpGlobals->curtime - startTime;
	float prevTime = deltaTime - gpGlobals->frametime;

	// Clamp..
	if (deltaTime < 0.0f)
		deltaTime = 0.0f;
	if (prevTime < 0.0f)
		prevTime = 0.0f;

	float frame = flFrameRate * deltaTime;	
	float prevFrame = flFrameRate * prevTime;

	int intFrame = ((int)frame) % numFrames; 
	int intPrevFrame = ((int)prevFrame) % numFrames;

	if ( m_iFrameStart != MATERIAL_MODIFY_ANIMATION_UNSET )
	{
		intFrame += m_iFrameStart;
		intPrevFrame += m_iFrameStart;
	}

	// Report wrap situation...
	if (intPrevFrame > intFrame)
	{
		m_bReachedEnd = true;

		if (bWrapAnimation)
		{
			AnimationWrapped( pEntity );
		}
		else
		{
			// Only sent the wrapped message once.
			// when we're in non-wrapping mode
			if (prevFrame < numFrames)
				AnimationWrapped( pEntity );
			intFrame = numFrames - 1;
		}
	}

	m_AnimatedTextureFrameNumVar->SetIntValue( intFrame );

	if ( ToolsEnabled() )
	{
		ToolFramework_RecordMaterialParams( GetMaterial() );
	}
}