Manipulating skeletal mesh vertex positions at runtime

Hey guys, I’m quite new to C++ programming (I much prefer C#) but I have a bit of experience with the engine itself (material creation etc.) and I’ve run into a bit of a problem. I’m trying to manipulate the vertex positions of a skeletal mesh at runtime without the editor. At first the engine crashed but I was able to fix that due to an array index being out of bounds. The real question I’m having is how can I update the mesh after the positions have been updated and to also fix a memory leak I’m having as well?

The code in question is here (no need for the header file as there’s not much other than the void function).

#include "UpdateVertex.h"
#include "SkeletalMeshTypes.h"
#include "Engine/Public/Rendering/SkeletalMeshLODRenderData.h"
#include "Engine/Public/Rendering/SkeletalMeshRenderData.h"
#include "Engine/SkeletalMesh.h"
#include "Components/SkinnedMeshComponent.h"
#include "Components/SkeletalMeshComponent.h"
#include "Engine.h"

//DOESN'T UPDATE MESH AND CAUSES HUGE MEMORY LEAK OF OVER 200MB
void UUpdateVertex::Update(USkeletalMeshComponent* SkeletalMeshComp, int32 LodIndex)
{
	//Avoid running if no skeletal mesh was found
	if (!SkeletalMeshComp->SkeletalMesh)
	{
		UE_LOG(LogTemp, Warning, TEXT("No skeletal mesh found!"));
		return;
	}
	USkeletalMesh* SkelMesh = SkeletalMeshComp->SkeletalMesh;

	FSkeletalMeshRenderData* RenderData = SkelMesh->GetResourceForRendering();

	//Avoid crashing if index is higher than meshes LOD count
	if (LodIndex > SkelMesh->GetLODNum())
	{
		UE_LOG(LogTemp, Warning, TEXT("LOD greater than index!"));
		return;
	}
	FSkeletalMeshLODRenderData& LodRender = RenderData->LODRenderData[LodIndex];


	//Update every vertex position in every render section
	for (int32 j = 0; j < LodRender.RenderSections.Num(); j++)
	{
		for (int32 i = 0; i < LodRender.RenderSections[j].GetNumVertices(); i++)
		{
			LodRender.StaticVertexBuffers.PositionVertexBuffer.VertexPosition(i) += FVector(0.0f, 0.0f, 10.0f);
			UE_LOG(LogTemp, Warning, TEXT("Vertex position: %s"), *LodRender.StaticVertexBuffers.PositionVertexBuffer.VertexPosition(i).ToString());
		}
	}
	//FSkeletalMeshLODRenderData* LodRender = RenderData->LODRenderData;
	
	SkeletalMeshComp->MarkRenderStateDirty();
}

I’m planning on separating the variables into an init function if that helps with the memory leak.

1 Like

Okay so I fixed the memory leak, turns out it was just the spamming of output logs in the ‘for loop’ that caused the RAM to go up like that. However, I still haven’t found a way for the updated vertex positions to render…

Do you only want to add 10 units on Z to each vertex?

You can call

SkelMesh->PostEditChange()
and
SkelMesh->PostLoad()

Depending on your UE4 version, you may need to call
SkelMesh->InvalidateDeriveDataCacheGUID()

doesn’t work