Generate Procedural Mesh

I was noticing that the collision mesh was lagging behind when changed dynamically, I originally thought it was the cooking time as it returns automatically if already cooking a previous change. However after a little experimentation the problem was solved by making the change below. Now the collision generates correctly after updates to the procedural mesh and I haven’t noticed any errors because of it so far.

From:


void UGeneratedMeshComponent::UpdateCollision() {
	if (bPhysicsStateCreated) {
		DestroyPhysicsState();
		UpdateBodySetup();
**		CreatePhysicsState();**
 
                ModelBodySetup->InvalidatePhysicsData();
		ModelBodySetup->CreatePhysicsMeshes();
	}
}

To:


void UGeneratedMeshComponent::UpdateCollision() {
	if (bPhysicsStateCreated) {
		DestroyPhysicsState();
		UpdateBodySetup();

 
                ModelBodySetup->InvalidatePhysicsData();
		ModelBodySetup->CreatePhysicsMeshes();
**		CreatePhysicsState();**
	}
}

Hey guys!

Thanks to Ori Cohen we got PhysX Cooking in runtime:

  • https://.com/EpicGames/UnrealEngine/commit/167a797ef8ed7062432f6449f97c4a408b3ea73b
  • https://.com/EpicGames/UnrealEngine/commit/7a01d572a98c9959e6ee48d9643c991751e59e72

This is still in the master though, but you should be able to integrate it into your code without effort.

Cheers,

As a proof of concept, i´ve created a procedural city (screenshot attached).
You can choose how many roads, buildings, parks and so on you want, and my class spawns them in the editor.

As far as i can see, FGeneratedMeshVertexFactory is not compatible with static lighting, because it crashes when i hit the Rebuild-button.

Is there a trick, to use static lighting never the less?

[=Mars007;156068]
As a proof of concept, i´ve created a procedural city (screenshot attached).
You can choose how many roads, buildings, parks and so on you want, and my class spawns them in the editor.

As far as i can see, FGeneratedMeshVertexFactory is not compatible with static lighting, because it crashes when i hit the Rebuild-button.

Is there a trick, to use static lighting never the less?
[/]

Yeah as it shows in the screenshot itself it is an ASSERT that throws if the process is trying to initialize the vertex factory inside the rendering thread. You can remove the assert and handle that part of the code getting called cleanly instead.

I ran into that awhile ago and changed it so it worked with what I was doing.


	/** Initialization */
	void Init(const FGeneratedMeshVertexBuffer* VertexBuffer)
	{
		**check(!IsInRenderingThread());**
 
		ENQUEUE_UNIQUE_RENDER_COMMAND_TWOPARAMETER(
			InitGeneratedMeshVertexFactory,
			FGeneratedMeshVertexFactory*,VertexFactory,this,
			const FGeneratedMeshVertexBuffer*,VertexBuffer,VertexBuffer,
		{
			// Initialize the vertex factory's stream components.
			DataType NewData;
			NewData.PositionComponent = STRUCTMEMBER_VERTEXSTREAMCOMPONENT(VertexBuffer,FDynamicMeshVertex,Position,VET_Float3);
			NewData.TextureCoordinates.Add(
				FVertexStreamComponent(VertexBuffer,STRUCT_OFFSET(FDynamicMeshVertex,TextureCoordinate),sizeof(FDynamicMeshVertex),VET_Float2)
				);
			NewData.TangentBasisComponents[0] = STRUCTMEMBER_VERTEXSTREAMCOMPONENT(VertexBuffer,FDynamicMeshVertex,TangentX,VET_PackedNormal);
			NewData.TangentBasisComponents[1] = STRUCTMEMBER_VERTEXSTREAMCOMPONENT(VertexBuffer,FDynamicMeshVertex,TangentZ,VET_PackedNormal);
			NewData.ColorComponent = STRUCTMEMBER_VERTEXSTREAMCOMPONENT(VertexBuffer, FDynamicMeshVertex, Color, VET_Color);
			VertexFactory->SetData(NewData);
		});
	}

Golding (Epic) stated previously that dynamic meshes are not compatible with static lighting:

[=JamesG;9597]
Right now this geometry is slightly slower than a regular static mesh, and doesn’t support things like precomputed lighting.
[/]

[=mordentral;156360]
You can remove the assert and handle that part of the code getting called cleanly instead.
[/]

So how do you do that? I mean, after removing the assert on line 44, what do you change on the code to make it support precomputed lighting?

Cheers!

This was an easy fix :slight_smile:
I thought this check prevents the engine from doing something bad.
But as i removed the IsInRenderingThread check, i got back static lighting for static meshes.
Dynamic meshes have to use dynamic lighting, as stated above.

[=;156409]
Golding (Epic) stated previously that dynamic meshes are not compatible with static lighting:

So how do you do that? I mean, after removing the assert on line 44, what do you change on the code to make it support precomputed lighting?

Cheers!
[/]

The reason it doesn’t work normally is because the example loads after the game has loaded so any baked lighting will obviously be incorrect, also if it changes then the baked lighting will also be wrong. If you have a mesh that is generated and never changes and is generated in engine prior to the baking process then it works just fine.

Hey guys! I’ve been trying to get this to work because it is critical for the game I’d like to start building. Basically I’m recreating a Tychoon-style terrain system and a procedural mesh with collision is the core component.

In Unity cranking out a procedural mesh was a piece of cake. So far in Unreal it’s been impossible. I’ve tried tinkering with as much stuff as I can but nothing seems to work. I keep getting the following error:


Error	2	error C2664: 'FVertexBufferRHIRef RHICreateVertexBuffer(uint32,uint32,FRHIResourceCreateInfo &)' : cannot convert argument 3 from 'EBufferUsageFlags' to 'FRHIResourceCreateInfo &'	C:\Users\...]\Source\ProMesh43\GeneratedMeshComponent.cpp	19	1	ProMesh43

I’ve tried fiddling with things, but I either get linking errors or errors that all kinds of behind the scenes functions take different arguments. I’ve tried this with 4.3, 4.4 and the 4.5 preview.

I realize this isn’t exactly plug and play, but has anyone else had these problems? (I’m new to C++ and don’t have the skills to get elbow deep in UE4)

Nevermind… I forgot to add RHI, RenderCore and ShadeCore modules to my build file. Derp.

[=;150736]
Hey guys!

Thanks to Ori Cohen we got PhysX Cooking in runtime:

  • https://.com/EpicGames/UnrealEngine/commit/167a797ef8ed7062432f6449f97c4a408b3ea73b
  • https://.com/EpicGames/UnrealEngine/commit/7a01d572a98c9959e6ee48d9643c991751e59e72

This is still in the master though, but you should be able to integrate it into your code without effort.

Cheers,

[/]

Thanks for sharing those links !

I’ve been hoping and wishing for this since 4.0 !

Fully functional dynamic meshes at runtime, runtime collision changes, yaaaay!

Hi, thank you all for the demo code of Procedural Mesh Generation !

To help people get the code working quickly, I’ve created a simple “ProceduralMesh” project featuring the demo code shown on the Wiki; its here on (UE4ProceduralMesh)

Cheers

[=;163155]

To help people get the code working quickly, I’ve created a simple “ProceduralMesh” project featuring the demo code shown on the Wiki; its here on (UE4ProceduralMesh)
[/]

Cool! Hope we can use that one to improve the code!

This is great!

Hello, quick question. In my blueprint… If I call the below function at every tick, will this animate any changes I had made to the mesh? I mean, is this the right way to do it?

[]

void AGameGeneratedMesh::UpdateMesh(TArray<FAtom> theUniverse)
{

TArray&lt;FCustomMeshTriangle&gt; triangles;

AGameGeneratedMesh::Cubing(triangles, theUniverse);

mesh-&gt;SetCustomMeshTriangles(triangles);
RootComponent = mesh;

}
[/]

Hey,
first a big thanks for the Procedural Mesh Tutorial and the code! As far as I can see we are using FDynamicMeshVertex inside the constructor of the scene proxy, therefore it should be possible to set the color of the vertices, which is done by “const FColor VertexColor(255, 255, 255);” in the wiki code, as VertexColor is later assigned to the vertices. But no matter what values i choose for VertexColor, my triangles stay black. Possibly I get the concept of vertex colors wrong, but shouldn’t the whole triangle be like VertexColor if I’m assigning it to every vertice of the triangle?
Alternatively I’ll try to use a Texture for my mesh tomorrow, but as I only want the triangles/quads to have a single color it would be a bit “overpowered” to use a 1px1px Texture (or 22 whatever, simply that 1 pixel on the texture will represent one color) I think and in addition it would be much more flexible to be able to use FColor or anything alike I can simply adjust in code. (I haven’t got it working to get a MID on the mesh either).

Thanks in advance,
Taces

I have managed to generate a mesh using the tutorial, but I cannot get collision with it to work. The mesh is static and a big part of the level, which the ship will fly around in. But the ship doesn’t collide with the mesh, it just flys through it. It does collide with other walls I have placed using the editor. I have enabled collision blocking for everything for the mesh. The ship has physics simulation enabled so I believe this may be the reason it doesn’t collide, as on this pagedocs.unrealengine.com/latest/INT/Engine/Physics/Collision/index.html it says complex collision is never used when simulating physics, and I interpret that as it will never collide with the triangles of the generated mesh. So I guess I have to somehow generate a set of simplified collision primitives for the generated mesh. How would I go about doing this? Is the functionality of the editor for generating the k-DOP collision primitives available in the API somewhere?

Thanks!

I now tried to assign a simple material to my mesh, but somehow it isn’t rendered. If I check the size of Component->Materials inside the FPrimitiveSceneProxy* UGeneratedMeshComponent::CreateSceneProxy() function, it is 0, although I added the Material to the array before. This is the constructor of my Actor:




mesh = PCIP.CreateDefaultSubobject<UGeneratedMeshComponent>(this, TEXT("MeshComp"));

	TArray<FGeneratedMeshTriangle> points;

	FGeneratedMeshTriangle tri;

	tri.Vertex0.Position = FVector(0, 0, 0);
	tri.Vertex1.Position = FVector(100, 0, 100);
	tri.Vertex2.Position = FVector(0, 0, 100);


	//points.Add(tri);

	tri.Vertex0.Position = FVector(100, 0, 100);
	tri.Vertex1.Position = FVector(0, 0, 0);
	tri.Vertex2.Position = FVector(100, 0, 0);


	points.Add(tri);

	mesh->SetGeneratedMeshTriangles(points);

	static ConstructorHelpers::FObjectFinder<UMaterial> MatFinder(TEXT("Material'/Game/TestMaterial.TestMaterial'"));
	UMaterial* Material = MatFinder.Object;
	UMaterialInstanceDynamic* DynMat1 = UMaterialInstanceDynamic::Create(Material, this);
	DynMat1->SetVectorParameterValue("Color", FLinearColor(1.f, 0.f, 0.f));
        UE_LOG(LogTemp, Warning, TEXT("Terrain Before: %d"), mesh->Materials.Num());
	mesh->SetMaterial(0, DynMat1);
	if (DynMat1 == NULL)
	{
		UE_LOG(LogTemp, Warning, TEXT(" DMI NULL"));
	}
	else 
	{
		UE_LOG(LogTemp, Warning, TEXT(" DMI NOT NULL"));
	}
	UE_LOG(LogTemp, Warning, TEXT("Terrain: %d"), mesh->Materials.Num());
	RootComponent = mesh;



Here the log says:

[]
LogTemp:Warning: Terrain Before: 0
LogTemp:Warning: DMI NOT NULL
LogTemp:Warning: Terrain: 1
[/]

And in the scene proxy:


UE_LOG(LogTemp, Warning, TEXT("GMC: %d"), Component->Materials.Num());
			Material = Component->GetMaterial(0);
			

			if (Material == NULL)
			{
				UE_LOG(LogTemp, Warning, TEXT("NULL"));
				Material = UMaterial::GetDefaultMaterial(MD_Surface);
			}
			else UE_LOG(LogTemp, Warning, TEXT("NOT NULL"));

and it says:

[]

LogTemp:Warning: Ret: 0
LogTemp:Warning: Ret: 0
LogTemp:Warning: GMC: 0
LogTemp:Warning: NULL
LogTemp:Warning: Ret: 0
[/]

“Ret: 0” comes from here:



int32 UGeneratedMeshComponent::GetNumMaterials() const
{
	UE_LOG(LogTemp, Warning, TEXT("Ret: %d"), Materials.Num());
	return 1;
}

If I change this to “return Materials.Num()” the triangle isn’t rendered at all, since it then always returns 0…

Sorry for the much code, but do you have any idea how to fix this issue?

Thanks,
Taces

Working with UE4.5

I’m working on getting this running with UE4.5…

I am getting the following errors:



Error	2	error C2660: 'UMeshComponent::GetMaterialRelevance' : function does not take 0 arguments	C:\...]\GeneratedMeshComponent.cpp	118	1	MGTycoon
Error	3	error C2660: 'CreatePrimitiveUniformBufferImmediate' : function does not take 4 arguments	C:\...]\GeneratedMeshComponent.cpp	209	1	MGTycoon


It seems like the signatures changed for these back-end functions?

Just stabbing around I got it to compile with:



118|			, MaterialRelevance(Component->GetMaterialRelevance(ERHIFeatureLevel::Num))
...|
209|			BatchElement.PrimitiveUniformBuffer = CreatePrimitiveUniformBufferImmediate(GetLocalToWorld(), GetBounds(), GetLocalBounds(), true, true);


Since I don’t know what this does exactly, I was wondering if anybody knows what I should actually be doing to solve this problem.

[=Sgt_Ludwig;165019]
I’m working on getting this running with UE4.5…

I am getting the following errors:



Error	2	error C2660: 'UMeshComponent::GetMaterialRelevance' : function does not take 0 arguments	C:\...]\GeneratedMeshComponent.cpp	118	1	MGTycoon
Error	3	error C2660: 'CreatePrimitiveUniformBufferImmediate' : function does not take 4 arguments	C:\...]\GeneratedMeshComponent.cpp	209	1	MGTycoon


It seems like the signatures changed for these back-end functions?

[/]

For the material relevance I pulled from the custom mesh they package in with releases for this:


Component->GetMaterialRelevance(GetScene()->GetFeatureLevel())

For the final argument of ‘CreatePrimitiveUniformBufferImmediate’ I get sporadic crashes if I don’t True it.

If anybody else has the same issue as I did (Material is not applied), I figured out how to do it: Instead of applying the material inside the constructor of my actor, I had to apply it in “PostInitializeComponents” - this way everything works fine! Although I don’t really understand why it doesn’t work in the constructor, it would be great if somebody could explan that? I’d suppose that the components are recreated after the constructor of my actor, but I dont’ know why this should happen.