Announcement

Collapse
No announcement yet.

Generate Procedural Mesh

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

    #16
    Here's the example. https://wiki.unrealengine.com/Proced...esh_Generation



    I haven't been able to embed images (I'm a wiki noob and short on time), but there are links. Here's what the blueprint portion looks like, really standard and simple:

    Last edited by Andargor; 11-28-2014, 01:49 PM.
    It is by will alone I set my code in motion.
    It is by coding that thoughts acquire speed, the hands acquire shaking, the shaking becomes a warning.
    It is by will alone I set my code in motion.

    Comment


      #17
      very cool, ill see if i can make my voxel chunk object like that.
      UDK and UE4 programmer and Unreal engine 4 betatester. Currently working on commercial VR games for PSVR.
      Deep knowlegde of C++ and blueprints. Open to freelance work.
      Games released, Deathwave(Steam), VRMultigames(Steam), DWVR(Steam,Oculus,PSVR):
      http://store.steampowered.com/app/463870
      http://store.steampowered.com/app/500360
      http://store.steampowered.com/app/520750

      Comment


        #18
        Originally posted by phoboz View Post
        Is there a performance hit when using dynamically created geometry rather than regular static mesh?
        Right now this geometry is slightly slower than a regular static mesh, and doesn't support things like precomputed lighting.
        Lead Programmer - UE4 Animation/Physics/Audio Team - Epic Games
        Twitter: @EpicJamesG

        Comment


          #19
          Originally posted by dmacesic View Post
          Aha! You guys didn't notice my normals were inverted... (Unreal seems to like clockwise vertices) I will share my code on the wiki to get you started with quick and dirty instructions, although it will not be to Rama-sama standards I'll post here when it's up.

          Here's another with more segments and proper normals:


          Wow this is awesome!

          Amazing work Dmacesic!

          Please do share the tutorial!

          Amazing things will come of it!

          EDIT

          His tutorial is now up and available here!

          Procedural Mesh

          https://wiki.unrealengine.com/Proced...esh_Generation




          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


            #20


            I thought I had published that yesterday, did you do anything to make it public?
            It is by will alone I set my code in motion.
            It is by coding that thoughts acquire speed, the hands acquire shaking, the shaking becomes a warning.
            It is by will alone I set my code in motion.

            Comment


              #21
              Originally posted by dmacesic View Post


              I thought I had published that yesterday, did you do anything to make it public?
              To clarify:

              "His tutorial is now up and available here!"

              I was just excitedly letting people know you already posted it

              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


                #22
                Hey guys, just wanted to share what I've been tinkering around with on this stuff to be able to set UV's for the custom meshes:

                First, I split off the FCustomMeshTriangle struct into these two structs:

                Code:
                USTRUCT(BlueprintType)
                struct FCustomMeshTriangleVertex
                {
                	GENERATED_USTRUCT_BODY()
                
                	UPROPERTY(EditAnywhere, Category = Triangle)
                	FVector Position;
                
                	UPROPERTY(EditAnywhere, Category = Triangle)
                	float U;
                
                	UPROPERTY(EditAnywhere, Category = Triangle)
                	float V;
                };
                
                USTRUCT(BlueprintType)
                struct FCustomMeshTriangle
                {
                	GENERATED_USTRUCT_BODY()
                
                	UPROPERTY(EditAnywhere, Category=Triangle)
                	FCustomMeshTriangleVertex Vertex0;
                
                	UPROPERTY(EditAnywhere, Category=Triangle)
                	FCustomMeshTriangleVertex Vertex1;
                
                	UPROPERTY(EditAnywhere, Category=Triangle)
                	FCustomMeshTriangleVertex Vertex2;
                };
                Then, the constructor for the FCustomMeshSceneProxy class would change to this:

                Code:
                FCustomMeshSceneProxy(UCustomMeshComponent* Component)
                		: FPrimitiveSceneProxy(Component)
                		, MaterialRelevance(Component->GetMaterialRelevance())
                	{
                		const FColor VertexColor(255,255,255);
                
                		// Add each triangle to the vertex/index buffer
                		for(int TriIdx=0; TriIdx<Component->CustomMeshTris.Num(); TriIdx++)
                		{
                			FCustomMeshTriangle& Tri = Component->CustomMeshTris[TriIdx];
                
                			const FVector Edge01 = (Tri.Vertex1.Position - Tri.Vertex0.Position);
                			const FVector Edge02 = (Tri.Vertex2.Position - Tri.Vertex0.Position);
                
                			const FVector TangentX = Edge01.SafeNormal();
                			const FVector TangentZ = (Edge02 ^ Edge01).SafeNormal();
                			const FVector TangentY = (TangentX ^ TangentZ).SafeNormal();
                
                			FDynamicMeshVertex Vert0;
                			Vert0.Position = Tri.Vertex0.Position;
                			Vert0.Color = VertexColor;
                			Vert0.SetTangents(TangentX, TangentY, TangentZ);
                			Vert0.TextureCoordinate.Set(Tri.Vertex0.U, Tri.Vertex0.V);
                			int32 VIndex = VertexBuffer.Vertices.Add(Vert0);
                			IndexBuffer.Indices.Add(VIndex);
                
                			FDynamicMeshVertex Vert1;
                			Vert1.Position = Tri.Vertex1.Position;
                			Vert1.Color = VertexColor;
                			Vert1.SetTangents(TangentX, TangentY, TangentZ);
                			Vert1.TextureCoordinate.Set(Tri.Vertex1.U, Tri.Vertex1.V);
                			VIndex = VertexBuffer.Vertices.Add(Vert1);
                			IndexBuffer.Indices.Add(VIndex);
                
                			FDynamicMeshVertex Vert2;
                			Vert2.Position = Tri.Vertex2.Position;
                			Vert2.Color = VertexColor;
                			Vert2.SetTangents(TangentX, TangentY, TangentZ);
                			Vert2.TextureCoordinate.Set(Tri.Vertex2.U, Tri.Vertex2.V);
                			VIndex = VertexBuffer.Vertices.Add(Vert2);
                			IndexBuffer.Indices.Add(VIndex);
                		}
                
                		// Init vertex factory
                		VertexFactory.Init(&VertexBuffer);
                
                		// Enqueue initialization of render resource
                		BeginInitResource(&VertexBuffer);
                		BeginInitResource(&IndexBuffer);
                		BeginInitResource(&VertexFactory);
                
                		// Grab material
                		Material = Component->GetMaterial(0);
                		if(Material == NULL)
                		{
                			Material = UMaterial::GetDefaultMaterial(MD_Surface);
                		}
                	}
                Lastly, to test this out I added a couple functions:

                Code:
                bool UCustomMeshComponent::ClearCustomMeshTriangles()
                {
                	CustomMeshTris.Empty();
                	// Need to recreate scene proxy to send it over
                	MarkRenderStateDirty();
                
                	return true;
                }
                
                bool UCustomMeshComponent::AddCustomBox(const float& Size, const FVector& Position)
                {
                	// make vertex positions
                	FVector p0 = FVector(Position.X, Position.Y, Position.Z);
                	FVector p1 = FVector(Position.X, Position.Y, Position.Z + Size);
                	FVector p2 = FVector(Position.X + Size, Position.Y, Position.Z + Size);
                	FVector p3 = FVector(Position.X + Size, Position.Y, Position.Z);
                	FVector p4 = FVector(Position.X + Size, Position.Y + Size, Position.Z);
                	FVector p5 = FVector(Position.X + Size, Position.Y + Size, Position.Z + Size);
                	FVector p6 = FVector(Position.X, Position.Y + Size, Position.Z + Size);
                	FVector p7 = FVector(Position.X, Position.Y + Size, Position.Z);
                
                	FCustomMeshTriangleVertex v0;
                	FCustomMeshTriangleVertex v1;
                	FCustomMeshTriangleVertex v2;
                	FCustomMeshTriangleVertex v3;
                	v0.U = 0; v0.V = 0;
                	v1.U = 0; v1.V = .5;
                	v2.U = .5; v2.V = .5;
                	v3.U = .5; v3.V = 0;
                
                	FCustomMeshTriangle t1;
                	FCustomMeshTriangle t2;
                
                	// front face
                	v0.Position = p0;
                	v1.Position = p1;
                	v2.Position = p2;
                	v3.Position = p3;
                	t1.Vertex0 = v0;
                	t1.Vertex1 = v1;
                	t1.Vertex2 = v2;
                	t2.Vertex0 = v0;
                	t2.Vertex1 = v2;
                	t2.Vertex2 = v3;
                	CustomMeshTris.Add(t1);
                	CustomMeshTris.Add(t2);
                
                	//back face
                	v0.Position = p4;
                	v1.Position = p5;
                	v2.Position = p6;
                	v3.Position = p7;
                	t1.Vertex0 = v0;
                	t1.Vertex1 = v1;
                	t1.Vertex2 = v2;
                	t2.Vertex0 = v0;
                	t2.Vertex1 = v2;
                	t2.Vertex2 = v3;
                	CustomMeshTris.Add(t1);
                	CustomMeshTris.Add(t2);
                
                	// left face
                	v0.Position = p7;
                	v1.Position = p6;
                	v2.Position = p1;
                	v3.Position = p0;
                	t1.Vertex0 = v0;
                	t1.Vertex1 = v1;
                	t1.Vertex2 = v2;
                	t2.Vertex0 = v0;
                	t2.Vertex1 = v2;
                	t2.Vertex2 = v3;
                	CustomMeshTris.Add(t1);
                	CustomMeshTris.Add(t2);
                
                	// right face
                	v0.Position = p3;
                	v1.Position = p2;
                	v2.Position = p5;
                	v3.Position = p4;
                	t1.Vertex0 = v0;
                	t1.Vertex1 = v1;
                	t1.Vertex2 = v2;
                	t2.Vertex0 = v0;
                	t2.Vertex1 = v2;
                	t2.Vertex2 = v3;
                	CustomMeshTris.Add(t1);
                	CustomMeshTris.Add(t2);
                
                	// top face
                	v0.Position = p1;
                	v1.Position = p6;
                	v2.Position = p5;
                	v3.Position = p2;
                	t1.Vertex0 = v0;
                	t1.Vertex1 = v1;
                	t1.Vertex2 = v2;
                	t2.Vertex0 = v0;
                	t2.Vertex1 = v2;
                	t2.Vertex2 = v3;
                	CustomMeshTris.Add(t1);
                	CustomMeshTris.Add(t2);
                
                	// bottom face
                	v0.Position = p3;
                	v1.Position = p4;
                	v2.Position = p7;
                	v3.Position = p0;
                	t1.Vertex0 = v0;
                	t1.Vertex1 = v1;
                	t1.Vertex2 = v2;
                	t2.Vertex0 = v0;
                	t2.Vertex1 = v2;
                	t2.Vertex2 = v3;
                	CustomMeshTris.Add(t1);
                	CustomMeshTris.Add(t2);
                
                	MarkRenderStateDirty();
                
                	return true;
                }
                With all that, and using the AddCustomBox function, applying materials to the custom mesh components should now look something like this:



                and then I went a little crazy with for loops:

                Comment


                  #23
                  Originally posted by FireOnHigh View Post
                  and then I went a little crazy with for loops
                  Must have been a long loop...
                  Nice work!
                  Point Cloud Plugin: Project Website | Forum Thread | Roadmap

                  If you need help: join me on Discord
                  Please support me on Patreon if you enjoy my content

                  Comment


                    #24
                    Originally posted by FireOnHigh View Post
                    Hey guys, just wanted to share what I've been tinkering around with on this stuff to be able to set UV's for the custom meshes:
                    Cool stuff, feel free to adjust the wiki article if you wish: https://wiki.unrealengine.com/Proced...esh_Generation

                    Or perhaps make your own since I renamed the class.
                    Last edited by Andargor; 04-01-2014, 11:36 PM.
                    It is by will alone I set my code in motion.
                    It is by coding that thoughts acquire speed, the hands acquire shaking, the shaking becomes a warning.
                    It is by will alone I set my code in motion.

                    Comment


                      #25
                      This is very cool. And I have got it working with a dev/editor build. However, a shipping build with a cooked assets folder causes a crash as soon as the custom geometry creation is triggered.

                      How would one go about making procedural geometry work in a non-editor build?

                      Comment


                        #26
                        I think another user actually found this bug yesterday, we'll try and get a fix in for the next release!
                        Lead Programmer - UE4 Animation/Physics/Audio Team - Epic Games
                        Twitter: @EpicJamesG

                        Comment


                          #27
                          Oh yeah, I just cooked my stuff and it does crash. Is there a bug report somewhere I can look at and perhaps add to?
                          It is by will alone I set my code in motion.
                          It is by coding that thoughts acquire speed, the hands acquire shaking, the shaking becomes a warning.
                          It is by will alone I set my code in motion.

                          Comment


                            #28
                            Originally posted by dmacesic View Post
                            Oh yeah, I just cooked my stuff and it does crash. Is there a bug report somewhere I can look at and perhaps add to?
                            My initial assumption was that I may be missing some specific material-assigning in my mesh-gen code, which in an editor-build, default materials/textures would be applied in places that I missed, but in a cooked build any undefined material refs would result in null (or random address) mat/tex pointers.
                            Last edited by RogerMelly; 04-04-2014, 12:22 PM.

                            Comment


                              #29
                              The problem with packaged builds is that it dereferences GEngine->WireframeMaterial, which is NULL after packaging the game without editor support. You can fix the problem by checking if WITH_EDITOR is true before dereferencing WireframeMaterial.

                              You can see the fix I made to my similar primitive component implementation here: https://github.com/AndrewScheidecker...691e354b36728a
                              Andrew - Twitter - Web

                              Comment


                                #30
                                Originally posted by AndrewJSch View Post
                                The problem with packaged builds is that it dereferences GEngine->WireframeMaterial, which is NULL after packaging the game without editor support. You can fix the problem by checking if WITH_EDITOR is true before dereferencing WireframeMaterial.

                                You can see the fix I made to my similar primitive component implementation here: https://github.com/AndrewScheidecker...691e354b36728a
                                Yep! That's fixed it!

                                Comment

                                Working...
                                X