Created
July 9, 2024 03:00
-
-
Save wxvyjb/9be5790a09457563819bc7b23341a06b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Random notes/code snippets for using the Realtime Mesh Component plugin for Unreal Engine. | |
I could not find many working examples for this. May create a repo for this later. | |
/////////////////////////////////////////////////////////////////////////////////////////////// | |
// Code for Normal and Tangent calculation to make stuff less flat since it's just a flat plane with a height map projected | |
FVector3f left = x > 0 ? VertexPositions[(y * TerrainGeneratorParameters.TerrainSizeVertices) + (x - 1)] : VertexPositions[i]; | |
FVector3f right = x < TerrainGeneratorParameters.TerrainSizeVertices - 1 ? VertexPositions[(y * TerrainGeneratorParameters.TerrainSizeVertices) + (x + 1)] : VertexPositions[i]; | |
FVector3f bottom = y > 0 ? VertexPositions[((y - 1) * TerrainGeneratorParameters.TerrainSizeVertices) + x] : VertexPositions[i]; | |
FVector3f top = y < TerrainGeneratorParameters.TerrainSizeVertices - 1 ? VertexPositions[((y + 1) * TerrainGeneratorParameters.TerrainSizeVertices) + x] : VertexPositions[i]; | |
// Calculate the tangent vectors along the x and y directions | |
FVector3f TangentX = right - left; | |
FVector3f TangentY = top - bottom; | |
// The normal vector is the cross product of the tangent vectors | |
Normals[i] = FVector3f::CrossProduct(TangentX, TangentY).GetSafeNormal(); | |
Tangents[i] = TangentX.GetSafeNormal(); | |
/////////////////////////////////////////////////////////////////////////////////////////////// | |
// Boilerplate code to needed generate a single square mesh | |
FRealtimeMeshTriMeshData RealtimeMeshData; | |
TArray<FVector> Verts; | |
Verts.Add(FVector::ZeroVector); | |
Verts.Add(FVector(100.0f, 0.0f, 0.0f)); | |
Verts.Add(FVector(0.0f, 100.0f, 0.0f)); | |
Verts.Add(FVector(0.0f, -100.0f, 0.0f)); | |
TArray<int32> Tris; | |
Tris.Add(0); | |
Tris.Add(2); | |
Tris.Add(1); | |
Tris.Add(0); | |
Tris.Add(1); | |
Tris.Add(3); | |
TArray<int32> MI; | |
MI.Add(0); | |
MI.Add(0); | |
TArray<FVector2D> UV0; | |
UV0.Add(FVector2D(0.0f, 0.0f)); | |
UV0.Add(FVector2D(0.0f, 1.0f)); | |
UV0.Add(FVector2D(1.0f, 1.0f)); | |
UV0.Add(FVector2D(1.0f, 0.0f)); | |
TArray<FVector> Normals; | |
RealtimeMeshData.UV0 = UV0; | |
RealtimeMeshData.Positions = Verts; | |
RealtimeMeshData.Triangles = Tris; | |
RealtimeMeshData.MaterialIndex = MI; | |
RealtimeMeshData.Normals = Normals; | |
/////////////////////////////////////////////////////////////////////////////////////////////// | |
// Code to generate a wavy Sin/Cos plane using the RealtimeMeshComponent plugin. | |
RealtimeMesh = nullptr; | |
RealtimeMesh = GetRealtimeMeshComponent()->InitializeRealtimeMesh<URealtimeMeshSimple>(); | |
FRealtimeMeshStreamSet StreamSet; | |
TRealtimeMeshBuilderLocal<uint16, FPackedNormal, FVector2DHalf, 1> Builder(StreamSet); | |
Builder.EnableTangents(); | |
Builder.EnableTexCoords(); | |
Builder.EnableColors(); | |
// Poly groups allow us to easily create a single set of buffers with multiple sections by adding an index to the triangle data | |
Builder.EnablePolyGroups(); | |
// initialize vertices | |
for (uint32 y = 0; y < chunk_y; y++) | |
{ | |
for (uint32 x = 0; x < chunk_x; x++) | |
{ | |
//vertices.Add( | |
Builder | |
.AddVertex(FVector3f(x * 10.f, y * 10.f, (sin(x) * cos(y) * 10.f))) | |
.SetNormalAndTangent(FVector3f(0.0f, 0.0f, 1.0f), FVector3f(1.0f, 0.0f, 0.0f)) | |
.SetColor(FColor::Red) | |
.SetTexCoord(FVector2f(static_cast<float>(x) / (chunk_x - 1), static_cast<float>(y) / (chunk_y - 1))); | |
//); | |
} | |
} | |
for (uint32 y = 0; y < chunk_y - 1; y++) | |
{ | |
for (uint32 x = 0; x < chunk_x - 1; x++) | |
{ | |
uint32 v0 = (y * chunk_x) + x; | |
uint32 v1 = (y * chunk_x) + x + 1; | |
uint32 v2 = ((y + 1) * chunk_x) + x; | |
uint32 v3 = ((y + 1) * chunk_x) + x + 1; | |
uint32 tri1 = Builder.AddTriangle(v2, v1, v0, 0); | |
uint32 tri2 = Builder.AddTriangle(v1, v2, v3, 0); | |
} | |
} | |
// setup material slots | |
RealtimeMesh->SetupMaterialSlot(0, "PrimaryMaterial"); | |
const FRealtimeMeshSectionGroupKey GroupKey = FRealtimeMeshSectionGroupKey::Create(0, FName("TestTriangle")); | |
const FRealtimeMeshSectionKey PolyGroup0SectionKey = FRealtimeMeshSectionKey::CreateForPolyGroup(GroupKey, 0); | |
// Now we create the section group, since the stream set has polygroups, this will create the sections as well | |
RealtimeMesh->CreateSectionGroup(GroupKey, StreamSet); | |
// Update the configuration of both the polygroup sections. | |
RealtimeMesh->UpdateSectionConfig(PolyGroup0SectionKey, FRealtimeMeshSectionConfig(ERealtimeMeshSectionDrawType::Static, 0)); | |
Super::OnGenerateMesh_Implementation(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment