Detail props/Aspect ratio fix

From Valve Developer Community
< Detail props
Revision as of 03:56, 13 November 2009 by TomEdwards (talk | contribs) (Created page with ''''This bug in Valve's stock code affects detail sprite materials stored at a location other than <code>detail\detailsprites</code>'''. The aspect ratio used whe…')
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

This bug in Valve's stock code affects detail sprite materials stored at a location other than detail\detailsprites. The aspect ratio used when selecting subregions of the custom texture is mistakenly read from detail\detailsprites at all times, meaning that the custom texture's aspect ratio must match that of the stock file.

This happens because Valve's aspect ratio code runs before the world has spawned and the detail sprite material becomes known. The fix is moving it to a function called post-spawn.

The fix

Go to CDetailObjectSystem::LevelInitPreEntity() in client\detailobjectsystem.cpp and remove this code block from about half-way down:

if ( m_DetailObjects.Count() || m_DetailSpriteDict.Count() )
{
	// There are detail objects in the level, so precache the material
	PrecacheMaterial( DETAIL_SPRITE_MATERIAL );
	IMaterial *pMat = m_DetailSpriteMaterial;
	// adjust for non-square textures (cropped)
	float flRatio = pMat->GetMappingWidth() / pMat->GetMappingHeight();
	if ( flRatio > 1.0 )
	{
		for( int i = 0; i<m_DetailSpriteDict.Count(); i++ )
		{
			m_DetailSpriteDict[i].m_TexUL.y *= flRatio;
			m_DetailSpriteDict[i].m_TexLR.y *= flRatio;
			m_DetailSpriteDictFlipped[i].m_TexUL.y *= flRatio;
			m_DetailSpriteDictFlipped[i].m_TexLR.y *= flRatio;
		}
	}
}

Then insert this as the start of CDetailObjectSystem::LevelInitPostEntity(), the next function in the file, replacing the pWorld conditional block:

void CDetailObjectSystem::LevelInitPostEntity()
{
	if ( m_DetailObjects.Count() || m_DetailSpriteDict.Count() )
	{
		const char *pDetailSpriteMaterial = DETAIL_SPRITE_MATERIAL;
		C_World *pWorld = GetClientWorldEntity();
		if ( pWorld && pWorld->GetDetailSpriteMaterial() && *(pWorld->GetDetailSpriteMaterial()) )
			pDetailSpriteMaterial = pWorld->GetDetailSpriteMaterial(); 

		m_DetailSpriteMaterial.Init( pDetailSpriteMaterial, TEXTURE_GROUP_OTHER );
		PrecacheMaterial( pDetailSpriteMaterial );
		IMaterial *pMat = m_DetailSpriteMaterial;

		// adjust for non-square textures (cropped)
		float flRatio = pMat->GetMappingWidth() / pMat->GetMappingHeight();
		if ( flRatio > 1.0 )
		{
			for( int i = 0; i<m_DetailSpriteDict.Count(); i++ )
			{
				m_DetailSpriteDict[i].m_TexUL.y *= flRatio;
				m_DetailSpriteDict[i].m_TexLR.y *= flRatio;
				m_DetailSpriteDictFlipped[i].m_TexUL.y *= flRatio;
				m_DetailSpriteDictFlipped[i].m_TexLR.y *= flRatio;
			}
		}
	}

The first line after this new code should be if ( GetDetailController() ).