Accessing mesh triangles and vertex positions in build

From Epic Wiki
Jump to: navigation, search

Overview

Author: vebski

If you are wondering how to access triangles and vertex positions in packaged project. Here is the solution I found. Accessing this data from Unreal's variables (ex. StaticMesh->GetPhysicsTriMeshData()) will not work since all vertex data of a mesh is serialized when packaging the project.

To do this we will have to use PhysX library inside UE4 (on how to include PhysX module check out Rama's tutorial).

Also remember to include these in your .cpp <syntaxhighlight lang="cpp">

  1. include "PhysicsPublic.h"
  2. include "PhysXIncludes.h"
  3. include "ThirdParty/PhysX/PhysX-3.3/include/geometry/PxTriangleMesh.h"
  4. include "ThirdParty/PhysX/PhysX-3.3/include/foundation/PxSimpleTypes.h"

</syntaxhighlight>

Mesh specific vertices and triangles

This method will access data only for specific UMeshComponent.

<syntaxhighlight lang="cpp"> // MyStaticMesh is a UStaticMeshComponent PxTriangleMesh* TempTriMesh = MyStaticMesh->BodyInstance.BodySetup.Get()->TriMeshes[0];

check(TempTriMesh); int32 TriNumber = TempTriMesh->getNbTriangles();

const PxVec3* PVertices = TempTriMesh->getVertices(); const void* Triangles = TempTriMesh->getTriangles();

// Grab triangle indices int32 I0, I1, I2;

for (int32 TriIndex = 0; TriIndex < TriNumber; ++TriIndex) { if (TempTriMesh->getTriangleMeshFlags() & PxTriangleMeshFlag::eHAS_16BIT_TRIANGLE_INDICES) { PxU16* P16BitIndices = (PxU16*)Triangles; I0 = P16BitIndices[(TriIndex * 3) + 0]; I1 = P16BitIndices[(TriIndex * 3) + 1]; I2 = P16BitIndices[(TriIndex * 3) + 2]; } else { PxU32* P32BitIndices = (PxU32*)Triangles; I0 = P32BitIndices[(TriIndex * 3) + 0]; I1 = P32BitIndices[(TriIndex * 3) + 1]; I2 = P32BitIndices[(TriIndex * 3) + 2]; }

       // Local position

const FVector V0 = P2UVector(PVertices[I0]); const FVector V1 = P2UVector(PVertices[I1]); const FVector V2 = P2UVector(PVertices[I2]); }

</syntaxhighlight>

There is also way of accessing all meshes (welded) of an actor. It can be done by calling GetAllShapes() in BodyInstance.

Getting Transformed Vertex Positions

Author Rama (talk)

Many thanks to vebski for making this wiki and providing this info!

I've written this code to get the transformed positions of all vertices of any static mesh component.

This will account for actor rotation, translation, and scaling.

<syntaxhighlight lang="cpp"> //Get Transformed Vertex positions of any static mesh! -Rama bool UVictoryBPFunctionLibrary::GetStaticMeshVertexLocations(UStaticMeshComponent* Comp, TArray<FVector>& VertexPositions) {

if(!Comp) { return false; }

if(!Comp->IsValidLowLevel()) { return false; } //~~~~~~~~~~~~~~~~~~~~~~~

//Component Transform FTransform RV_Transform = Comp->GetComponentTransform();

//Body Setup valid? UBodySetup* BodySetup = Comp->GetBodySetup();

if(!BodySetup || !BodySetup->IsValidLowLevel()) { return false; }

       //array as of 4.9

for(PxTriangleMesh* EachTriMesh : BodySetup->TriMeshes) { if (!EachTriMesh) { return false; } //~~~~~~~~~~~~~~~~

//Number of vertices PxU32 VertexCount = EachTriMesh->getNbVertices();

//Vertex array const PxVec3* Vertices = EachTriMesh->getVertices();

//For each vertex, transform the position to match the component Transform for (PxU32 v = 0; v < VertexCount; v++) { VertexPositions.Add(RV_Transform.TransformPosition(P2UVector(Vertices[v]))); } }

return true; } </syntaxhighlight>

Rama (talk)

Summary

I hope it will save you some time, it took me a while of reading source code to figure this out.

vebski