Announcement

Collapse
No announcement yet.

Accessing Vertex Positions of static mesh

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Accessing Vertex Positions of static mesh

    Hello community

    I'm trying to integrate a system into UE4 we had as an external content pipeline for CE3 that let us build large amounts of corridors for our hobby project.

    For that I need to somehow get a hold of the vertex positions in a static mesh, containing a 3D shape like this one:
    Click image for larger version

Name:	4252-splinebase.jpg
Views:	1
Size:	112.3 KB
ID:	1135281

    To that end I tried to create a new Blueprint node which would get a UStaticMeshComponent as input and puts out the vertices of that mesh in given order as a TArray<FVector>, like so:

    StaticMesh->LODData[0].PaintedVertices[X].Position; //for each vertex of course

    (I do have that BP node part up and running as part of the UObjectPlugin)



    Yet, no matter what I try and what different parts of the static mesh I try to access that could hold the info I want, they all come back as empty or invalid or as cats and dogs living together.
    I tried looking at its LodData, RenderData and all the others that would make half sense, same non-result.

    It seems so simple but the solution still evades me.

    I am hoping you guys can help me figure this out. (Please bear in mind, C++ n00b here )

  • #2
    You want the PositionVertex not the Painted, that's why its all cats and dogs

    Also you need to convert the verticies from UStaticMesh asset space into World Actor space, including scaling and rotation!

    ~~~

    Code For You

    Here's my code which I put together for you

    Code:
    //~~~~~~~~~~~~~~~~~~~~
    //				Vertex Buffer
    if(!IsValidLowLevel()) return;
    if(!StaticMeshComponent) return;
    if(!StaticMeshComponent->StaticMesh) return;
    if(!StaticMeshComponent->StaticMesh->RenderData) return;
    
    if(StaticMeshComponent->StaticMesh->RenderData->LODResources.Num() > 0)
    {
    	FPositionVertexBuffer* VertexBuffer = &StaticMeshComponent->StaticMesh->RenderData->LODResources[0].PositionVertexBuffer;
    	if (VertexBuffer) 
    	{
    		const int32 VertexCount = VertexBuffer->GetNumVertices();
    		for (int32 Index = 0;  Index < VertexCount; Index++ )
    		{
    			//This is in the Static Mesh Actor Class, so it is location and tranform of the SMActor
    			const FVector WorldSpaceVertexLocation = GetActorLocation() + GetTransform().TransformVector(VertexBuffer->VertexPosition(Index));
    			//add to output FVector array
    		}
    	}
    }
    ~~~

    The Critical Part

    This is the critical part that took me long time to figure out on my own during the Beta

    converts the UStaticMesh vertex into world actor space including Translation, Rotation, and Scaling!!

    Code:
    const FVector WorldSpaceVertexLocation = GetActorLocation() + GetTransform().TransformVector(VertexBuffer->VertexPosition(Index));


    Rama
    Last edited by Rama; 06-07-2014, 09:29 PM.
    100+ UE4 C++ Tutorials on the UE4 Code Wiki, including UE4 Multi-Threading!

    UE4 Marketplace: Melee Weapon Plugin & Compressed Binary Save System Plugin | Rama's C++ AI Jumping Videos | Vertex Snap Editor Plugin

    Visit www.ue4code.com to see lots of videos about my C++ Creations! ♥ Rama

    Comment


    • #3
      Thanks a lot Rama, that worked!

      Next sushi is on me!


      Here's the code for everyone:


      Header:

      Code:
      #pragma once
      
      #include "Components/StaticMeshComponent.h"
      #include "CorridorBlueprintFunctionLib.generated.h"
      
      UCLASS(MinimalAPI)
      class ACorridorBlueprintFunctionLib : public AActor
      {
      	GENERATED_UCLASS_BODY()
      
      	UFUNCTION(BlueprintPure, Category = "Corridor", meta = (Keywords = "corridor vertex mesh meshdata", NativeBreakFunc))
      	TArray<FVector> MeshData(const UStaticMeshComponent* StaticMeshComponent);
      };

      and the cpp:

      Code:
      #include "UObjectPluginPrivatePCH.h"
      #include "CorridorBlueprintFunctionLib.h"
      #include "Components/StaticMeshComponent.h"
      
      ACorridorBlueprintFunctionLib::ACorridorBlueprintFunctionLib(const class FPostConstructInitializeProperties& PCIP)
      : Super(PCIP)
      {
      }
      
      TArray<FVector> ACorridorBlueprintFunctionLib::MeshData(const UStaticMeshComponent* StaticMeshComponent)
      {
      	TArray<FVector> vertices = TArray<FVector>();
      
      	//~~~~~~~~~~~~~~~~~~~~
      	// Many thanks to Rama for this solution! :)
      	//
      	// Vertex Buffer
      	if (!IsValidLowLevel()) return vertices;
      	if (!StaticMeshComponent) return vertices;
      	if (!StaticMeshComponent->StaticMesh) return vertices;
      	if (!StaticMeshComponent->StaticMesh->RenderData) return vertices;
      
      	if (StaticMeshComponent->StaticMesh->RenderData->LODResources.Num() > 0)
      	{
      		FPositionVertexBuffer* VertexBuffer = &StaticMeshComponent->StaticMesh->RenderData->LODResources[0].PositionVertexBuffer;
      		if (VertexBuffer)
      		{
      			const int32 VertexCount = VertexBuffer->GetNumVertices();
      			for (int32 Index = 0; Index < VertexCount; Index++)
      			{
      				//This is in the Static Mesh Actor Class, so it is location and tranform of the SMActor
      				const FVector WorldSpaceVertexLocation = GetActorLocation() + GetTransform().TransformVector(VertexBuffer->VertexPosition(Index));
      				//add to output FVector array
      				vertices.Add(WorldSpaceVertexLocation);
      			}
      		}
      	}	
      	
      	return vertices;
      }

      Many thanks again Rama. Now we can continue with our corridors YAY


      Happy coding.

      Ruben

      Comment


      • #4
        Originally posted by rubenst View Post
        Many thanks again Rama. Now we can continue with our corridors YAY
        Yaaay!



        Rama
        100+ UE4 C++ Tutorials on the UE4 Code Wiki, including UE4 Multi-Threading!

        UE4 Marketplace: Melee Weapon Plugin & Compressed Binary Save System Plugin | Rama's C++ AI Jumping Videos | Vertex Snap Editor Plugin

        Visit www.ue4code.com to see lots of videos about my C++ Creations! ♥ Rama

        Comment


        • #5
          Thanks a lot Rama and Rube, this is exactly what I was looking for!

          I also needed to get vertex data for volumes (brush actors) and managed to figure that thanks to this thread. Here's the snippet with brush specific part in bold:

          Code:
          TArray<FVector> vertices = TArray<FVector>();
          	TResourceArray<FModelVertex, 0U> modelVertices = volumeOrBrushActor->Brush->VertexBuffer.Vertices;
          
          	for (FModelVertex vert : modelVertices)
          	{
          		const FVector WorldSpaceVertexLocation = volumeOrBrushActor->GetActorLocation() + GetTransform().TransformVector(vert.Position);
          		vertices.AddUnique(WorldSpaceVertexLocation);
          	}
          
          	return vertices;
          A quick digression - can this be simplified further with some functional programming construct?
          eg pseudo code: Transform( ModelVerts, FUNC{vert -> actorLocation + GetTransform().TransformVector(vert.Position)} ); would accomplish all of that in one line but I'm not sure of the C++ equivalent.



          DoN’s Mesh Painting Plugin | DoN’s 3D Pathfinding System | DoN the Nature Game at Steam

          Comment


          • #6
            Wow thanks for sharing guys! This sure comes in handy ^^

            Any idea how to get the vertexes for a UPrimitiveComponent though?

            PS- Is accessing the vertexes of a basic squared mesh expensive?
            Last edited by Horus; 10-09-2014, 09:35 AM.
            [On Hold]WIP: Vertex-Based Ledge Detection/Parkour Engine

            Looking for fellow programmers to develop a project.

            Comment


            • #7
              Originally posted by Horus View Post
              Wow thanks for sharing guys! This sure comes in handy ^^

              Any idea how to get the vertexes for a UPrimitiveComponent though?

              PS- Is accessing the vertexes of a basic squared mesh expensive?
              What is the actual end class of your Primitive Component class hierarchy? Is it Brush/BSP, Static Mesh, Skeletal ?

              I dont think primitive component is something you use directly, you need at least a box component, sphere component, etc.

              No accessing the vertices is not expensive, at least not until you start looping over 50k or 100k of them. But if you break up the loop you'll still be fine
              Last edited by Rama; 10-10-2014, 12:44 AM.
              100+ UE4 C++ Tutorials on the UE4 Code Wiki, including UE4 Multi-Threading!

              UE4 Marketplace: Melee Weapon Plugin & Compressed Binary Save System Plugin | Rama's C++ AI Jumping Videos | Vertex Snap Editor Plugin

              Visit www.ue4code.com to see lots of videos about my C++ Creations! ♥ Rama

              Comment


              • #8
                Originally posted by Rama View Post
                What is the actual end class of your Primitive Component class hierarchy? Is it Brush/BSP, Static Mesh, Skeletal ?

                I dont think primitive component is something you use directly, you need at least a box component, sphere component, etc.

                No accessing the vertices is not expensive, at least not until you start looping over 50k or 100k of them. But if you break up the loop you'll still be fine
                Nevermind lol
                Last edited by Horus; 10-10-2014, 05:16 AM.
                [On Hold]WIP: Vertex-Based Ledge Detection/Parkour Engine

                Looking for fellow programmers to develop a project.

                Comment


                • #9
                  BP Node Released

                  Access All Vertex Locations of Any Static Mesh


                  I just released a BP node to get all vertex locations, scaled translated and rotated, of any static mesh component!

                  C++ source code is in the download

                  https://forums.unrealengine.com/show...l=1#post161019


                  This pic was achieved using only my custom BP node, also available to you via link above!
                  Click image for larger version

Name:	VertexPositions.jpg
Views:	15
Size:	176.5 KB
ID:	1057668

                  Rama
                  100+ UE4 C++ Tutorials on the UE4 Code Wiki, including UE4 Multi-Threading!

                  UE4 Marketplace: Melee Weapon Plugin & Compressed Binary Save System Plugin | Rama's C++ AI Jumping Videos | Vertex Snap Editor Plugin

                  Visit www.ue4code.com to see lots of videos about my C++ Creations! ♥ Rama

                  Comment


                  • #10
                    The LOD information doesn't get updated if you rescale the object or am I doing something wrong?

                    Apparently it doesn't, because when I use a basic cube mesh (default) it works fine, but if I scale that same mesh, sideways,upwards,etc, the found vertexes are still in the same position as if they were a cube.

                    Images:
                    Normal:
                    Click image for larger version

Name:	normal.png
Views:	1
Size:	487.9 KB
ID:	1057669
                    Rescaled:
                    Click image for larger version

Name:	distorted.png
Views:	1
Size:	445.6 KB
ID:	1057670
                    [On Hold]WIP: Vertex-Based Ledge Detection/Parkour Engine

                    Looking for fellow programmers to develop a project.

                    Comment


                    • #11
                      @Horus: It also looks like the rotation is off. Did you change the Actors or Components transformation or both?

                      The way the vertices are transformed looks wrong to me. But I also still haven't had that in-depth look at the engine I would have liked.

                      Lets assume you import a static mesh asset. The vertices of the static mesh are in model space just like they were imported.
                      Now a StaticMeshComponent has a StaticMesh. But the StaticMeshComponent can be translated, rotated, scaled. So in order to go from model to component space you have to transform the vertices through this first.
                      Finally a StaticMeshComponent is attached to A(n)Actor. The Actor also has a transformation consisting of translation, rotation and scale (which is applied to "all" components). To finally reach world space for the vertices the component space needs to be transformed by the actors transformation as well.
                      Theoretically there could be more transformations inbetween. For example if the StaticMeshComponent is attached to a socket which animates via some sort of skeleton. Depending on how "deep" this "inheritance" goes you'll have quite a few calculations to do.


                      This may be completely wrong so please correct me in that case so I can learn too.
                      Youtube - UnrealEverything

                      Games:
                      [Android] World of Bricks Released!

                      [TUTORIAL] Edge Detection Post Process Effect using World Normals

                      2B || !(2B)

                      Comment


                      • #12
                        Oh its off because the prime mesh, the cube, is tilted as you can see in the first image, my guess is the engine accesses the LOD information of the initial mesh, being the cube mesh, and takes that as reference.
                        I will read your entire reply as soon as I get home, and thanks for taking your time to help.
                        [On Hold]WIP: Vertex-Based Ledge Detection/Parkour Engine

                        Looking for fellow programmers to develop a project.

                        Comment


                        • #13
                          Sorry finally found time to read your reply. Yes it makes perfect sense, in theory, though I'm not sure how things work on the engine.

                          Wouldn't one expect for this type of math to be implemented as a base of UE4? I mean, proper vertex calculation might be somewhat important lol
                          [On Hold]WIP: Vertex-Based Ledge Detection/Parkour Engine

                          Looking for fellow programmers to develop a project.

                          Comment


                          • #14
                            I noticed this as well in my initial testing with static meshes. Luckily volume/brush actors (which is what I need for now) do provide accurate vertex information even after scaling/rotation or even translation of individual vertices through the geometry edit tool.



                            DoN’s Mesh Painting Plugin | DoN’s 3D Pathfinding System | DoN the Nature Game at Steam

                            Comment


                            • #15
                              Not trying to hijack the topic. But, is it possible to get vertices of all triangles present in the static mesh? I have been wanting to do that since a long time but couldn't find any method to do so.

                              Comment

                              Working...
                              X