Generate Procedural Mesh

Has anyone had any luck generating a procedural mesh as a static mesh? My procedural mesh actor is a child of AStaticMeshActor, and I’ve tried:



	GenerateCube(triangles, cubeSize, cubeSize, cubeSize, FVector(0.f, 0.f, 0.f), false, false, false);
	mesh->SetProceduralMeshTriangles(triangles);
	StaticMeshComponent->SetStaticMesh(Cast<UStaticMesh>(mesh));

with no luck. Ideally I’d like to be able to bake lighting on the mesh which isn’t possible as a procedural mesh. Is this even possible?

[=;229704]
Has anyone had any luck generating a procedural mesh as a static mesh? My procedural mesh actor is a child of AStaticMeshActor, and I’ve tried:



	GenerateCube(triangles, cubeSize, cubeSize, cubeSize, FVector(0.f, 0.f, 0.f), false, false, false);
	mesh->SetProceduralMeshTriangles(triangles);
	StaticMeshComponent->SetStaticMesh(Cast<UStaticMesh>(mesh));

with no luck. Ideally I’d like to be able to bake lighting on the mesh which isn’t possible as a procedural mesh. Is this even possible?
[/]

Yesterday i was tried too. But unreal crash whith this code. I’d like to be able to bake light and vertex paint. I see that the proceduralmeshcomponent and the staticmeshcomponent is a child of one class - meshcomponent. May be its possible to make proceduralmesh with the staticmesh opportunities. But i dont know how. Now i working with this idea. If u find how pleas send a message.

I am doing some procedural terrain. The output of the algorithm (Dual Contouring) is a vertex list(position, normal), and a list of indices.

The output is also in Quads not triangles. I know I will have to triangulate these quads, but how do I create the tangent vectors? This terrain is smooth and the quads share verts (so I cannot create the tangents like the wiki does) it will just end up with a normal that favors the last triangle that uses that vert).

Do I create the tangents for every triangle that uses that vert then average them? It just feels like if I already have the normal I shouldn’t have to go through all that (I could be wrong, it would not be the first time).

[=TaurusI76;228819]
I’ve had the exact same problem since the update from 4.6.1 to 4.7. I’d be super glad if somebody had a solution…
[/]

I found the solution to this. You are missing the “GetDynamicMeshElements” function inside the FGeneratedMeshSceneProxy. Take a look at the project for the function.

[=JohnnyBeans78;231909]
I found the solution to this. You are missing the “GetDynamicMeshElements” function inside the FGeneratedMeshSceneProxy. Take a look at the project for the function.
[/]

Could you please provide a link for this project? The one I’ve found doesn’t have this code related to “GetDynamicMeshElements”

[=;231936]
Could you please provide a link for this project? The one I’ve found doesn’t have this code related to “GetDynamicMeshElements”
[/]

https://.com//UE4ProceduralMesh/

[=JohnnyBeans78;232096]
https://.com//UE4ProceduralMesh/
[/]

Maybe I’m too stupid for this. I use UE4.6.1 and after adding into the buildfile “RHI”, “RenderCore”, “ShaderCore”, creating ProceduralTriangleActor and ProceduralMeshComponent I get errors in the following lines:

ProceduralMeshComponent.h:
line #include “ProceduralMeshComponent.generated.h” Error: cannot open source file “ProceduralMeshComponent.generated.h”
line FVector Position; Error: expected a ‘;’
line FProceduralMeshVertex Vertex0; Error: expected a ‘;’
line class UProceduralMeshComponent : public UMeshComponent, public IInterface_CollisionDataProvider{ GENERATED_UCLASS_BODY()… Error: expected an identifier

ProceduralMeshComponent.cpp:
lline UProceduralMeshComponent::UProceduralMeshComponent(const FObjectInitializer& PCIP): Super(PCIP) Error: no instance of overloaded funcion “UProceduralMeshComponent::UProceduralMeshComponent” matches the specified type

I’m sitting at this problem for about 2 weeks, can somebody help please?

I just became able to compile the code. The mistake was that I added the class ProceduralMeshComponent from within visual instead of the ue editor add code wizard

[=JohnnyBeans78;231475]
I am doing some procedural terrain. The output of the algorithm (Dual Contouring) is a vertex list(position, normal), and a list of indices.

The output is also in Quads not triangles. I know I will have to triangulate these quads, but how do I create the tangent vectors? This terrain is smooth and the quads share verts (so I cannot create the tangents like the wiki does) it will just end up with a normal that favors the last triangle that uses that vert).

Do I create the tangents for every triangle that uses that vert then average them? It just feels like if I already have the normal I shouldn’t have to go through all that (I could be wrong, it would not be the first time).
[/]

I am interested in this as well. I’m attempting to implement the same algorithm. So I guess there’s no way to define meshes as quads?

I’m trying out mordentral’s method of calculating tangents in the shader and I’m getting a weird lighting issue where the shadows are inverted from each other on the left and right sides. What could be causing this issue?

https://.com/watch?v=Q30nwMeH40M

You have still marked the Tangent Space Normal in the checkbox on the left (in your material). You sould remove that maker if you are computing your normals within the shader.

Ok, fixed that, but I still have the lighting issue with point lights. Spot lights don’t seem to have that problem though. Also, now the shadow intensity seems to have a correlation with the camera distance where if you are far away from the object, that shadowing looks correct but once you zoom in it’s almost completely black.

Edit: It looks like MeshUtilites.cpp has all of the tangent calculation stuff built in and they just updated it to calculate in Mikktspace. Is there a way that we can use this in the proceduralmeshcomponent ?

[=;238214]
Ok, fixed that, but I still have the lighting issue with point lights. Spot lights don’t seem to have that problem though. Also, now the shadow intensity seems to have a correlation with the camera distance where if you are far away from the object, that shadowing looks correct but once you zoom in it’s almost completely black.
[/]

I can’t replicate the problem with point lights in my scene. The shadowing problem sounds like you need to add a skylight to the level though, as with fully dynamic lighting the shadows will be pure black without one.

Couple of notes from the video too:

#1: You need to normalize the cross result for the normal, other you will get inconsistencies.

#2: I stopped using that method of combining normal maps as it was killing a lot of the angled depth. Unreal has a node for adding detail maps to normal maps but it is intended for Packed normals and won’t work with derived ones. I have attached a picture of a new material node I made that is doing my normal combining now, it has both WhiteOut and RNM methods in it (RNM is what the unreal version does and has the best looking result).

#3: That procedural cabinet system looks f***ing cool, good work.

Thanks for looking into it. I’m not quite getting it to work but I’ll keep at it.

Some of the stuff in the cabinet system uses a script that parses an obj file to generate the code for more complicated procedural geometry. I plan on releasing it once I get the normal mapping issue fixed.

Edit: I think I have the normals squared away. Static mesh on the left, procedural on the right.

[=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?
[/]

Could you explain how you procedurally create the mesh directly in the editor instead of in the game?

[=Meessen;238489]
Could you explain how you procedurally create the mesh directly in the editor instead of in the game?
[/]

Put the code to generate in “postload()” if the user has authority (is owner/ is the server) and run the generation in “Beginplay()” if it is a client. That way it will work in editor and in game.

I’m having an issue with the generated mesh based actor (lathe) falling through the floor. I started with the UE 4.7.2 first-person C++ template. I cloned the latest UE4ProceduralMesh code and copied the ProceduralMeshComponent and ProceduralLatheActor. I’ve tried enabling physics and collisions in code as well as creating an instance in the editor and turning on physics and collisions. I play the game from the editor and every time it falls from the sky down through the floor.

It collides with my player character, but then bounces off through a wall or through the floor.

Is something broken here or do I need to do something differently?

Anyone else getting these warnings?


[2015.03.07-02.06.13:844] 27]PIE:Warning: Warning AttachTo: '/Game/Maps/HorrorScene.HorrorScene:PersistentLevel.Pro_Horror_Floor_C_1.Procedural Floor' is not static  (in blueprint "Pro_Horror_Floor"), cannot attach '/Game/Maps/HorrorScene.HorrorScene:PersistentLevel.Pro_Horror_Floor_C_1.StaticMeshComponent0' which is static to it. Aborting.
[2015.03.07-02.06.15:906][268]Cmd: CAMERA ALIGN ACTIVEVIEWPORTONLY
[2015.03.07-02.06.15:907][268]LogUnrealMath:Error: FMatrix::Inverse(), trying to invert a NIL matrix, this results in NaNs! Use Inverse() instead.


You can’t attach static mesh to movable or the other way around. all actor tree must be either static or movable.

[=ScottMG;239829]
I’m having an issue with the generated mesh based actor (lathe) falling through the floor. I started with the UE 4.7.2 first-person C++ template. I cloned the latest UE4ProceduralMesh code and copied the ProceduralMeshComponent and ProceduralLatheActor. I’ve tried enabling physics and collisions in code as well as creating an instance in the editor and turning on physics and collisions. I play the game from the editor and every time it falls from the sky down through the floor.

It collides with my player character, but then bounces off through a wall or through the floor.

Is something broken here or do I need to do something differently?
[/]

You need to set the collision channels up correctly.

[= ;239913]
You can’t attach static mesh to movable or the other way around. all actor tree must be either static or movable.
[/]

It throws warnings all over the place but it lets you do it and it works fine.

I think it was indirectly related to me manually inputting triangle data. When I was only working with 50 or so triangles it was ok and my compile times were around 30 seconds. 300 triangles and it would throw errors (NAN, etc) and compile times were up around 8 minutes. 800 triangles won’t compile. I either get a malloc error or a build failed(no other info). This however works fine no matter how many triangles I add:


void AProcedural_Horror_Floor::GenerateFloor()
{
	//prevent negative divsions
	if (divisionsX < 0)
	{
		divisionsX = 0;
	}

	if (divisionsY < 0)
	{
		divisionsY = 0;
	}

	//calculate total number of triangles
	int numQuads = (divisionsY + 1) * (divisionsX + 1);
	TArray<FProceduralMeshTriangle> t;
	
	int curRowIndex = 0;
	int curColIndex = 0;

	//t.AddUninitialized(numQuads * 2);
	for (int i = 0; i < numQuads * 2; i++)
	{
		FProceduralMeshTriangle temp;
		t.Add(temp);
	}

	FVector faceNormal = FVector(0.f, 0.f, 1.f);
	
	for (int i = 0; i < numQuads; i++)
	{
		if (curColIndex > divisionsX)
		{
			curRowIndex++;
			curColIndex = 0;
		}

		//debug info
		//UE_LOG(LogTemp, Warning, TEXT("curRowIndex# %d curColIndex %d"), curRowIndex, curColIndex);
		float quadsizeX;
		float quadsizeY;

		//need quad size and offset
		if (divisionsX > 0)
		{
			quadsizeX = sizeX / (divisionsX + 1);
		}

		else
		{
			quadsizeX = sizeX;
		}

		if (divisionsY > 0)
		{
			quadsizeY = sizeY / (divisionsY + 1);
		}

		else
		{
			quadsizeY = sizeY;
		}

		
		FVector offset = FVector(curColIndex * quadsizeX, curRowIndex * quadsizeY, 0.f);
		FVector2D offset2D = FVector2D(curColIndex * quadsizeX, curRowIndex * quadsizeY);

		

		//need 4 vertices per quad
		FVector vertexPos[4];
		vertexPos[0] = (FVector(0.f, 0.f, 0.f) + offset) * scaleMod;
		vertexPos[1] = (FVector(quadsizeX, 0.f, 0.f) + offset) * scaleMod;
		vertexPos[2] = (FVector(0.f, quadsizeY, 0.f) + offset) * scaleMod;
		vertexPos[3] = (FVector(quadsizeX, quadsizeY, 0.f) + offset) * scaleMod;

		vertexPos[0] = vertexPos[0] + (FVector(0.f, 0.f, abs((vertexPos[0] - bulgePosition).Size() * bulgeAmount))) * scaleMod;
		vertexPos[1] = vertexPos[1] + (FVector(0.f, 0.f, abs((vertexPos[1] - bulgePosition).Size() * bulgeAmount))) * scaleMod;
		vertexPos[2] = vertexPos[2] + (FVector(0.f, 0.f, abs((vertexPos[2] - bulgePosition).Size() * bulgeAmount))) * scaleMod;
		vertexPos[3] = vertexPos[3] + (FVector(0.f, 0.f, abs((vertexPos[3] - bulgePosition).Size() * bulgeAmount))) * scaleMod;

		//UV coordinates
		FVector2D vt[4];
		vt[0] = (FVector2D(0.f, 0.f) + offset2D) / UVScale;
		vt[1] = (FVector2D(quadsizeX, 0.f) + offset2D) / UVScale;
		vt[2] = (FVector2D(0.f, quadsizeY) + offset2D) / UVScale;
		vt[3] = (FVector2D(quadsizeX, quadsizeY) + offset2D) / UVScale;

		t[i * 2].Vertex0.Position = vertexPos[2];      t[i * 2].Vertex0.U = vt[2].X;     t[i * 2].Vertex0.V = vt[2].Y;     t[i * 2].Vertex0.vNormal = faceNormal;     t[i * 2].Vertex0.manualNormals = true;
		t[i * 2].Vertex1.Position = vertexPos[1];      t[i * 2].Vertex1.U = vt[1].X;     t[i * 2].Vertex1.V = vt[1].Y;     t[i * 2].Vertex1.vNormal = faceNormal;     t[i * 2].Vertex1.manualNormals = true;
		t[i * 2].Vertex2.Position = vertexPos[0];      t[i * 2].Vertex2.U = vt[0].X;     t[i * 2].Vertex2.V = vt[0].Y;     t[i * 2].Vertex2.vNormal = faceNormal;     t[i * 2].Vertex2.manualNormals = true;
		
		t(i * 2) + 1].Vertex0.Position = vertexPos[3];      t(i * 2) + 1].Vertex0.U = vt[3].X;     t(i * 2) + 1].Vertex0.V = vt[3].Y;     t(i * 2) + 1].Vertex0.vNormal = faceNormal;     t(i * 2) + 1].Vertex0.manualNormals = true;
		t(i * 2) + 1].Vertex1.Position = vertexPos[1];      t(i * 2) + 1].Vertex1.U = vt[1].X;     t(i * 2) + 1].Vertex1.V = vt[1].Y;     t(i * 2) + 1].Vertex1.vNormal = faceNormal;     t(i * 2) + 1].Vertex1.manualNormals = true;
		t(i * 2) + 1].Vertex2.Position = vertexPos[2];      t(i * 2) + 1].Vertex2.U = vt[2].X;     t(i * 2) + 1].Vertex2.V = vt[2].Y;     t(i * 2) + 1].Vertex2.vNormal = faceNormal;     t(i * 2) + 1].Vertex2.manualNormals = true;

		t[i * 2].attachedTriangles.Add((i * 2) + 1);

		curColIndex++;
	}

	proceduralFloor->SetProceduralMeshTriangles(t);
	
}