コード例 #1
0
ファイル: disp_ivp.cpp プロジェクト: AluminumKen/hl2sb-src
void Disp_BuildVirtualMesh( int contentsMask )
{
	CUtlVector<CPhysCollide *> virtualMeshes;
	virtualMeshes.EnsureCount( g_CoreDispInfos.Count() );
	for ( int i = 0; i < g_CoreDispInfos.Count(); i++ )	
	{
		CCoreDispInfo *pDispInfo = g_CoreDispInfos[ i ];
		mapdispinfo_t *pMapDisp = &mapdispinfo[ i ];

		virtualMeshes[i] = NULL;
		// not solid for this pass
		if ( !(pMapDisp->contents & contentsMask) )
			continue;

		// Build a triangle list. This shares the tesselation code with the engine.
		CUtlVector<unsigned short> indices;
		CVBSPTesselateHelper helper;
		helper.m_pIndices = &indices;
		helper.m_pActiveVerts = pDispInfo->GetAllowedVerts().Base();
		helper.m_pPowerInfo = pDispInfo->GetPowerInfo();

		::TesselateDisplacement( &helper );

		// validate the collision data
		if ( 1 )
		{
			int triCount = indices.Count() / 3;
			for ( int j = 0; j < triCount; j++ )
			{
				int index = j * 3;
				Vector v0 = pDispInfo->GetVert( indices[index+0] );
				Vector v1 = pDispInfo->GetVert( indices[index+1] );
				Vector v2 = pDispInfo->GetVert( indices[index+2] );
				if ( v0 == v1 || v1 == v2 || v2 == v0 )
				{
					Warning( "Displacement %d has bad geometry near %.2f %.2f %.2f\n", i, v0.x, v0.y, v0.z );
					texinfo_t *pTexInfo = &texinfo[pMapDisp->face.texinfo];
					dtexdata_t *pTexData = GetTexData( pTexInfo->texdata );
					const char *pMatName = TexDataStringTable_GetString( pTexData->nameStringTableID );

					Error( "Can't compile displacement physics, exiting.  Texture is %s\n", pMatName );
				}
			}

		}
		CDispMeshEvent meshHandler( indices.Base(), indices.Count(), pDispInfo );
		virtualmeshparams_t params;
		params.buildOuterHull = true;
		params.pMeshEventHandler = &meshHandler;
		params.userData = &meshHandler;
		virtualMeshes[i] = physcollision->CreateVirtualMesh( params );
	}
	unsigned int totalSize = 0;
	CUtlBuffer buf;
	dphysdisp_t header;
	header.numDisplacements = g_CoreDispInfos.Count();
	buf.PutObjects( &header );

	CUtlVector<char> dispBuf;
	for ( int i = 0; i < header.numDisplacements; i++ )
	{
		if ( virtualMeshes[i] )
		{
			unsigned int testSize = physcollision->CollideSize( virtualMeshes[i] );
			totalSize += testSize;
			buf.PutShort( testSize );
		}
		else
		{
			buf.PutShort( -1 );
		}
	}
	for ( int i = 0; i < header.numDisplacements; i++ )
	{
		if ( virtualMeshes[i] )
		{
			unsigned int testSize = physcollision->CollideSize( virtualMeshes[i] );
			dispBuf.RemoveAll();
			dispBuf.EnsureCount(testSize);

			unsigned int outSize = physcollision->CollideWrite( dispBuf.Base(), virtualMeshes[i], false );
			Assert( outSize == testSize );
			buf.Put( dispBuf.Base(), outSize );
		}
	}
	g_PhysDispSize = totalSize + sizeof(dphysdisp_t) + (sizeof(unsigned short) * header.numDisplacements);
	Assert( buf.TellMaxPut() == g_PhysDispSize );
	g_PhysDispSize = buf.TellMaxPut();
	g_pPhysDisp = new byte[g_PhysDispSize];
	Q_memcpy( g_pPhysDisp, buf.Base(), g_PhysDispSize );
}