Example #1
0
void CPhysicsSystem::PhysicsSimulate()
{
	CMiniProfilerGuard mpg(&g_mp_PhysicsSimulate);
	VPROF_BUDGET( "CPhysicsSystem::PhysicsSimulate", VPROF_BUDGETGROUP_PHYSICS );
	float frametime = gpGlobals->frametime;

	if ( physenv )
	{
		g_Collisions.BufferTouchEvents( true );
#ifdef _DEBUG
		physenv->DebugCheckContacts();
#endif
		frametime *= cl_phys_timescale.GetFloat();

		int maxTicks = cl_phys_maxticks.GetInt();
		if ( maxTicks )
		{
			float maxFrameTime = physenv->GetDeltaFrameTime( maxTicks ) - 1e-4f;
			frametime = clamp( frametime, 0, maxFrameTime );
		}

		physenv->Simulate( frametime );

		int activeCount = physenv->GetActiveObjectCount();
		g_mp_active_object_count.Add(activeCount);
		IPhysicsObject **pActiveList = NULL;
		if ( activeCount )
		{
			PHYS_PROFILE(aUpdateActiveObjects)
			pActiveList = (IPhysicsObject **)stackalloc( sizeof(IPhysicsObject *)*activeCount );
			physenv->GetActiveObjects( pActiveList );

			for ( int i = 0; i < activeCount; i++ )
			{
				C_BaseEntity *pEntity = reinterpret_cast<C_BaseEntity *>(pActiveList[i]->GetGameData());
				if ( pEntity )
				{
					//const CCollisionProperty *collProp = pEntity->CollisionProp();
					//debugoverlay->AddBoxOverlay( collProp->GetCollisionOrigin(), collProp->OBBMins(), collProp->OBBMaxs(), collProp->GetCollisionAngles(), 190, 190, 0, 0, 0.01 );

					if ( pEntity->CollisionProp()->DoesVPhysicsInvalidateSurroundingBox() )
					{
						pEntity->CollisionProp()->MarkSurroundingBoundsDirty();
					}
					pEntity->VPhysicsUpdate( pActiveList[i] );
					IPhysicsShadowController *pShadow = pActiveList[i]->GetShadowController();
					if ( pShadow )
					{
						// active shadow object, check for error
						Vector pos, targetPos;
						QAngle rot, targetAngles;
						pShadow->GetTargetPosition( &targetPos, &targetAngles );
						pActiveList[i]->GetPosition( &pos, &rot );
						Vector delta = targetPos - pos;
						float dist = VectorNormalize(delta);
						bool bBlocked = false;
						if ( dist > cl_phys_block_dist.GetFloat() )
						{
							Vector vel;
							pActiveList[i]->GetImplicitVelocity( &vel, NULL );
							float proj = DotProduct(vel, delta);
							if ( proj < dist * cl_phys_block_fraction.GetFloat() )
							{
								bBlocked = true;
								//Msg("%s was blocked %.3f (%.3f proj)!\n", pEntity->GetClassname(), dist, proj );
							}
						}
						Vector targetAxis;
						float deltaTargetAngle;
						RotationDeltaAxisAngle( rot, targetAngles, targetAxis, deltaTargetAngle );
						if ( fabsf(deltaTargetAngle) > 0.5f )
						{
							AngularImpulse angVel;
							pActiveList[i]->GetImplicitVelocity( NULL, &angVel );
							float proj = DotProduct( angVel, targetAxis ) * Sign(deltaTargetAngle);
							if ( proj < (fabsf(deltaTargetAngle) * cl_phys_block_fraction.GetFloat()) )
							{
								bBlocked = true;
								//Msg("%s was rot blocked %.3f proj %.3f!\n", pEntity->GetClassname(), deltaTargetAngle, proj );
							}
						}
					
						if ( bBlocked )
						{
							C_BaseEntity *pBlocker = FindPhysicsBlocker( pActiveList[i] );
							if ( pBlocker )
							{
								if ( IsBlockedShouldDisableCollisions( pEntity ) )
								{
									PhysDisableEntityCollisions( pEntity, pBlocker );
									pActiveList[i]->RecheckContactPoints();
									// GetClassname returns a pointer to the same buffer always!
									//Msg("%s blocked !", pEntity->GetClassname() ); Msg("by %s\n", pBlocker->GetClassname() );
								}
							}
						}
					}
				}
			}
		}

#if 0
		if ( cl_visualize_physics_shadows.GetBool() )
		{
			int entityCount = NUM_ENT_ENTRIES;
			for ( int i = 0; i < entityCount; i++ )
			{
				IClientEntity *pClientEnt = cl_entitylist->GetClientEntity(i);
				if ( !pClientEnt )
					continue;
				C_BaseEntity *pEntity = pClientEnt->GetBaseEntity();
				if ( !pEntity )
					continue;

				Vector pos;
				QAngle angle;
				IPhysicsObject *pObj = pEntity->VPhysicsGetObject();
				if ( !pObj || !pObj->GetShadowController() )
					continue;

				pObj->GetShadowPosition( &pos, &angle );
				debugoverlay->AddBoxOverlay( pos, pEntity->CollisionProp()->OBBMins(), pEntity->CollisionProp()->OBBMaxs(), angle, 255, 255, 0, 32, 0 );
				char tmp[256];
				V_snprintf( tmp, sizeof(tmp),"%s, (%s)\n", pEntity->GetClassname(), VecToString(angle) );
				debugoverlay->AddTextOverlay( pos, 0, tmp );
			}
		}
#endif
		g_Collisions.BufferTouchEvents( false );
		g_Collisions.FrameUpdate();
	}
	physicssound::PlayImpactSounds( m_impactSounds );
}
Example #2
0
void CPDumpPanel::Paint()
{
	C_BaseEntity *ent = m_hDumpEntity;
	if ( !ent )
	{
		Clear();
		return;
	}

	// Now output the strings
	int x[5];
	x[0] = 20;
	int columnwidth = 375;
	int numcols = ScreenWidth() / columnwidth;
	int i;

	numcols = clamp( numcols, 1, 5 );

	for ( i = 0; i < numcols; i++ )
	{
		if ( i == 0 )
		{
			x[i] = 20;
		}
		else
		{
			x[i] = x[ i-1 ] + columnwidth - 20;
		}
	}

	int c = m_DumpEntityInfo.Size();
	int fonttall = vgui::surface()->GetFontTall( m_FontSmall ) - 3;
	int fonttallMedium = vgui::surface()->GetFontTall( m_FontMedium );
	int fonttallBig = vgui::surface()->GetFontTall( m_FontBig );

	char currentclass[ 128 ];
	currentclass[ 0 ] = 0;

	int starty = 60;
	int y = starty;

	int col = 0;

	int r = 255;
	int g = 255;
	int b = 255;
	int a = 255;

	char classextra[ 32 ];
	classextra[ 0 ] = 0;
	char classprefix[ 32 ];
	Q_strncpy( classprefix, "class ", sizeof( classprefix ) );
	const char *classname = ent->GetClassname();
	if ( !classname[ 0 ] )
	{
		classname = typeid( *ent ).name();
		Q_strncpy( classextra, " (classmap missing)", sizeof( classextra ) );
		classprefix[ 0 ] = 0;
	}

	char sz[ 512 ];
	wchar_t szconverted[ 1024 ];

	surface()->DrawSetTextFont( m_FontBig );
	surface()->DrawSetTextColor( Color( 255, 255, 255, 255 ) );
	surface()->DrawSetTextPos( x[ col ] - 10, y - fonttallBig - 2 );
	Q_snprintf( sz, sizeof( sz ), "entity # %i: %s%s%s", ent->entindex(), classprefix, classname, classextra );
	g_pVGuiLocalize->ConvertANSIToUnicode( sz, szconverted, sizeof(szconverted)  );
	surface()->DrawPrintText( szconverted, wcslen( szconverted ) );

	for ( i = 0; i < c; i++ )
	{
		DumpInfo *slot = &m_DumpEntityInfo[ i ];

		if ( stricmp( slot->classname, currentclass ) )
		{
			y += 2;

			surface()->DrawSetTextFont( m_FontMedium );
			surface()->DrawSetTextColor( Color( 0, 255, 100, 255 ) );
			surface()->DrawSetTextPos( x[ col ] - 10, y );
			Q_snprintf( sz, sizeof( sz ), "%s", slot->classname );
			g_pVGuiLocalize->ConvertANSIToUnicode( sz, szconverted, sizeof(szconverted)  );
			surface()->DrawPrintText( szconverted, wcslen( szconverted ) );

			y += fonttallMedium-1;
			Q_strncpy( currentclass, slot->classname, sizeof( currentclass ) );
		}

	
		PredictionDumpColor( slot->networked, !slot->noterrorchecked, slot->differs, slot->withintolerance,
			r, g, b, a );

		surface()->DrawSetTextFont( m_FontSmall );
		surface()->DrawSetTextColor( Color( r, g, b, a ) );
		surface()->DrawSetTextPos( x[ col ], y );
		Q_snprintf( sz, sizeof( sz ), "%s", slot->fieldstring );
		g_pVGuiLocalize->ConvertANSIToUnicode( sz, szconverted, sizeof(szconverted)  );
		surface()->DrawPrintText( szconverted, wcslen( szconverted ) );

		y += fonttall;

		if ( y >= ScreenHeight() - fonttall - 60 )
		{
			y = starty;
			col++;
			if ( col >= numcols )
				break;
		}
	}

	surface()->DrawSetTextFont( m_FontSmall );


	// Figure how far over the legend needs to be.
	const char *pFirstAndLongestString = "Not networked, no differences";
	g_pVGuiLocalize->ConvertANSIToUnicode( pFirstAndLongestString, szconverted, sizeof(szconverted)  );
	int textSizeWide, textSizeTall;
	surface()->GetTextSize( m_FontSmall, szconverted, textSizeWide, textSizeTall );


	// Draw a legend now
	int xpos = ScreenWidth() - textSizeWide - 5;
	y = ScreenHeight() - 7 * fonttall - 80;

	// Not networked, no differences
	PredictionDumpColor( false, false, false, false, r, g, b, a );


	surface()->DrawSetTextColor( Color( r, g, b, a ) );
	surface()->DrawSetTextPos( xpos, y );
	Q_strncpy( sz, pFirstAndLongestString, sizeof( sz ) );
	g_pVGuiLocalize->ConvertANSIToUnicode( sz, szconverted, sizeof(szconverted)  );
	surface()->DrawPrintText( szconverted, wcslen( szconverted ) );

	y += fonttall;

	// Networked, no error check
	PredictionDumpColor( true, false, false, false, r, g, b, a );

	surface()->DrawSetTextColor( Color( r, g, b, a ) );
	surface()->DrawSetTextPos( xpos, y );
	Q_strncpy( sz, "Networked, not checked", sizeof( sz ) );
	g_pVGuiLocalize->ConvertANSIToUnicode( sz, szconverted, sizeof(szconverted)  );
	surface()->DrawPrintText( szconverted, wcslen( szconverted ) );

	y += fonttall;

	// Networked, with error check
	PredictionDumpColor( true, true, false, false, r, g, b, a );

	surface()->DrawSetTextColor( Color( r, g, b, a ) );
	surface()->DrawSetTextPos( xpos, y );
	Q_strncpy( sz, "Networked, error checked", sizeof( sz ) );
	g_pVGuiLocalize->ConvertANSIToUnicode( sz, szconverted, sizeof(szconverted)  );
	surface()->DrawPrintText( szconverted, wcslen( szconverted ) );

	y += fonttall;

	// Differs, but within tolerance
	PredictionDumpColor( true, true, true, true, r, g, b, a );

	surface()->DrawSetTextColor( Color( r, g, b, a ) );
	surface()->DrawSetTextPos( xpos, y );
	Q_strncpy( sz, "Differs, but within tolerance", sizeof( sz ) );
	g_pVGuiLocalize->ConvertANSIToUnicode( sz, szconverted, sizeof(szconverted)  );
	surface()->DrawPrintText( szconverted, wcslen( szconverted ) );

	y += fonttall;

	// Differs, not within tolerance, but not networked
	PredictionDumpColor( false, true, true, false, r, g, b, a );

	surface()->DrawSetTextColor( Color( r, g, b, a ) );
	surface()->DrawSetTextPos( xpos, y );
	Q_strncpy( sz, "Differs, but not networked", sizeof( sz ) );
	g_pVGuiLocalize->ConvertANSIToUnicode( sz, szconverted, sizeof(szconverted)  );
	surface()->DrawPrintText( szconverted, wcslen( szconverted ) );

	y += fonttall;

	// Differs, networked, not within tolerance
	PredictionDumpColor( true, true, true, false, r, g, b, a );

	surface()->DrawSetTextColor( Color( r, g, b, a ) );
	surface()->DrawSetTextPos( xpos, y );
	Q_strncpy( sz, "Differs, networked", sizeof( sz ) );
	g_pVGuiLocalize->ConvertANSIToUnicode( sz, szconverted, sizeof(szconverted)  );
	surface()->DrawPrintText( szconverted, wcslen( szconverted ) );

	y += fonttall;
}