Download

Is it possible to get Primative Collision from UStaticMeshComponent?

I have created a couple static meshes from BSP. From each of those I have created Simplified Collision (have tried Box, Sphere, Capsule). What I want to do is get the instance of these simplified collisions as FCollisionShape:Box, Sphere, Capsule, etc. I tried (UStaticMeshComponent*)ActorItr->GetComponentsByClass(UStaticMeshComponent::StaticClass())[a])->GetCollisionShape() but I think GetCollisionShape() is creating a new item that is always Box?

Hopefully someone can point me in the right direction.

~~~ Instanced PhysX Shapes ~~~

To get all of the instanced shapes of box,capsule,sphere,

I believe what you want is:



int32 SyncShapes = 0;
TArray<physx::PxShape*> CollisionShapes = YourPrimitiveComponent->BodyInstance.GetAllShapes(SyncShapes);


See PxShape.h for details

Relevant function in BodyInstance.h:



/** 
	 *	Utility to get all the shapes from a FBodyInstance 
	 *	Shapes belonging to sync actor are first, then async. Number of shapes belonging to sync actor is returned.
	 */
	TArray<physx::PxShape*> GetAllShapes(int32& OutNumSyncShapes) const;



**More Info**

**UE4 PhysX**

See my PhysX Wiki for working with PhysX code in UE4
https://wiki.unrealengine.com/PhysX,_Integrating_PhysX_Code_into_Your_Project

Enjoy!

Rama

Sorry for the late reply but this was exactly what I was looking for, thank you very much.

Now I am having issues trying to get the heightdata from Landscape. I thought I could do it just like the other Shapes:



for (TActorIterator<AStaticMeshActor> ActorItr(gi->GetWorld()); ActorItr; ++ActorItr)
	{
		GEngine->AddOnScreenDebugMessage(-1, 50.f, FColor::Yellow, ActorItr->GetName());

		UStaticMeshComponent* collision;
		for (int32 a = 0; a < ActorItr->GetComponentsByClass(UStaticMeshComponent::StaticClass()).Num(); a++)
		{
			collision = (UStaticMeshComponent*)ActorItr->GetComponentsByClass(UStaticMeshComponent::StaticClass())[a];

			TArray<physx::PxShape*> CollisionShapes = collision->BodyInstance.GetAllShapes(shapes);

			for (int32 shape = 0; shape < CollisionShapes.Num(); shape++)
			{
				physx::PxShape* s = CollisionShapes[shape];
				physx::PxGeometryType::Enum gt = s->getGeometryType();
				switch (gt)
				{
				case physx::PxGeometryType::Enum::eBOX:
                                        ///GOOD
					break;
				case physx::PxGeometryType::Enum::eCAPSULE:
                                        ///GOOD
				case physx::PxGeometryType::Enum::eSPHERE:
                                        ///GOOD
					break;
				case physx::PxGeometryType::Enum::eHEIGHTFIELD:
                                        ///NEVER GETS HIT
                        }
                 }
          }



but the case for the eHeightField never gets hit. I was thinking this was because Landscape wasn’t inheriting from AStaticMeshActor. So I tried this:



for (TActorIterator<ALandscape> ActorItr(gi->GetWorld()); ActorItr; ++ActorItr)
	{
		GEngine->AddOnScreenDebugMessage(-1, 50.f, FColor::Yellow, ActorItr->GetName());

		lprxy = (ALandscape*)*ActorItr;

		TArray<physx::PxShape*> CollisionShapes = lprxy->BodyInstance.GetAllShapes(shapes2);
		bi = lprxy->BodyInstance;

		GEngine->AddOnScreenDebugMessage(-1, 50.f, FColor::Blue, FString("Col Shapes: ").Append(FString::FromInt(CollisionShapes.Num())));

		for (int32 shape = 0; shape < CollisionShapes.Num(); shape++)
		{
			physx::PxShape* s = CollisionShapes[shape];
			physx::PxGeometryType::Enum gt = s->getGeometryType();
		}
	}



but CollisionShapes var is always returning 0. So I am at a loss of how to get the PhysX heightfield data. Once I get the instance of it I can:



physx::PxHeightFieldGeometry heightFieldG = PxHeightFieldGeometry();
case physx::PxGeometryType::Enum::eHEIGHTFIELD:
					GEngine->AddOnScreenDebugMessage(-1, 50.f, FColor::Yellow, "HEIGHTFIELD");
					if (s->getHeightFieldGeometry(heightFieldG))
					{
						bpterrain.Center = FPositionData(center.X, -center.Y, center.Z);
						bpterrain.LocalScale = FPositionData(localScale.X, localScale.Z, localScale.Y);
						bpterrain.Rotation = FPositionData(rotation.Yaw, rotation.Pitch, rotation.Roll);

						physx::PxHeightField* heightField = heightFieldG.heightField;
					}



but I cannot get the instance. Any thoughts?

Hello, what includes do I need to add to be able to work with pxShape?

http://lmgtfy.com/?q=pxshape+usage

Apparently not that simple.

I’ve included the following and nothing works to allow me to dereference an object.

#include “PhysXIncludes.h”
#include “PhysxUserData.h”
#include “Physics/PhysicsInterfaceCore.h”
#include “PhysicsInterfaceDeclares.h”
#include “Runtime/Engine/Private/PhysicsEngine/PhysXSupport.h”
#include “Physics/PhysicsInterfaceTypes.h”
#include “PhysicsGeometryPhysX.h”
#include “PhysicsPublic.h”
#include “ThirdParty/PhysX3/PhysX_3.4/Include/PxShape.h”

Does this not work?

#include <PxShape.h>

That alone does not seem to work.
In the end it is some combo of the previous I listed, Resharper and Intelisense are still reporting errors but they seem to be false because I have gotten it to compile despite nearly every physx:: object throwing an error. I’ll come back with specifics as I have them.

Intellisense is dumb, especially in large code bases. Only trust errors from the compiler, everything else is suspect and (more often than not) a false positive.