Is there a way to do this in C++?
I’ve found a couple of things that explain something similar but can’t quite work it out.
Basically I want to have a procedural mesh that is an exact copy of the skeletal mesh, including animations and morphs, and have it updating at runtime.
It should also have collision.
I don’t mind if this will be expensive, it will only be used for one or 2 meshes.
This should help, however it doesn’t work with morph targets.
void CopySkeletalMeshToProcedural(USkeletalMeshComponent* SkeletalMeshComponent, int32 LODIndex, UProceduralMeshComponent* ProcMeshComponent)
FSkeletalMeshRenderData* SkMeshRenderData = SkeletalMeshComponent->GetSkeletalMeshRenderData();
const FSkeletalMeshLODRenderData& DataArray = SkMeshRenderData->LODRenderData[LODIndex];
FSkinWeightVertexBuffer& SkinWeights = *SkeletalMeshComponent->GetSkinWeightBuffer(LODIndex);
//get num vertices
int32 NumSourceVertices = DataArray.RenderSections.NumVertices;
for (int32 i = 0; i < NumSourceVertices; i++)
//get skinned vector positions
FVector SkinnedVectorPos = USkeletalMeshComponent::GetSkinnedVertexPosition(SkeletalMeshComponent, i, DataArray, SkinWeights);
//Calc normals and tangents from the static version instead of the skeletal one
FVector ZTangentStatic = DataArray.StaticVertexBuffers.StaticMeshVertexBuffer.VertexTangentZ(i);
FVector XTangentStatic = DataArray.StaticVertexBuffers.StaticMeshVertexBuffer.VertexTangentX(i);
//add normals from the static mesh version instead because using the skeletal one doesn't work right.
FVector2D uvs = DataArray.StaticVertexBuffers.StaticMeshVertexBuffer.GetVertexUV(i, 0);
//dummy vertex colors
Colors.Add(FColor(0, 0, 0, 255));
//get index buffer
//iterate over num indices and add traingles
for (int32 i = 0; i < indicesData.Indices.Num(); i++)
uint32 a = 0;
a = indicesData.Indices[i];
//Create the procedural mesh
ProcMeshComponent->CreateMeshSection(0, VerticesArray, Tris, Normals, UV, Colors, Tangents, true);
thank you so much for your greatest work done here, but there is a little problem in your code: error C2065: ‘SkinWeights’: undeclared identifier, how can I get the value of the SkinWeights variable?
Oh, I figure it out now:
add FSkinWeightVertexBuffer* SkinWeights = SkeletalMeshComponent->GetSkinWeightBuffer(LODIndex); before line 21 and it works fine. thanks a lot for your amazing work!
Oops, looks like i forgot a line - I’ve updated my answer, so you shouldn’t be seeing errors now
This is cool! How would I go about implementing this code? I’m not very keen on C++ just yet. Would I make a Blueprint Function Library ? What would I include ? Thanks!
I would also like to know how this is implemented in blueprints, please
Works like a charm, thank you very much for sharing your knowledge!
Thanks for the excellent solution; it helped me a lot!
A small addition: if the mesh has multiple render sections, this code will copy only the first one. It is easily solved by adding a loop and iterating through all DataArray.RenderSections.
And then offset the vertex indexes by DataArray.RenderSections[SectionCount].BaseVertexIndex.
But I have a different but related question: does anybody know how to pick only the vertexes, which have weights associated with some particular bone?
I try to create a dynamic dismemberment system, which would work on with “solid” skeletal meshes without any pre-cutting.
It already works, but it is not very efficient because each time, I have to copy a lot of “unused” vertices and slice them afterwards, but I don’t like this.
FSkinWeightVertexBuffer’s method GetBoneIndex(VertexIndex, InfluenceIndex) seems to be the solution. However, due to a lack of documentation, I am not sure that I use it properly (e.g. I still do not completely get what InfluenceIndex is).