diff --git a/.drone.yml b/.drone.yml index ba62011..19e3477 100644 --- a/.drone.yml +++ b/.drone.yml @@ -65,6 +65,8 @@ steps: image: alpine/git commands: - cd game + - cp bin/linux64/vphysics.so bin/linux64/vphysics_client.so + - cp bin/linux64/vphysics.so.dbg bin/linux64/vphysics_client.so.dbg - git add . - git commit -m "Update binaries as of $DRONE_COMMIT" || true - git pull --rebase diff --git a/.github/workflows/artifacts.yml b/.github/workflows/artifacts.yml index 3032528..37c8c8e 100644 --- a/.github/workflows/artifacts.yml +++ b/.github/workflows/artifacts.yml @@ -5,6 +5,7 @@ on: [push, pull_request, workflow_dispatch] jobs: windows: strategy: + fail-fast: false matrix: source_branch: [sdk2013-sp, sdk2013-mp, asw] @@ -12,21 +13,17 @@ jobs: steps: - name: Checkout Mini Source SDK - id: checkout-minisdk uses: actions/checkout@v3 with: - repository: 'Joshua-Ashton/mini-source-sdk' + repository: Joshua-Ashton/mini-source-sdk - name: Checkout VPhysics Jolt - id: checkout-code uses: actions/checkout@v3 with: - path: '${{ matrix.source_branch }}/src/vphysics_jolt' + path: ${{ matrix.source_branch }}/src/vphysics_jolt submodules: recursive - name: Find Visual Studio - id: find-vs - shell: pwsh run: | $installationPath = Get-VSSetupInstance ` | Select-VSSetupInstance -Require Microsoft.VisualStudio.Workload.NativeDesktop -Latest ` @@ -35,9 +32,7 @@ jobs: | Out-File -FilePath "${Env:GITHUB_ENV}" -Append - name: Build MSVC x86 - id: build - shell: pwsh - working-directory: '${{ matrix.source_branch }}/src' + working-directory: ${{ matrix.source_branch }}/src run: | & "${Env:COMSPEC}" /s /c "`"${Env:VSDEVCMD}`" -arch=x86 -host_arch=x64 -no_logo && set" ` | % { , ($_ -Split '=', 2) } ` @@ -48,8 +43,7 @@ jobs: msbuild jolt.sln /nodeReuse:false /t:Rebuild /p:Configuration=Release /p:Platform=x86 /m /v:minimal - name: Upload artifacts - id: upload-artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: vphysics_jolt_${{ matrix.source_branch }}_win32 path: ${{ matrix.source_branch }}/game @@ -57,6 +51,7 @@ jobs: linux: strategy: + fail-fast: false matrix: source_branch: [sdk2013-sp, sdk2013-mp] @@ -65,37 +60,30 @@ jobs: steps: - name: Install Dependencies - id: install-deps - shell: bash run: | dpkg --add-architecture i386 apt update apt install -y build-essential git libstdc++6:i386 gcc-multilib g++-multilib - name: Checkout Mini Source SDK - id: checkout-minisdk uses: actions/checkout@v3 with: - repository: 'Joshua-Ashton/mini-source-sdk' + repository: Joshua-Ashton/mini-source-sdk - name: Checkout VPhysics Jolt - id: checkout-code uses: actions/checkout@v3 with: - path: '${{ matrix.source_branch }}/src/vphysics_jolt' + path: ${{ matrix.source_branch }}/src/vphysics_jolt submodules: recursive - name: Build GCC x86 - id: build - shell: bash - working-directory: '${{ matrix.source_branch }}/src' + working-directory: ${{ matrix.source_branch }}/src run: | ./createjoltprojects.sh make -f jolt.mak -j $(nproc) - name: Upload artifacts - id: upload-artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: vphysics_jolt_${{ matrix.source_branch }}_linux32 path: ${{ matrix.source_branch }}/game diff --git a/.gitignore b/.gitignore index 5b8ad27..45ce9b6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ # Multi-platform *.vpc_cache *.vpc_crc +*.sentinel .vscode .cache @@ -10,6 +11,7 @@ *.filters .vs enc_temp_folder/ +*.enc *.suo *.user *.FileListAbsolute.txt diff --git a/README.md b/README.md index 7976931..ae165c2 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,8 @@ Volt should build fine against Source SDK 2013 and Alien Swarm SDK on a MSVC or Unfortunately we cannot redistribute the additional code/headers needed to build Volt for games such as Garry's Mod which uses a different VPhysics interface (CS:GO's) to what is found in the Valve-provided public SDKs. +For full build instructions pertaining to SDK 2013, refernce [build.md](/build.md). + ## Download Development builds for each commit for SDK2013 SP/MP + ASW are available as artifacts on each commit on GitHub through GitHub Actions.
@@ -77,7 +79,7 @@ For each release, binary builds are provided for Garry's Mod and Source SDK 2013 ### Lots of Balls Test [![Lots of Balls Test](https://img.youtube.com/vi/tYfiTyRtmz8/0.jpg)](https://www.youtube.com/watch?v=tYfiTyRtmz8 "Lots of Balls Test") -### Wheels + Weld Car Dupe Test +### Wheels + Weld Car Dupe Test [![Weld Car Dupe Test](https://img.youtube.com/vi/5_QbbXbIrg8/0.jpg)](https://www.youtube.com/watch?v=5_QbbXbIrg8 "Weld Car Dupe Test") ### Door + NPC (Physics Shadowed Objects) Test diff --git a/build.md b/build.md new file mode 100644 index 0000000..bf2f593 --- /dev/null +++ b/build.md @@ -0,0 +1,108 @@ +# Building Volt + +###### Note: This repository can be built with the default SDK but will not be outlined in this guide. +###### Note: x64 platform builds will also not be outlined in this guide. + +All build instructions start the same. Clone a local copy of [mini-source-sdk](https://github.com/Joshua-Ashton/mini-source-sdk). (A minified version of [Source SDK](https://github.com/ValveSoftware/source-sdk-2013) with support for Linux and added support for [Visual Studio 2022](https://visualstudio.microsoft.com/vs/) and the [Windows 11 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/)) +```bash +git clone https://github.com/Joshua-Ashton/mini-source-sdk.git +``` + +Following your clone of the mini-source-sdk, navigate to the "version" you would like to build (`sdk2013-mp`, `sdk2013-sp`, `asw`). As an example, the multiplayer version will be used from now on. +```bash +cd mini-source-sdk/sdk2013-mp/src/ +``` + +At this time you should now recursively git clone the VPhysics-Jolt repository into your "src" directory. +```bash +git clone --recursive https://github.com/Joshua-Ashton/VPhysics-Jolt.git vphysics_jolt +``` + +From this point onward, please follow the rest of the guide specific to your chosen build platform. The current working directory is also assumed to be `mini-source-sdk/sdk2013-mp/src/` and should be adjusted to suit your own build if need be. + +## Windows + +Continuing on Windows, be sure you have both [Visual Studio 2022](https://visualstudio.microsoft.com/vs/) and the [Windows 11 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/) installed on your system. (even if you run Windows 10 the SDK still applies) + +### CLI + +The next step is to run the fix registry script (as administrator). You can just Right-Click -> 'Run As Administrator' the `fix_registry.bat` file located in `mini-source-sdk/sdk2013-mp/src/`. If your command prompt or powershell instance are already running under administrator you can run the script from there: +```bash +.\fix_registry.bat +``` + +This is the final command to run before the CLI portion of this guide ends. It will generate your [Visual Studio](https://visualstudio.microsoft.com/vs/) project/solution file(s). (You may also just Double-Click the file `createjoltprojects.bat`) +```bash +.\createjoltprojects.bat +``` + +### Visual Studio + +After running `createjoltprojects.bat` you should now have a file named `jolt.sln`. Open it. After opening, building should be simple. Press the shortcut `Ctrl+Shift+B` *OR* find the `Solution 'jolt'` bar in the Solution explorer window and Right-Click -> `Build Solution`. + +Congratulations! + +The built `vphysics_jolt.dll` file should now be located in `mini-source-sdk/sdk2013-mp/game/bin/`. + +### Build errors + +Common build errors you may run into building on Windows and their solutions. + +> #### memoverride.cpp + +If there is an error involving a symbol named ` size_t _msize` or `size_t __cdecl _msize_base`, it is most likely because you haven't updated your Windows SDK to the [Windows 11 SDK](https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/). Please do so. If you still get this error make sure that your Visual Studio projects also default to the latest installed version if they don't already. + +## Linux + +Continuing on Linux, there are a few prerequisites to building regardless of distribution. +- gcc 10+ +- g++ 10+ +- gcc-multilib +- g++-multilib +- make + +### Debian/Ubuntu +###### Note: Certain versions may also require version explicit packages (gcc/g++ 10 may not be the default installed version). + +Before we continue building project files, lets get our dependencies out of the way. +Install the `build-essential` group to get common developer packages such as gcc, g++, and make, which are included. +```bash +sudo apt install build-essential +``` + +After installing the build-essential group packages, we now need to install the x86 dependencies. +```bash +sudo apt install gcc-multilib g++-multilib +``` + +The next step is to build our makefiles by running the premade script `createjoltprojects.sh` +```bash +./createjoltprojects.sh +``` + +Once the script has finished running you should now have a file name `jolt.mak` in the current directory. Verify you do and now run it with the command below. This command automatically will (and is recommended to) use all available CPU threads. If you want to specify it yourself, replace `$(nproc)` with a number less than or equal to your max number of threads. To be clear, this only affects compile speed. +```bash +make -j $(nproc) -f jolt.mak +``` + +Alternative example... +```bash +make -j 8 -f jolt.mak +``` + +Congratulations! + +If the console outputs `LINKING` *and* `COPYING TO` messages, that means your build was successful and you may retrieve your `vphysics_jolt.so` and `vphysics_jolt_srv.so` files which will be located in `mini-source-sdk/sdk2013-mp/game/bin/`. + +### Build errors (distribution independent) + +Common build errors you may run into building on Linux and their solutions. + +> #### error: unrecognized command line option ‘-std=gnu++20’; did you mean ‘-std=gnu++2a’? (make: *** [jolt.mak:28: all] Error 2) + +This error is caused because the compile was not started with gcc/g++ v10 or higher. Please update. + +## OSX +Unsupported. + +¯\\\_(ツ)\_/¯ diff --git a/joltphysics/joltphysics_avx2.vpc b/joltphysics/joltphysics_avx2.vpc new file mode 100644 index 0000000..1d856f9 --- /dev/null +++ b/joltphysics/joltphysics_avx2.vpc @@ -0,0 +1,12 @@ +//----------------------------------------------------------------------------- +// JOLTPHYSICS_AVX2.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$Macro PROJNAME "joltphysics_avx2" + +$Conditional VOLT_AVX2 "1" +$Macro VOLTARCH "AVX2" + +$Include "joltphysics_inc.vpc" diff --git a/joltphysics/joltphysics.vpc b/joltphysics/joltphysics_inc.vpc similarity index 97% rename from joltphysics/joltphysics.vpc rename to joltphysics/joltphysics_inc.vpc index b973d3f..477de60 100644 --- a/joltphysics/joltphysics.vpc +++ b/joltphysics/joltphysics_inc.vpc @@ -5,7 +5,7 @@ //----------------------------------------------------------------------------- $Macro SRCDIR "..\.." -$Macro OUTLIBNAME "joltphysics" +$Macro OUTLIBNAME "$PROJNAME" $Include "$SRCDIR\vpc_scripts\source_lib_base.vpc" @@ -20,7 +20,25 @@ $Configuration } } -$Project "JoltPhysics" +$Configuration "Debug" +{ + $General + { + //$OutputDirectory ".\Debug_$VOLTARCH$PLATSUBDIR" [$WINDOWS] + $IntermediateDirectory ".\Debug_$VOLTARCH$PLATSUBDIR" [$WINDOWS] + } +} + +$Configuration "Release" +{ + $General + { + //$OutputDirectory ".\Release_$VOLTARCH$PLATSUBDIR" [$WINDOWS] + $IntermediateDirectory ".\Release_$VOLTARCH$PLATSUBDIR" [$WINDOWS] + } +} + +$Project "$PROJNAME" { $Folder "Precompiled Header" { diff --git a/joltphysics/joltphysics_settings.vpc b/joltphysics/joltphysics_settings.vpc index faeff4b..922c8fe 100644 --- a/joltphysics/joltphysics_settings.vpc +++ b/joltphysics/joltphysics_settings.vpc @@ -2,6 +2,8 @@ // Configuration settings for Jolt Physics // +$MacroRequired "VOLTARCH" + $Configuration { $Compiler @@ -11,14 +13,18 @@ $Configuration $PreprocessorDefinitions "$BASE;JPH_DISABLE_CUSTOM_ALLOCATOR;JPH_DEBUG_RENDERER" $PreprocessorDefinitions "$BASE;JPH_ENABLE_ASSERTS" [$DEVELOPMENT_ONLY] //$PreprocessorDefinitions "$BASE;JPH_PROFILE_ENABLED" [$DEVELOPMENT_ONLY] - - // CPU feature macros, we may want to tune these before release. - $PreprocessorDefinitions "$BASE;JPH_USE_SSE4_1;JPH_USE_SSE4_2;JPH_USE_LZCNT;JPH_USE_TZCNT;JPH_USE_F16C;JPH_USE_FMADD" - $GCC_ExtraCompilerFlags "$BASE -msse4.1 -msse4.2 -mlzcnt -mf16c -mfma -mbmi" + // Feature test stuff for the AVX2 build + $PreprocessorDefinitions "$BASE;JPH_USE_SSE4_1;JPH_USE_SSE4_2;JPH_USE_AVX;JPH_USE_AVX2;JPH_USE_LZCNT;JPH_USE_TZCNT;JPH_USE_F16C;JPH_USE_FMADD" [$VOLT_AVX2] + $GCC_ExtraCompilerFlags "$BASE -msse4.1 -msse4.2 -mavx2 -mlzcnt -mf16c -mfma -mbmi" [$VOLT_AVX2] + $EnableEnhancedInstructionSet "Advanced Vector Extensions 2 (/arch:AVX2)" [$VOLT_AVX2] + + // Feature test stuff for the SSE 4.2 build + $PreprocessorDefinitions "$BASE;JPH_USE_SSE4_1;JPH_USE_SSE4_2" [$VOLT_SSE42] + $GCC_ExtraCompilerFlags "$BASE -msse4.1 -msse4.2" [$VOLT_SSE42] + $EnableEnhancedInstructionSet "Streaming SIMD Extensions 2 (/arch:SSE2)" [$WIN32 && $VOLT_SSE42] // Source 2013 doesn't enable this by default - // We DO want to comment this line out for release, AVX 1 & 2 adoption isn't reliable enough yet - // $EnableEnhancedInstructionSet "Advanced Vector Extensions 2 (/arch:AVX2)" [$DEVELOPMENT_ONLY] + // Feature test stuff for the SSE 2 build + $EnableEnhancedInstructionSet "Streaming SIMD Extensions 2 (/arch:SSE2)" [$WIN32 && $VOLT_SSE2] // Source 2013 doesn't enable this by default } } - diff --git a/joltphysics/joltphysics_sse2.vpc b/joltphysics/joltphysics_sse2.vpc new file mode 100644 index 0000000..5bc4399 --- /dev/null +++ b/joltphysics/joltphysics_sse2.vpc @@ -0,0 +1,12 @@ +//----------------------------------------------------------------------------- +// JOLTPHYSICS_SSE2.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$Macro PROJNAME "joltphysics_sse2" + +$Conditional VOLT_SSE2 "1" +$Macro VOLTARCH "SSE2" + +$Include "joltphysics_inc.vpc" diff --git a/joltphysics/joltphysics_sse42.vpc b/joltphysics/joltphysics_sse42.vpc new file mode 100644 index 0000000..b89db27 --- /dev/null +++ b/joltphysics/joltphysics_sse42.vpc @@ -0,0 +1,12 @@ +//----------------------------------------------------------------------------- +// JOLTPHYSICS_SSE42.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$Macro PROJNAME "joltphysics_sse42" + +$Conditional VOLT_SSE42 "1" +$Macro VOLTARCH "SSE42" + +$Include "joltphysics_inc.vpc" diff --git a/vpc_scripts/vjolt_groups.vgc b/vpc_scripts/vjolt_groups.vgc index dfeca58..72ce8f3 100644 --- a/vpc_scripts/vjolt_groups.vgc +++ b/vpc_scripts/vjolt_groups.vgc @@ -5,17 +5,6 @@ //----------------------------------------------------------------------------- $Group "jolt" -{ - "appframework" - "interfaces" - "tier1" - "tier2" - "mathlib" - "joltphysics" - "vphysics_jolt" -} - -$Group "jolt_static" { "appframework" "interfaces" @@ -23,7 +12,12 @@ $Group "jolt_static" "tier1" "tier2" "mathlib" - "joltphysics" - "vphysics_jolt_static" "vstdlib_static" + "joltphysics_avx2" + "joltphysics_sse42" + "joltphysics_sse2" + "vphysics_jolt_avx2" + "vphysics_jolt_sse42" + "vphysics_jolt_sse2" + "vphysics_wrapper_external" } diff --git a/vpc_scripts/vjolt_projects.vgc b/vpc_scripts/vjolt_projects.vgc index 7bbb39c..bde220b 100644 --- a/vpc_scripts/vjolt_projects.vgc +++ b/vpc_scripts/vjolt_projects.vgc @@ -4,14 +4,44 @@ // Project configurations for VPhysics Jolt //----------------------------------------------------------------------------- -$Project "joltphysics" +$Project "joltphysics_avx2" { - "vphysics_jolt/joltphysics/joltphysics.vpc" + "vphysics_jolt/joltphysics/joltphysics_avx2.vpc" } -$Project "vphysics_jolt" +$Project "joltphysics_sse42" { - "vphysics_jolt/vphysics_jolt/vphysics_jolt.vpc" + "vphysics_jolt/joltphysics/joltphysics_sse42.vpc" +} + +$Project "joltphysics_sse2" +{ + "vphysics_jolt/joltphysics/joltphysics_sse2.vpc" +} + +$Project "vphysics_jolt_avx2" +{ + "vphysics_jolt/vphysics_jolt/vphysics_jolt_avx2.vpc" +} + +$Project "vphysics_jolt_sse42" +{ + "vphysics_jolt/vphysics_jolt/vphysics_jolt_sse42.vpc" +} + +$Project "vphysics_jolt_sse2" +{ + "vphysics_jolt/vphysics_jolt/vphysics_jolt_sse2.vpc" +} + +$Project "vphysics_wrapper_internal" +{ + "vphysics_jolt/vphysics_wrapper/vphysics_wrapper_internal.vpc" +} + +$Project "vphysics_wrapper_external" +{ + "vphysics_jolt/vphysics_wrapper/vphysics_wrapper_external.vpc" } $Project "vphysics_jolt_static" diff --git a/vphysics_jolt/vjolt_collide.cpp b/vphysics_jolt/vjolt_collide.cpp index 42f4be2..5b2393b 100644 --- a/vphysics_jolt/vjolt_collide.cpp +++ b/vphysics_jolt/vjolt_collide.cpp @@ -700,7 +700,7 @@ void JoltPhysicsCollision::VCollideUnload( vcollide_t *pVCollide ) { VCollideFreeUserData( pVCollide ); for ( int i = 0; i < pVCollide->solidCount; i++ ) - delete pVCollide->solids[ i ]; + delete pVCollide->solids[ i ]->ToShape(); delete[] pVCollide->solids; delete[] pVCollide->pKeyValues; diff --git a/vphysics_jolt/vjolt_collide.h b/vphysics_jolt/vjolt_collide.h index ebdbec1..08422b9 100644 --- a/vphysics_jolt/vjolt_collide.h +++ b/vphysics_jolt/vjolt_collide.h @@ -12,6 +12,8 @@ // Does not and will not contain *any* data. class CPhysCollide { + ~CPhysCollide() = delete; + public: JPH::Shape* ToShape() { @@ -42,6 +44,8 @@ public: // Does not and will not contain *any* data. class CPhysConvex { + ~CPhysConvex() = delete; + public: JPH::ConvexShape* ToConvexShape() { diff --git a/vphysics_jolt/vjolt_constraints.cpp b/vphysics_jolt/vjolt_constraints.cpp index 6e00c16..0dfa01e 100644 --- a/vphysics_jolt/vjolt_constraints.cpp +++ b/vphysics_jolt/vjolt_constraints.cpp @@ -151,7 +151,7 @@ void JoltPhysicsConstraint::SetLinearMotor( float speed, float maxLinearImpulse { case CONSTRAINT_SLIDING: { - JPH::SliderConstraint *pConstraint = static_cast( m_pConstraint ); + JPH::SliderConstraint *pConstraint = static_cast( m_pConstraint.GetPtr() ); pConstraint->SetMotorState( speed ? JPH::EMotorState::Velocity : JPH::EMotorState::Off ); pConstraint->SetTargetVelocity( speed ); @@ -184,7 +184,7 @@ void JoltPhysicsConstraint::SetAngularMotor( float rotSpeed, float maxAngularImp // :/ VJoltAssert( m_pConstraint->GetSubType() == JPH::EConstraintSubType::SixDOF ); - JPH::SixDOFConstraint *pConstraint = static_cast( m_pConstraint ); + JPH::SixDOFConstraint *pConstraint = static_cast( m_pConstraint.GetPtr() ); pConstraint->SetTargetAngularVelocityCS( JPH::Vec3( rotSpeed, rotSpeed, rotSpeed ) ); pConstraint->SetMaxFriction( JPH::SixDOFConstraint::EAxis::RotationX, maxAngularImpulse ); pConstraint->SetMaxFriction( JPH::SixDOFConstraint::EAxis::RotationY, maxAngularImpulse ); @@ -194,7 +194,7 @@ void JoltPhysicsConstraint::SetAngularMotor( float rotSpeed, float maxAngularImp case CONSTRAINT_HINGE: { - JPH::HingeConstraint *pConstraint = static_cast( m_pConstraint ); + JPH::HingeConstraint *pConstraint = static_cast( m_pConstraint.GetPtr() ); pConstraint->SetMotorState( rotSpeed ? JPH::EMotorState::Velocity : JPH::EMotorState::Off ); pConstraint->SetTargetAngularVelocity( rotSpeed ); @@ -285,12 +285,12 @@ static uint32 GetDegreesOfFreedom( const constraint_ragdollparams_t &ragdoll ) bool JoltPhysicsConstraint::InitialiseHingeFromRagdoll( IPhysicsConstraintGroup* pGroup, const constraint_ragdollparams_t& ragdoll ) { const uint32 uDOFMask = GetDegreesOfFreedom( ragdoll ); - const uint32 uDOFCount = popcnt( uDOFMask ); + const uint32 uDOFCount = JPH::CountBits( uDOFMask ); if ( uDOFCount != 1 ) return false; - const uint32 uDOF = tzcnt( uDOFMask ); + const uint32 uDOF = JPH::CountTrailingZeros( uDOFMask ); const Vector vecNextDOFAxis = DOFToAxis( NextDOF( uDOF ) ); matrix3x4_t refObjToWorld; @@ -494,7 +494,7 @@ void JoltPhysicsConstraint::InitialiseSliding( IPhysicsConstraintGroup *pGroup, if ( sliding.velocity ) { - JPH::SliderConstraint *pConstraint = static_cast( m_pConstraint ); + JPH::SliderConstraint *pConstraint = static_cast( m_pConstraint.GetPtr() ); pConstraint->SetMotorState( JPH::EMotorState::Velocity ); pConstraint->SetTargetVelocity( SourceToJolt::Distance( sliding.velocity ) ); } @@ -618,7 +618,6 @@ void JoltPhysicsConstraint::DestroyConstraint() if ( m_pConstraint ) { m_pPhysicsSystem->RemoveConstraint( m_pConstraint ); - m_pConstraint->Release(); m_pConstraint = nullptr; } } diff --git a/vphysics_jolt/vjolt_constraints.h b/vphysics_jolt/vjolt_constraints.h index 8821cbc..349b6e0 100644 --- a/vphysics_jolt/vjolt_constraints.h +++ b/vphysics_jolt/vjolt_constraints.h @@ -88,14 +88,14 @@ private: void DestroyConstraint(); - JoltPhysicsObject *m_pObjReference = nullptr; - JoltPhysicsObject *m_pObjAttached = nullptr; - JPH::Constraint *m_pConstraint = nullptr; - constraintType_t m_ConstraintType = CONSTRAINT_UNKNOWN; + JoltPhysicsObject *m_pObjReference = nullptr; + JoltPhysicsObject *m_pObjAttached = nullptr; + JPH::Ref< JPH::Constraint > m_pConstraint; + constraintType_t m_ConstraintType = CONSTRAINT_UNKNOWN; - JoltPhysicsConstraintGroup *m_pGroup = nullptr; + JoltPhysicsConstraintGroup *m_pGroup = nullptr; - void *m_pGameData = nullptr; - JoltPhysicsEnvironment *m_pPhysicsEnvironment = nullptr; - JPH::PhysicsSystem *m_pPhysicsSystem = nullptr; + void *m_pGameData = nullptr; + JoltPhysicsEnvironment *m_pPhysicsEnvironment = nullptr; + JPH::PhysicsSystem *m_pPhysicsSystem = nullptr; }; diff --git a/vphysics_jolt/vjolt_environment.cpp b/vphysics_jolt/vjolt_environment.cpp index f472d8e..22ed635 100644 --- a/vphysics_jolt/vjolt_environment.cpp +++ b/vphysics_jolt/vjolt_environment.cpp @@ -182,6 +182,8 @@ JoltBPLayerInterfaceImpl JoltPhysicsEnvironment::s_BPLayerInterface; JoltPhysicsEnvironment::JoltPhysicsEnvironment() : m_ContactListener( m_PhysicsSystem ) { + m_PerformanceParams.Defaults(); + m_PhysicsSystem.Init( kMaxBodies, kNumBodyMutexes, kMaxBodyPairs, kMaxContactConstraints, s_BPLayerInterface, JoltBroadPhaseCanCollide, JoltObjectCanCollide ); @@ -1180,16 +1182,20 @@ void JoltPhysicsEnvironment::SweepCollideable( const CPhysCollide *pCollide, con void JoltPhysicsEnvironment::GetPerformanceSettings( physics_performanceparams_t *pOutput ) const { - Log_Stub( LOG_VJolt ); - - *pOutput = m_PhysicsPerformanceParams; + if ( pOutput ) + *pOutput = m_PerformanceParams; } void JoltPhysicsEnvironment::SetPerformanceSettings( const physics_performanceparams_t *pSettings ) { - Log_Stub( LOG_VJolt ); + if ( pSettings ) + { + m_PerformanceParams = *pSettings; - m_PhysicsPerformanceParams = *pSettings; + // Normalize these values to match VPhysics behaviour. + m_PerformanceParams.minFrictionMass = Clamp( m_PerformanceParams.minFrictionMass, 1.0f, VPHYSICS_MAX_MASS ); + m_PerformanceParams.maxFrictionMass = Clamp( m_PerformanceParams.maxFrictionMass, 1.0f, VPHYSICS_MAX_MASS ); + } m_PhysicsSystem.GetBodies(m_CachedBodies); @@ -1212,42 +1218,42 @@ void JoltPhysicsEnvironment::SetPerformanceSettings( const physics_performancepa inline int JoltPhysicsEnvironment::MaxCollisionsPerObjectPerTimestep() const { - return m_PhysicsPerformanceParams.maxCollisionsPerObjectPerTimestep; + return m_PerformanceParams.maxCollisionsPerObjectPerTimestep; } inline int JoltPhysicsEnvironment::MaxCollisionChecksPerTimestep() const { - return m_PhysicsPerformanceParams.maxCollisionChecksPerTimestep; + return m_PerformanceParams.maxCollisionChecksPerTimestep; } inline float JoltPhysicsEnvironment::MaxVelocity() const { - return m_PhysicsPerformanceParams.maxVelocity; + return m_PerformanceParams.maxVelocity; } inline float JoltPhysicsEnvironment::MaxAngularVelocity() const { - return m_PhysicsPerformanceParams.maxAngularVelocity; + return m_PerformanceParams.maxAngularVelocity; } inline float JoltPhysicsEnvironment::LookAheadTimeObjectsVsWorld() const { - return m_PhysicsPerformanceParams.lookAheadTimeObjectsVsWorld; + return m_PerformanceParams.lookAheadTimeObjectsVsWorld; } inline float JoltPhysicsEnvironment::LookAheadTimeObjectsVsObject() const { - return m_PhysicsPerformanceParams.lookAheadTimeObjectsVsObject; + return m_PerformanceParams.lookAheadTimeObjectsVsObject; } inline float JoltPhysicsEnvironment::MinFrictionMass() const { - return m_PhysicsPerformanceParams.minFrictionMass; + return m_PerformanceParams.minFrictionMass; } inline float JoltPhysicsEnvironment::MaxFrictionMass() const { - return m_PhysicsPerformanceParams.maxFrictionMass; + return m_PerformanceParams.maxFrictionMass; } //------------------------------------------------------------------------------------------------- diff --git a/vphysics_jolt/vjolt_environment.h b/vphysics_jolt/vjolt_environment.h index 10cda67..9c2dbce 100644 --- a/vphysics_jolt/vjolt_environment.h +++ b/vphysics_jolt/vjolt_environment.h @@ -237,5 +237,5 @@ private: mutable bool m_bActiveObjectCountFirst = true; - physics_performanceparams_t m_PhysicsPerformanceParams; + physics_performanceparams_t m_PerformanceParams; }; diff --git a/vphysics_jolt/vjolt_listener_contact.h b/vphysics_jolt/vjolt_listener_contact.h index 4979d7d..cf4f095 100644 --- a/vphysics_jolt/vjolt_listener_contact.h +++ b/vphysics_jolt/vjolt_listener_contact.h @@ -552,7 +552,7 @@ private: { for ( uint32 thread = m_Mask; thread; thread &= thread - 1 ) { - const uint32 i = tzcnt( thread ); + const uint32 i = JPH::CountTrailingZeros( thread ); for ( auto &event : m_Events[ i ] ) func( event ); diff --git a/vphysics_jolt/vjolt_object.cpp b/vphysics_jolt/vjolt_object.cpp index 91a5f32..a3aaec7 100644 --- a/vphysics_jolt/vjolt_object.cpp +++ b/vphysics_jolt/vjolt_object.cpp @@ -68,6 +68,8 @@ JoltPhysicsObject::~JoltPhysicsObject() for ( int i = m_destroyedListeners.Count() - 1; i >= 0; i-- ) m_destroyedListeners[ i ]->OnJoltPhysicsObjectDestroyed( this ); + m_pEnvironment->RemoveDirtyStaticBody( GetBodyID() ); + JPH::BodyInterface& bodyInterface = m_pPhysicsSystem->GetBodyInterfaceNoLock(); bodyInterface.DestroyBody( GetBodyID() ); } diff --git a/vphysics_jolt/vjolt_util.h b/vphysics_jolt/vjolt_util.h index 15e8d46..e6427ac 100644 --- a/vphysics_jolt/vjolt_util.h +++ b/vphysics_jolt/vjolt_util.h @@ -312,56 +312,6 @@ void ActOnSubShapes( const JPH::Shape *pShape, Func ShapeFunc ) ShapeFunc( static_cast< const ShapeType * >( UndecorateShape( pShape ) ), JPH::Mat44::sIdentity() ); } -inline uint32 popcntStep( uint32 n, uint32 mask, uint32 shift ) -{ - return ( n & mask ) + ( ( n & ~mask ) >> shift ); -} - -inline uint32 popcnt( uint32 n ) -{ - n = popcntStep(n, 0x55555555, 1); - n = popcntStep(n, 0x33333333, 2); - n = popcntStep(n, 0x0F0F0F0F, 4); - n = popcntStep(n, 0x00FF00FF, 8); - n = popcntStep(n, 0x0000FFFF, 16); - return n; -} - -inline uint32 tzcnt( uint32 n ) -{ -#if defined(_MSC_VER) && !defined(__clang__) - return _tzcnt_u32( n ); -#elif defined(__BMI__) - return __tzcnt_u32( n ); -#elif defined(__GNUC__) || defined(__clang__) - // tzcnt is encoded as rep bsf, so we can use it on all - // processors, but the behaviour of zero inputs differs: - // - bsf: zf = 1, cf = ?, result = ? - // - tzcnt: zf = 0, cf = 1, result = 32 - // We'll have to handle this case manually. - uint32 res; - uint32 tmp; - asm ( - "tzcnt %2, %0;" - "mov $32, %1;" - "test %2, %2;" - "cmovz %1, %0;" - : "=&r" (res), "=&r" (tmp) - : "r" (n) - : "cc"); - return res; -#else - uint32 r = 31; - n &= -n; - r -= ( n & 0x0000FFFF ) ? 16 : 0; - r -= ( n & 0x00FF00FF ) ? 8 : 0; - r -= ( n & 0x0F0F0F0F ) ? 4 : 0; - r -= ( n & 0x33333333 ) ? 2 : 0; - r -= ( n & 0x55555555 ) ? 1 : 0; - return n != 0 ? r : 32; -#endif -} - template< typename T, typename Value > constexpr void Erase( T &c, const Value &value ) { diff --git a/vphysics_jolt/vphysics_jolt_static.vpc b/vphysics_jolt/vphysics_jolt_avx2.vpc similarity index 64% rename from vphysics_jolt/vphysics_jolt_static.vpc rename to vphysics_jolt/vphysics_jolt_avx2.vpc index 6e41647..c9264c4 100644 --- a/vphysics_jolt/vphysics_jolt_static.vpc +++ b/vphysics_jolt/vphysics_jolt_avx2.vpc @@ -1,9 +1,12 @@ //----------------------------------------------------------------------------- -// VPHYSICS_JOLT_STATIC.VPC +// VPHYSICS_JOLT_AVX2.VPC // // Project Script //----------------------------------------------------------------------------- -$Macro PROJNAME "vphysics_jolt_static" +$Macro PROJNAME "vphysics_jolt_avx2" + +$Conditional VOLT_AVX2 "1" +$Macro VOLTARCH "AVX2" $Include "vphysics_jolt_inc.vpc" diff --git a/vphysics_jolt/vphysics_jolt_inc.vpc b/vphysics_jolt/vphysics_jolt_inc.vpc index ad06f66..8ec5143 100644 --- a/vphysics_jolt/vphysics_jolt_inc.vpc +++ b/vphysics_jolt/vphysics_jolt_inc.vpc @@ -1,5 +1,5 @@ //----------------------------------------------------------------------------- -// VPHYSICS_JOLT_INC.INC +// VPHYSICS_JOLT_INC.VPC // // Project Script //----------------------------------------------------------------------------- @@ -30,6 +30,24 @@ $Configuration } } +$Configuration "Debug" +{ + $General + { + $OutputDirectory ".\Debug_$VOLTARCH$PLATSUBDIR" [$WINDOWS] + $IntermediateDirectory ".\Debug_$VOLTARCH$PLATSUBDIR" [$WINDOWS] + } +} + +$Configuration "Release" +{ + $General + { + $OutputDirectory ".\Release_$VOLTARCH$PLATSUBDIR" [$WINDOWS] + $IntermediateDirectory ".\Release_$VOLTARCH$PLATSUBDIR" [$WINDOWS] + } +} + $Project "$PROJNAME" { $Folder "Precompiled Header" @@ -142,7 +160,9 @@ $Project "$PROJNAME" $Folder "Link Libraries" { - $Lib "joltphysics" + $Lib "joltphysics_avx2" [$VOLT_AVX2] + $Lib "joltphysics_sse42" [$VOLT_SSE42] + $Lib "joltphysics_sse2" [$VOLT_SSE2] $Lib "mathlib" $Lib "tier2" } diff --git a/vphysics_jolt/vphysics_jolt_sse2.vpc b/vphysics_jolt/vphysics_jolt_sse2.vpc new file mode 100644 index 0000000..c164b99 --- /dev/null +++ b/vphysics_jolt/vphysics_jolt_sse2.vpc @@ -0,0 +1,12 @@ +//----------------------------------------------------------------------------- +// VPHYSICS_JOLT_SSE2.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$Macro PROJNAME "vphysics_jolt_sse2" + +$Conditional VOLT_SSE2 "1" +$Macro VOLTARCH "SSE2" + +$Include "vphysics_jolt_inc.vpc" diff --git a/vphysics_jolt/vphysics_jolt.vpc b/vphysics_jolt/vphysics_jolt_sse42.vpc similarity index 70% rename from vphysics_jolt/vphysics_jolt.vpc rename to vphysics_jolt/vphysics_jolt_sse42.vpc index b7f9456..32e3953 100644 --- a/vphysics_jolt/vphysics_jolt.vpc +++ b/vphysics_jolt/vphysics_jolt_sse42.vpc @@ -4,6 +4,9 @@ // Project Script //----------------------------------------------------------------------------- -$Macro PROJNAME "vphysics_jolt" +$Macro PROJNAME "vphysics_jolt_sse42" + +$Conditional VOLT_SSE42 "1" +$Macro VOLTARCH "SSE42" $Include "vphysics_jolt_inc.vpc" diff --git a/vphysics_wrapper/vphysics_wrapper.cpp b/vphysics_wrapper/vphysics_wrapper.cpp new file mode 100644 index 0000000..81698d1 --- /dev/null +++ b/vphysics_wrapper/vphysics_wrapper.cpp @@ -0,0 +1,208 @@ +//================================================================================================= +// +// The base physics DLL interface +// +// This is a thin CPU-agnostic wrapper for the actual Volt DLLs which are named +// vphysics_jolt_sse2.dll, vphysics_jolt_sse42.dll and vphysics_jolt_avx2.dll +// +//================================================================================================= + +#include "tier0/basetypes.h" +#include "tier1/interface.h" +#include "vphysics_interface.h" + +#ifdef _WIN32 +#include +#else +#include +#endif + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +//------------------------------------------------------------------------------------------------- + +class PhysicsWrapper final : public CBaseAppSystem +{ +public: + bool Connect( CreateInterfaceFn factory ) override; + void Disconnect() override; + + InitReturnVal_t Init() override; + void Shutdown() override; + void *QueryInterface( const char *pInterfaceName ) override; + + IPhysicsEnvironment *CreateEnvironment() override; + void DestroyEnvironment( IPhysicsEnvironment *pEnvironment ) override; + IPhysicsEnvironment *GetActiveEnvironmentByIndex( int index ) override; + + IPhysicsObjectPairHash *CreateObjectPairHash() override; + void DestroyObjectPairHash( IPhysicsObjectPairHash *pHash ) override; + + IPhysicsCollisionSet *FindOrCreateCollisionSet( unsigned int id, int maxElementCount ) override; + IPhysicsCollisionSet *FindCollisionSet( unsigned int id ) override; + void DestroyAllCollisionSets() override; + +public: + static PhysicsWrapper &GetInstance() { return s_PhysicsInterface; } + +private: + bool InitWrapper(); + + CSysModule *m_pActualPhysicsModule; + IPhysics *m_pActualPhysicsInterface; + + static PhysicsWrapper s_PhysicsInterface; +}; + +PhysicsWrapper PhysicsWrapper::s_PhysicsInterface; +EXPOSE_SINGLE_INTERFACE_GLOBALVAR( PhysicsWrapper, IPhysics, VPHYSICS_INTERFACE_VERSION, PhysicsWrapper::GetInstance() ); + +//------------------------------------------------------------------------------------------------- + +enum CPULevel_t +{ + CPU_HAS_SSE2, + CPU_HAS_SSE42, + CPU_HAS_AVX2, +}; + +static void GetCPUID( int *pInfo, int func, int subfunc ) +{ +#ifdef _WIN32 + __cpuidex( pInfo, func, subfunc ); +#else + __cpuid_count( func, subfunc, pInfo[0], pInfo[1], pInfo[2], pInfo[3] ); +#endif +} + +static CPULevel_t GetCPULevel() +{ + int cpuInfo[4]; + CPULevel_t cpuLevel = CPU_HAS_SSE2; + + GetCPUID( cpuInfo, 0, 0 ); // Get the number of functions + const int numFuncs = cpuInfo[0]; + if ( numFuncs >= 7 ) + { + GetCPUID( cpuInfo, 7, 0 ); // Call function 7 + bool hasAVX2 = cpuInfo[1] & ( 1 << 5 ); // 5 is the AVX2 bit + if ( hasAVX2 ) + cpuLevel = CPU_HAS_AVX2; + } + else + { + GetCPUID( cpuInfo, 1, 0 ); // Call function 1 + bool hasSSE42 = cpuInfo[2] & ( 1 << 20 ); // 20 is the SSE42 bit + if ( hasSSE42 ) + cpuLevel = CPU_HAS_SSE42; + } + + return cpuLevel; +} + +static const char *GetModuleFromCPULevel( CPULevel_t level ) +{ + switch ( level ) + { + case CPU_HAS_AVX2: return "vphysics_jolt_avx2" DLL_EXT_STRING; + case CPU_HAS_SSE42: return "vphysics_jolt_sse42" DLL_EXT_STRING; + default: return "vphysics_jolt_sse2" DLL_EXT_STRING; + } +} + +// Tries to load the actual vphysics DLL +bool PhysicsWrapper::InitWrapper() +{ + if ( m_pActualPhysicsInterface ) + return true; + + const char *pModuleName = GetModuleFromCPULevel( GetCPULevel() ); + + if ( !Sys_LoadInterface( pModuleName, VPHYSICS_INTERFACE_VERSION, &m_pActualPhysicsModule, (void **)&m_pActualPhysicsInterface ) ) + return false; + + return true; +} + +bool PhysicsWrapper::Connect( CreateInterfaceFn factory ) +{ + if ( !InitWrapper() ) + return false; + + return m_pActualPhysicsInterface->Connect( factory ); +} + +void PhysicsWrapper::Disconnect() +{ + m_pActualPhysicsInterface->Disconnect(); + + Sys_UnloadModule( m_pActualPhysicsModule ); +} + +//------------------------------------------------------------------------------------------------- + +InitReturnVal_t PhysicsWrapper::Init() +{ + return m_pActualPhysicsInterface->Init(); +} + +void PhysicsWrapper::Shutdown() +{ + m_pActualPhysicsInterface->Shutdown(); +} + +void *PhysicsWrapper::QueryInterface( const char *pInterfaceName ) +{ + // This function can be called before Connect, so try and load the real DLL early + if ( !InitWrapper() ) + return nullptr; + + return m_pActualPhysicsInterface->QueryInterface( pInterfaceName ); +} + +//------------------------------------------------------------------------------------------------- + +IPhysicsEnvironment *PhysicsWrapper::CreateEnvironment() +{ + return m_pActualPhysicsInterface->CreateEnvironment(); +} + +void PhysicsWrapper::DestroyEnvironment( IPhysicsEnvironment *pEnvironment ) +{ + m_pActualPhysicsInterface->DestroyEnvironment( pEnvironment ); +} + +IPhysicsEnvironment *PhysicsWrapper::GetActiveEnvironmentByIndex( int index ) +{ + return m_pActualPhysicsInterface->GetActiveEnvironmentByIndex( index ); +} + +//------------------------------------------------------------------------------------------------- + +IPhysicsObjectPairHash *PhysicsWrapper::CreateObjectPairHash() +{ + return m_pActualPhysicsInterface->CreateObjectPairHash(); +} + +void PhysicsWrapper::DestroyObjectPairHash( IPhysicsObjectPairHash *pHash ) +{ + m_pActualPhysicsInterface->DestroyObjectPairHash( pHash ); +} + +//------------------------------------------------------------------------------------------------- + +IPhysicsCollisionSet *PhysicsWrapper::FindOrCreateCollisionSet( unsigned int id, int maxElementCount ) +{ + return m_pActualPhysicsInterface->FindOrCreateCollisionSet( id, maxElementCount ); +} + +IPhysicsCollisionSet *PhysicsWrapper::FindCollisionSet( unsigned int id ) +{ + return m_pActualPhysicsInterface->FindCollisionSet( id ); +} + +void PhysicsWrapper::DestroyAllCollisionSets() +{ + m_pActualPhysicsInterface->DestroyAllCollisionSets(); +} diff --git a/vphysics_wrapper/vphysics_wrapper_external.vpc b/vphysics_wrapper/vphysics_wrapper_external.vpc new file mode 100644 index 0000000..9ab24a9 --- /dev/null +++ b/vphysics_wrapper/vphysics_wrapper_external.vpc @@ -0,0 +1,12 @@ +//----------------------------------------------------------------------------- +// VPHYSICS_WRAPPER_EXTERNAL.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +// Existing Source engine games don't know about Volt, so public wrapper builds +// just output "vphysics.dll" + +$Macro WRAPPER_NAME "vphysics" + +$Include "vphysics_wrapper_inc.vpc" diff --git a/vphysics_wrapper/vphysics_wrapper_inc.vpc b/vphysics_wrapper/vphysics_wrapper_inc.vpc new file mode 100644 index 0000000..1d1b804 --- /dev/null +++ b/vphysics_wrapper/vphysics_wrapper_inc.vpc @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// VPHYSICS_WRAPPER.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$MacroRequired "WRAPPER_NAME" + +$Macro SRCDIR "..\.." +$Macro OUTBINNAME "$WRAPPER_NAME" +$Macro OUTBINDIR "$SRCDIR\..\$GAMEDIR\bin" + +$Include "$SRCDIR\vpc_scripts\source_dll_base.vpc" + +$Configuration +{ + $Linker + { + // For Alien Swarm, we don't get the ability to build our own tier1 or mathlib + // which means we need to be compatible with the .libs provided built for + // ancient Visual Studio. + $AdditionalDependencies "$BASE legacy_stdio_definitions.lib" [$GAME_ASW] + } +} + +$Project "vphysics_wrapper" +{ + $Folder "Source Files" + { + $File "vphysics_wrapper.cpp" + } + + $Folder "Header Files" + { + } + + $Folder "Interface" + { + $File "$SRCDIR\public\vphysics_interface.h" + $File "$SRCDIR\public\vphysics\collision_set.h" + $File "$SRCDIR\public\vphysics\constraints.h" + $File "$SRCDIR\public\vphysics\friction.h" + $File "$SRCDIR\public\vphysics\object_hash.h" + $File "$SRCDIR\public\vphysics\performance.h" + $File "$SRCDIR\public\vphysics\player_controller.h" + $File "$SRCDIR\public\vphysics\stats.h" + $File "$SRCDIR\public\vphysics\vehicles.h" + } + + $Folder "Link Libraries" + { + } +} diff --git a/vphysics_wrapper/vphysics_wrapper_internal.vpc b/vphysics_wrapper/vphysics_wrapper_internal.vpc new file mode 100644 index 0000000..6c18c86 --- /dev/null +++ b/vphysics_wrapper/vphysics_wrapper_internal.vpc @@ -0,0 +1,11 @@ +//----------------------------------------------------------------------------- +// VPHYSICS_WRAPPER_INTERNAL.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +// This file is used when building for an engine that is aware of vphysics_jolt + +$Macro WRAPPER_NAME "vphysics_jolt" + +$Include "vphysics_wrapper_inc.vpc"