diff options
Diffstat (limited to 'vphysics/perftest')
| -rw-r--r-- | vphysics/perftest/perftest.cpp | 342 | ||||
| -rw-r--r-- | vphysics/perftest/perftest.vpc | 57 | ||||
| -rw-r--r-- | vphysics/perftest/stdafx.h | 13 |
3 files changed, 412 insertions, 0 deletions
diff --git a/vphysics/perftest/perftest.cpp b/vphysics/perftest/perftest.cpp new file mode 100644 index 0000000..18843ab --- /dev/null +++ b/vphysics/perftest/perftest.cpp @@ -0,0 +1,342 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#include "stdafx.h" +#include "filesystem_tools.h" +#include "KeyValues.h" +#include "physdll.h" +#include "materialsystem/imesh.h" +#include "utlvector.h" + +char g_szAppName[] = "VPhysics perf test"; +bool g_bCaptureOnFocus = false; + +IPhysics *physics = NULL; +IPhysicsCollision *physcollision = NULL; +IPhysicsSurfaceProps *physprops = NULL; +IMaterial *g_materialFlatshaded = NULL; +IMaterial *g_pWireframeMaterial = NULL; +int gKeys[256]; + +const objectparams_t g_PhysDefaultObjectParams = +{ + NULL, + 1.0f, //mass + 1.0f, // inertia + 0.0f, // damping + 0.0f, // rotdamping + 0.05f, // rotIntertiaLimit + "DEFAULT", + NULL,// game data + 0.f, // volume (leave 0 if you don't have one or call physcollision->CollideVolume() to compute it) + 1.0f, // drag coefficient + true,// enable collisions? +}; + + +void AddSurfacepropFile( const char *pFileName, IPhysicsSurfaceProps *pProps, IFileSystem *pFileSystem ) +{ + // Load file into memory + FileHandle_t file = pFileSystem->Open( pFileName, "rb" ); + + if ( file ) + { + int len = pFileSystem->Size( file ); + + // read the file + char *buffer = (char *)stackalloc( len+1 ); + pFileSystem->Read( buffer, len, file ); + pFileSystem->Close( file ); + buffer[len] = 0; + pProps->ParseSurfaceData( pFileName, buffer ); + // buffer is on the stack, no need to free + } +} + +void PhysParseSurfaceData( IPhysicsSurfaceProps *pProps, IFileSystem *pFileSystem ) +{ + const char *SURFACEPROP_MANIFEST_FILE = "scripts/surfaceproperties_manifest.txt"; + KeyValues *manifest = new KeyValues( SURFACEPROP_MANIFEST_FILE ); + if ( manifest->LoadFromFile( pFileSystem, SURFACEPROP_MANIFEST_FILE, "GAME" ) ) + { + for ( KeyValues *sub = manifest->GetFirstSubKey(); sub != NULL; sub = sub->GetNextKey() ) + { + if ( !Q_stricmp( sub->GetName(), "file" ) ) + { + // Add + AddSurfacepropFile( sub->GetString(), pProps, pFileSystem ); + continue; + } + + Warning( "surfaceprops::Init: Manifest '%s' with bogus file type '%s', expecting 'file'\n", + SURFACEPROP_MANIFEST_FILE, sub->GetName() ); + } + } + else + { + Error( "Unable to load manifest file '%s'\n", SURFACEPROP_MANIFEST_FILE ); + } + + manifest->deleteThis(); +} + +struct physics_test_object_t +{ + IPhysicsObject *pPhysics; + ICollisionQuery *pModel; +}; + +struct physicstest_t +{ + IPhysicsEnvironment *physenv; + CUtlVector<physics_test_object_t> list; + + void Clear() + { + physenv->SetQuickDelete( true ); + for ( int i = 0; i < list.Count(); i++ ) + { + physcollision->DestroyQueryModel( list[i].pModel ); + physenv->DestroyObject( list[i].pPhysics ); + } + list.Purge(); + physics->DestroyEnvironment( physenv ); + } + void InitEnvironment() + { + physenv = physics->CreateEnvironment(); + //g_EntityCollisionHash = physics->CreateObjectPairHash(); + physenv->EnableDeleteQueue( true ); + + //physenv->SetCollisionSolver( &g_Collisions ); + //physenv->SetCollisionEventHandler( &g_Collisions ); + //physenv->SetConstraintEventHandler( g_pConstraintEvents ); + //physenv->SetObjectEventHandler( &g_Objects ); + + physenv->SetSimulationTimestep( DEFAULT_TICK_INTERVAL ); // 15 ms per tick + // HL Game gravity, not real-world gravity + physenv->SetGravity( Vector( 0, 0, -600.0f ) ); + physenv->SetAirDensity( 0.5f ); + } + + int AddObject( IPhysicsObject *pObject ) + { + int index = list.AddToTail(); + list[index].pPhysics = pObject; + list[index].pModel = physcollision->CreateQueryModel( (CPhysCollide *)pObject->GetCollide() ); + return index; + } + + void CreateGround( float size ) + { + { + CPhysCollide *pCollide = physcollision->BBoxToCollide( Vector(-size,-size,-24), Vector(size,size,0) ); + objectparams_t params = g_PhysDefaultObjectParams; + IPhysicsObject *pGround = physenv->CreatePolyObjectStatic( pCollide, physprops->GetSurfaceIndex( "default" ), vec3_origin, vec3_angle, ¶ms ); + AddObject( pGround ); + } + + for ( int i = 0; i < 20; i++ ) + { + CPhysCollide *pCollide = physcollision->BBoxToCollide( Vector(-24,-24,-24), Vector(24,24,24) ); + objectparams_t params = g_PhysDefaultObjectParams; + params.mass = 150.0f; + IPhysicsObject *pGround = physenv->CreatePolyObject( pCollide, physprops->GetSurfaceIndex( "default" ), Vector(64*(i%4),64 * (i%5),1024), vec3_angle, ¶ms ); + AddObject( pGround ); + pGround->Wake(); + } + } + + void Explode( const Vector &origin, float force ) + { + for ( int i = 0; i < list.Count(); i++ ) + { + if ( !list[i].pPhysics->IsMoveable() ) + continue; + + Vector pos, dir; + list[i].pPhysics->GetPosition( &pos, NULL ); + dir = pos - origin; + dir.z += 10; + VectorNormalize( dir ); + list[i].pPhysics->ApplyForceCenter( dir * force ); + } + } + void RandomColor( float *color, int key ) + { + static bool first = true; + static colorVec colors[256]; + + if ( first ) + { + int r, g, b; + first = false; + for ( int i = 0; i < 256; i++ ) + { + do + { + r = rand()&255; + g = rand()&255; + b = rand()&255; + } while ( (r+g+b)<256 ); + colors[i].r = r; + colors[i].g = g; + colors[i].b = b; + colors[i].a = 255; + } + } + + int index = key & 255; + color[0] = colors[index].r * (1.f / 255.f); + color[1] = colors[index].g * (1.f / 255.f); + color[2] = colors[index].b * (1.f / 255.f); + color[3] = colors[index].a * (1.f / 255.f); + } + + void DrawObject( ICollisionQuery *pModel, IMaterial *pMaterial, IPhysicsObject *pObject ) + { + matrix3x4_t matrix; + pObject->GetPositionMatrix( &matrix ); + CMatRenderContextPtr pRenderContext(g_MaterialSystemApp.m_pMaterialSystem); + pRenderContext->Bind( pMaterial ); + + int vertIndex = 0; + for ( int i = 0; i < pModel->ConvexCount(); i++ ) + { + float color[4]; + RandomColor( color, i + (int)pObject ); + IMesh* pMatMesh = pRenderContext->GetDynamicMesh( ); + CMeshBuilder meshBuilder; + int triCount = pModel->TriangleCount( i ); + meshBuilder.Begin( pMatMesh, MATERIAL_TRIANGLES, triCount ); + + for ( int j = 0; j < triCount; j++ ) + { + Vector objectSpaceVerts[3]; + pModel->GetTriangleVerts( i, j, objectSpaceVerts ); + + for ( int k = 0; k < 3; k++ ) + { + Vector v; + + VectorTransform (objectSpaceVerts[k], matrix, v); + meshBuilder.Position3fv( v.Base() ); + meshBuilder.Color4fv( color ); + meshBuilder.AdvanceVertex(); + } + } + meshBuilder.End( false, true ); + } + } + + void Draw() + { + for ( int i = 0; i < list.Count(); i++ ) + { + DrawObject( list[i].pModel, g_materialFlatshaded, list[i].pPhysics ); + } + } + void Simulate( float frametime ) + { + physenv->Simulate( frametime ); + } +}; + +physicstest_t staticTest; + +void AppInit( void ) +{ + memset( gKeys, 0, sizeof(gKeys) ); + CreateInterfaceFn physicsFactory = GetPhysicsFactory(); + if (!(physics = (IPhysics *)physicsFactory( VPHYSICS_INTERFACE_VERSION, NULL )) || + !(physcollision = (IPhysicsCollision *)physicsFactory( VPHYSICS_COLLISION_INTERFACE_VERSION, NULL )) || + !(physprops = (IPhysicsSurfaceProps *)physicsFactory( VPHYSICS_SURFACEPROPS_INTERFACE_VERSION, NULL )) ) + { + return; + } + + PhysParseSurfaceData( physprops, g_pFullFileSystem ); + g_materialFlatshaded = g_MaterialSystemApp.m_pMaterialSystem->FindMaterial("debug/debugdrawflatpolygons", TEXTURE_GROUP_OTHER, true); + g_pWireframeMaterial = g_MaterialSystemApp.m_pMaterialSystem->FindMaterial("shadertest/wireframevertexcolor", TEXTURE_GROUP_OTHER); + staticTest.InitEnvironment(); + staticTest.CreateGround( 1024 ); +} + +void FPSControls( float frametime, float mouseDeltaX, float mouseDeltaY, Vector& cameraPosition, QAngle& cameraAngles, float speed ) +{ + cameraAngles[1] -= mouseDeltaX; + cameraAngles[0] -= mouseDeltaY; + + if ( cameraAngles[0] < -85 ) + cameraAngles[0] = -85; + if ( cameraAngles[0] > 85 ) + cameraAngles[0] = 85; + + Vector forward, right, up; + AngleVectors( cameraAngles, &forward, &right, &up ); + + if ( gKeys[ 'W' ] ) + VectorMA( cameraPosition, frametime * speed, forward, cameraPosition ); + if ( gKeys[ 'S' ] ) + VectorMA( cameraPosition, -frametime * speed, forward, cameraPosition ); + if ( gKeys[ 'A' ] ) + VectorMA( cameraPosition, -frametime * speed, right, cameraPosition ); + if ( gKeys[ 'D' ] ) + VectorMA( cameraPosition, frametime * speed, right, cameraPosition ); +} + + +void SetupCamera( Vector& cameraPosition, QAngle& cameraAngles ) +{ + CMatRenderContextPtr pRenderContext(g_MaterialSystemApp.m_pMaterialSystem); + pRenderContext->MatrixMode( MATERIAL_VIEW ); + pRenderContext->LoadIdentity( ); + pRenderContext->Rotate( -90, 1, 0, 0 ); // put Z going up + pRenderContext->Rotate( 90, 0, 0, 1 ); + + pRenderContext->Rotate( -cameraAngles[2], 1, 0, 0); // roll + pRenderContext->Rotate( -cameraAngles[0], 0, 1, 0); // pitch + pRenderContext->Rotate( -cameraAngles[1], 0, 0, 1); // yaw + + pRenderContext->Translate( -cameraPosition[0], -cameraPosition[1], -cameraPosition[2] ); +} + +static Vector cameraPosition = Vector(0,0,128); +static QAngle cameraAngles = vec3_angle; + +void AppRender( float frametime, float mouseDeltaX, float mouseDeltaY ) +{ + FPSControls( frametime, mouseDeltaX, mouseDeltaY, cameraPosition, cameraAngles, 300 ); + SetupCamera( cameraPosition, cameraAngles ); + + staticTest.Simulate( frametime ); + staticTest.Draw(); +} + +void AppExit( void ) +{ + staticTest.Clear(); + + //physics->DestroyObjectPairHash( g_EntityCollisionHash ); + //g_EntityCollisionHash = NULL; + physics->DestroyAllCollisionSets(); +} + +void AppKey( int key, int down ) +{ + gKeys[ key & 255 ] = down; +} + + +void AppChar( int key ) +{ + if ( key == ' ' ) + { + staticTest.Explode( cameraPosition, 150 * 100 ); + } +} + diff --git a/vphysics/perftest/perftest.vpc b/vphysics/perftest/perftest.vpc new file mode 100644 index 0000000..6888662 --- /dev/null +++ b/vphysics/perftest/perftest.vpc @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// PERFTEST.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$Macro SRCDIR "..\.." +$Macro OUTBINDIR "$SRCDIR\..\game\bin" + +$Include "$SRCDIR\vpc_scripts\source_exe_win_win32_base.vpc" + +$Configuration +{ + $Compiler + { + $AdditionalIncludeDirectories "$BASE,..\..\utils\common,..\..\utils\matsysapp,." + $PreprocessorDefinitions "$BASE;VECTOR;PROTECTED_THINGS_DISABLE" + } + + $Linker + { +// $AdditionalDependencies "comctl32.lib winmm.lib" + } +} + +$Project "perftest" +{ + $Folder "Source Files" + { + $File "..\..\utils\matsysapp\matsysapp.cpp" + $File "perftest.cpp" + + $Folder "common files" + { +// $File "..\..\utils\common\bsplib.cpp" + $File "..\..\utils\common\cmdlib.cpp" + $File "$SRCDIR\public\filesystem_helpers.cpp" + $File "$SRCDIR\public\filesystem_init.cpp" + $File "..\..\utils\common\filesystem_tools.cpp" + $File "..\..\utils\common\physdll.cpp" + $File "..\..\utils\common\scriplib.cpp" + } + } + + $Folder "Header Files" + { + $File "$SRCDIR\public\vphysics_interface.h" + $File "stdafx.h" + } + + $Folder "Link Libraries" + { +// $DynamicFile "$SRCDIR\lib\public\appframework.lib" + $DynamicFile "$SRCDIR\lib\public\mathlib.lib" + $DynamicFile "$SRCDIR\lib\public\tier2.lib" + } +} diff --git a/vphysics/perftest/stdafx.h b/vphysics/perftest/stdafx.h new file mode 100644 index 0000000..07a49ce --- /dev/null +++ b/vphysics/perftest/stdafx.h @@ -0,0 +1,13 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// + +#include "materialsystem/imaterialsystem.h" +#include "matsysapp.h" +#include "mathlib/mathlib.h" +#include "const.h" +#include "vphysics_interface.h" |