ryder rami
ryder rami

Reputation: 11

How to combine intersecting static meshes into a single mesh?

I'm new to Unreal Engine and trying to make a spider locomotion system that works similar to a Navmesh except it applies to all surfaces (walls and ceilings included) with the goal being that the players actor will read the data of the face it's standing on to orient its rotation and direction of gravity to align with the surface it's standing on. To do so I've been working on a custom Unreal Engine actor that will:

  1. Scan all of the non-player static meshes in a level.
  2. Detects intersections and creates connections between the vertices of intersecting meshes.
  3. Combines all intersecting static meshes into a single static mesh.

I’m currently stuck on step 3. Is it possible to combine static meshes through C++ in Unreal Engine? If so, what APIs or classes should I explore to do so? Any guidance or examples would be greatly appreciated!

Here's the code I have for drawing lines between nearby vertices of different static meshes. How do I now turn these lines into faces that connect the two Meshes together?

Image Link to code since some lines of code became offset in code block

   // Retrieve vertex buffers
   const FPositionVertexBuffer& SourceVertexBuffer = SourceLOD.VertexBuffers.PositionVertexBuffer;
   const FPositionVertexBuffer& OtherVertexBuffer = OtherLOD.VertexBuffers.PositionVertexBuffer;

   // Loop through First meshes vertices
   for (uint32 SourceIndex = 0; SourceIndex < SourceVertexBuffer.GetNumVertices(); ++SourceIndex)
   {
       FVector SourceVertexWorld = SourceMeshComponent->GetComponentTransform().TransformPosition(
           FVector(SourceVertexBuffer.VertexPosition(SourceIndex))
       );

       // Loop through other meshes vertices
       for (uint32 OtherIndex = 0; OtherIndex < OtherVertexBuffer.GetNumVertices(); ++OtherIndex)
       {
           FVector OtherVertexWorld = OtherMeshComponent->GetComponentTransform().TransformPosition(
               FVector(OtherVertexBuffer.VertexPosition(OtherIndex))
           ); 

           UE_LOG(LogTemp, Log, TEXT("The Source Verticie is located at %s and the other is at %s"),
               *SourceVertexWorld.ToString(), *OtherVertexWorld.ToString());

           // Check if vertices are close enough to be considerd intersecting
           if (FVector::Dist(SourceVertexWorld, OtherVertexWorld) < 100.0f) 
           {
              
              // Debug of vertices 
               DrawDebugPoint(GetWorld(), SourceVertexWorld, 10.0f, FColor::Red, false, 5.0f);
               DrawDebugPoint(GetWorld(), OtherVertexWorld, 10.0f, FColor::Blue, false, 5.0f);

               UE_LOG(LogTemp, Log, TEXT("DRAWING LINE SourceLocation: %s, OtherLocation: %s"), *SourceVertexWorld.ToString(), *OtherVertexWorld.ToString());
               DrawDebugLine(GetWorld(), SourceVertexWorld, OtherVertexWorld, FColor::Orange, true, -1.0f);

               
               UE_LOG(LogTemp, Log, TEXT("Connected vertex between meshes at %s and%s"),
                   *SourceVertexWorld.ToString(), *OtherVertexWorld.ToString());
           }
           else 
           {

               UE_LOG(LogTemp, Log, TEXT("Verticies too far for bridge at %s and %s"),
                   *SourceVertexWorld.ToString(), *OtherVertexWorld.ToString());

           } 
       }
   }

Upvotes: 0

Views: 59

Answers (1)

ephb
ephb

Reputation: 629

There multiple ways to achieve this. Since I assume you want basically only a hull when you are done and not the vertices that are intersecting you could use Geometry scripting to iterate over all the meshes the you deemed intersecting and emerge them one by one with the with "Apply Mesh Boolean" to get the union between them. It is quite slow and will likely hard to keep your uvs but I assume you do not need that anyway.

There are also functions for simplification and cleanup.

Quick search shows there is even an Epic Games tutorial for this, even though it is blueprint, it directly translates to C++.

Upvotes: 1

Related Questions