PhysX, Integrating PhysX Code into Your Project

From Epic Wiki
Jump to: navigation, search

Overview

Author: Rama (talk)

In this tutorial I am showing you how you can work with Nvidia PhysX directly in your UE4 code base!

I provide sample code that iterates over all the destructible chunks of a DestructibleComponent and draws their current world space positions to the screen!

PhysX 3.3 Source Code For UE4 Developers

Nvidia has made PhysX3.3 Open Source for all Unreal Engine 4 Developers!

Here's the link to the PhysX 3.3 Source Code

PhysX3.3 Source Code

edit: the link is broken but PhysX source code is in the UnrealEngine repo under .../Source/ThirdParty/PhysX/

You must be signed in to a UE4-Linked Github account to view the above link!

Simply sign up for Unreal Engine 4 and then follow the steps to link your github account to UE4.

UE4 Gitub Setup

Compiling the PhysX Source Code

Here's how to compile PhysX source code for UE4 as of 4.8!

Compiling PhysX Source Code for UE4

Video of a PhysX Vortex Spiral in UE4

In this video I am programmatically arranging apex pieces after the mesh is destroyed and the pieces bounce around normally.

I am arranging the pieces into a spiral/vortex formation!

Please notice that the apex pieces continue to have collision with the world and even each other, after I begin spinning them myself via C++!

This is all done via PhysX coding!

There is no measurable performance hit with my current method, my frame rate stays solid at max :)

In other words, I literally cannot detect any drop in performance even after I start the PhysX coding that you see in video below!

<youtube>https://www.youtube.com/watch?v=7KpkQPhvBKA</youtube>

This video is from my Abatron work in progress thread, UE4 Forum Link: Abatron

Pics

Below you can see I am drawing to screen the world space positions of each chunk of a Destructible Mesh using the PhysX code!

Some of the points can't be seen cause they are hidden inside the little pieces :)

But you can also see I am displaying the locations to the screen! Yay!

NvdiaUE4CPP1.jpg


Below I added a vertical offset to make the points visible for all chunks!

PhysXUE4CPP2.jpg

Enjoy!

Custom Destructible Mesh Class

Here's a custom destructible mesh class you can use to test whether you got the PhysX code setup properly!

This is the code I used for the picture above!

HappyDestructible.h

#pragma once

#include "HappyDestructible.generated.h"
UCLASS()
class AHappyDestructible : public ADestructibleActor
{
	GENERATED_UCLASS_BODY()
	
protected:
	virtual void Tick(float DeltaTime) override;
	
//Drawing!
public:
	FORCEINLINE void DrawPoint 
	(
		const FVector& Loc,
		const float& Size = 7,
		const FColor& Color = FColor::Red,
		const float Duration=-1.f
	) const {
		DrawDebugPoint(
			GetWorld(), 
			Loc,  
			Size, //thickness
			Color, 
			false,
			Duration
		);
	} 

	FORCEINLINE void ScreenMsg(const FString& Msg)
	{
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, *Msg);
	}

	FORCEINLINE void ScreenMsg(const FString& Msg, const FString& Msg2)
	{
		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("%s %s"), *Msg, *Msg2));
	}

};

HappyDestructible.cpp

#include "YourGame.h"
#include "HappyDestructible.h"

//~~~~~~~~~~~~~~~~~~~~~~~~
//	   PhysX 			
#include "PhysXIncludes.h" 
//~~~~~~~~~~~~~~~~~~~~~~~~

AHappyDestructible::AHappyDestructible(const class FPostConstructInitializeProperties& PCIP) : Super(PCIP)
{
	
}

//Tick
void AHappyDestructible::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
	//~~~~~~~~~~~~
	
	
	//Draw All Centers to the screen!
	#if WITH_PHYSX
	ScreenMsg("Got into PhysX!!!");

        //4.8 Version
	uint32 ChunkCount = DestructibleComponent->ApexDestructibleActor->getNumVisibleChunks();
	const uint16* ChunkIndices = DestructibleComponent->ApexDestructibleActor->getVisibleChunks();
	for(uint32 c = 0; c < ChunkCount; c++)
	{
		PxRigidDynamic* PActor = DestructibleComponent->ApexDestructibleActor->getChunkPhysXActor(ChunkIndices[c]);
		check(PActor);
		PxTransform Trans = PActor->getGlobalPose();
		PxVec3& PxLoc = Trans.p;

		FVector Location(PxLoc.x,PxLoc.y,PxLoc.z);

		DrawPoint(Location);

		ScreenMsg("physx loc", Location.ToString());
	}

        /* PRE 4.8 Version
	for(FDestructibleChunkInfo& Each : DestructibleComponent->ChunkInfos)
	{
		physx::PxRigidDynamic* Actor = Each.Actor;
		 
		if(Actor)
		{    
			PxTransform Trans = Actor->getGlobalPose();
			PxVec3& PxLoc = Trans.p;
			
			FVector Location(PxLoc.x,PxLoc.y,PxLoc.z);
			
			DrawPoint(Location);
			
			ScreenMsg("physx loc", Location.ToString());
		}
	}
        */
     #endif // WITH_PHYSX 
}

Packaging

I can verify that the code I've shared packages just fine into a full release game!

PhysX ~ Basic

Build.CS

You will need the following to work with Nvidia Apex:

PublicDependencyModuleNames.AddRange(new string[] { 
	"Core", 
	"CoreUObject", 
	"Engine", 
	"InputCore",
	
   "PhysX", "APEX" //PhysX
});

The Essential Include

You can include this in your .cpp or .h if you define any Px vars in your .h files.

//PhysX 
#include "PhysXIncludes.h"

PhysX ~ Advanced

PhysicsPublic.h

#include "PhysicsPublic.h"  //FPhysScene
#include "PhysXPublic.h"    //PtoU conversions

These include give you access to the conversion functions from PhysX to Unreal and back for various essential types like FVector / PxVec3

PhysXSupport.h for Scene Read/Write Locking

//For Scene Locking using Epic's awesome helper macros like SCOPED_SCENE_READ_LOCK
#include "Runtime/Engine/Private/PhysicsEngine/PhysXSupport.h"

This include is absolutely essential if you want to do any low-level multi-threaded PhysX coding!

Epic has created some wonderful macros to make it fast to create scoped read/write locks of the PhysX scene, for example see below!

PhysX ~ How to Get the PhysX Scene & WRITE/READ LOCK

Here's some sample code I'v written for how you can get the PhysX scene if you have the UE4 UWorld* !

void SomeClass::SomeFunction(UWorld* World)
{
  check(World); 
  //if crash here world was not valid, needs to be investigated, did it come from a UObject?

  FPhysScene* PhysScene = World->GetPhysicsScene();
  if(!PhysScene) return;

  // Scene Lock for Multi-Threading
  PxScene* SyncScene = PhysScene->GetPhysXScene(PST_Sync);
  SCOPED_SCENE_WRITE_LOCK(SyncScene); //or SCOPED_SCENE_READ_LOCK if you only need to read

  //now you can use the PhysX scene in multi-threaded fashion within this function context!
  //  -Rama
}

Yay!

UE4 4.15+ Entry PhysX Points Into UE4 Engine

As of 4.15 there are new entry points you can use to write a physX-related plugin or game project and interact with UE4's integration of PhysX!

"We have now refactored our PhysX Vehicle support as an optional plugin! This makes it easy for games that are not using vehicles to exclude this feature and save disk space and memory. This work also adds several useful physics extension points to Engine (e.g. OnPhysSceneInit/Term, OnPhysSceneStep) to make it easier for other developers to write their own similar systems."

https://www.unrealengine.com/blog/unreal-engine-4-15-released

Conclusion

Using the same UE4 class code, the build cs additions, and #includes I've shown above, you can now write any PhysX code you want!

Using the PhysX Scene access code I've shown above, you can do lowest level multi-threaded PhysX coding!

Have fun!

Rama (talk)