|
| 1 | +// Copyright TriAxis Games, L.L.C. All Rights Reserved. |
| 2 | + |
| 3 | + |
| 4 | +#include "RealtimeMeshByStreamBuilder.h" |
| 5 | +#include "RealtimeMeshSimple.h" |
| 6 | + |
| 7 | + |
| 8 | +ARealtimeMeshByStreamBuilder::ARealtimeMeshByStreamBuilder() |
| 9 | +{ |
| 10 | + PrimaryActorTick.bCanEverTick = false; |
| 11 | +} |
| 12 | + |
| 13 | +void ARealtimeMeshByStreamBuilder::OnGenerateMesh_Implementation() |
| 14 | +{ |
| 15 | + // Initialize to a simple mesh, this behaves the most like a ProceduralMeshComponent |
| 16 | + // Where you can set the mesh data and forget about it. |
| 17 | + URealtimeMeshSimple* RealtimeMesh = GetRealtimeMeshComponent()->InitializeRealtimeMesh<URealtimeMeshSimple>(); |
| 18 | + |
| 19 | + // The most important part of the mesh data is the StreamSet, it contains the individual buffers, |
| 20 | + // like position, tangents, texcoords, triangles etc. |
| 21 | + FRealtimeMeshStreamSet StreamSet; |
| 22 | + |
| 23 | + // Setup a stream for position of type FVector3f, and wrap it in a direct builder for FVector3f |
| 24 | + TRealtimeMeshStreamBuilder<FVector3f> PositionBuilder(StreamSet.AddStream(FRealtimeMeshStreams::Position, GetRealtimeMeshBufferLayout<FVector3f>())); |
| 25 | + |
| 26 | + // Setup a stream for tangents of t ype FRealtimeMeshTangentsNormalPrecision, and then wrap it in a |
| 27 | + // builder that lets us work with it in full precision by using the FRealtimeMeshTangentsHighPrecision as the interface type |
| 28 | + TRealtimeMeshStreamBuilder<FRealtimeMeshTangentsHighPrecision, FRealtimeMeshTangentsNormalPrecision> TangentBuilder( |
| 29 | + StreamSet.AddStream(FRealtimeMeshStreams::Tangents, GetRealtimeMeshBufferLayout<FRealtimeMeshTangentsNormalPrecision>())); |
| 30 | + |
| 31 | + // Setup a stream for texcoords of type FVector2DHalf, and wrap it a builder that lets us work with it as though it was FVector2f's |
| 32 | + TRealtimeMeshStreamBuilder<FVector2f, FVector2DHalf> TexCoordsBuilder(StreamSet.AddStream(FRealtimeMeshStreams::TexCoords, GetRealtimeMeshBufferLayout<FVector2DHalf>())); |
| 33 | + |
| 34 | + // Setup a stream for colors of type FColor, and wrap it in a direct builder for the FColor type |
| 35 | + TRealtimeMeshStreamBuilder<FColor> ColorBuilder(StreamSet.AddStream(FRealtimeMeshStreams::Color, GetRealtimeMeshBufferLayout<FColor>())); |
| 36 | + |
| 37 | + // Setup a stream for the triangles of type TIndex3<uint16> and wrap it in a builder that lets us work with it as though it was TIndex3<uint32> |
| 38 | + TRealtimeMeshStreamBuilder<TIndex3<uint32>, TIndex3<uint16>> TrianglesBuilder(StreamSet.AddStream(FRealtimeMeshStreams::Triangles, GetRealtimeMeshBufferLayout<TIndex3<uint16>>())); |
| 39 | + |
| 40 | + // Setup a stream for the polygroups of type uint16 and wrap it in a builder that lets us work with it as though it was uint32 |
| 41 | + TRealtimeMeshStreamBuilder<uint32, uint16> PolygroupsBuilder(StreamSet.AddStream(FRealtimeMeshStreams::PolyGroups, GetRealtimeMeshBufferLayout<uint16>())); |
| 42 | + |
| 43 | + // This is kinda pointless for this example, but shows how you can reserve space in the buffers just like a TArray |
| 44 | + PositionBuilder.Reserve(3); |
| 45 | + TangentBuilder.Reserve(3); |
| 46 | + ColorBuilder.Reserve(3); |
| 47 | + TexCoordsBuilder.Reserve(3); |
| 48 | + |
| 49 | + TrianglesBuilder.Reserve(2); |
| 50 | + PolygroupsBuilder.Reserve(2); |
| 51 | + |
| 52 | + // Add first vertex |
| 53 | + int32 V0 = PositionBuilder.Add(FVector3f(-50.0f, 0.0f, 0.0f)); |
| 54 | + TangentBuilder.Add(FRealtimeMeshTangentsHighPrecision(FVector3f(0.0f, -1.0f, 0.0f), FVector3f(1.0f, 0.0f, 0.0f))); |
| 55 | + ColorBuilder.Add(FColor::Red); |
| 56 | + TexCoordsBuilder.Add(FVector2f(0.0f, 0.0f)); |
| 57 | + |
| 58 | + // Add second vertex |
| 59 | + int32 V1 = PositionBuilder.Add(FVector3f(0.0f, 0.0f, 100.0f)); |
| 60 | + TangentBuilder.Add(FRealtimeMeshTangentsHighPrecision(FVector3f(0.0f, -1.0f, 0.0f), FVector3f(1.0f, 0.0f, 0.0f))); |
| 61 | + ColorBuilder.Add(FColor::Green); |
| 62 | + TexCoordsBuilder.Add(FVector2f(0.5f, 1.0f)); |
| 63 | + |
| 64 | + // Add third vertex |
| 65 | + int32 V2 = PositionBuilder.Add(FVector3f(50.0, 0.0, 0.0)); |
| 66 | + TangentBuilder.Add(FRealtimeMeshTangentsHighPrecision(FVector3f(0.0f, -1.0f, 0.0f), FVector3f(1.0f, 0.0f, 0.0f))); |
| 67 | + ColorBuilder.Add(FColor::Blue); |
| 68 | + TexCoordsBuilder.Add(FVector2f(1.0f, 0.0f)); |
| 69 | + |
| 70 | + // Add first triangle and associated polygroup |
| 71 | + TrianglesBuilder.Add(TIndex3<uint32>(V0, V1, V2)); |
| 72 | + PolygroupsBuilder.Add(0); |
| 73 | + |
| 74 | + // Add second triangle and associated polygroup |
| 75 | + TrianglesBuilder.Add(TIndex3<uint32>(V2, V1, V0)); |
| 76 | + PolygroupsBuilder.Add(1); |
| 77 | + |
| 78 | + // Setup the two material slots |
| 79 | + RealtimeMesh->SetupMaterialSlot(0, "PrimaryMaterial"); |
| 80 | + RealtimeMesh->SetupMaterialSlot(1, "SecondaryMaterial"); |
| 81 | + |
| 82 | + // Now create the group key. This is a unique identifier for the section group |
| 83 | + // A section group contains one or more sections that all share the underlying buffers |
| 84 | + // these sections can overlap the used vertex/index ranges depending on use case. |
| 85 | + const FRealtimeMeshSectionGroupKey GroupKey = FRealtimeMeshSectionGroupKey::Create(0, FName("TestTriangle")); |
| 86 | + |
| 87 | + // Now create the section key, this is a unique identifier for a section within a group |
| 88 | + // The section contains the configuration for the section, like the material slot, |
| 89 | + // and the draw type, as well as the range of the index/vertex buffers to use to render. |
| 90 | + // Here we're using the version to create the key based on the PolyGroup index |
| 91 | + const FRealtimeMeshSectionKey PolyGroup0SectionKey = FRealtimeMeshSectionKey::CreateForPolyGroup(GroupKey, 0); |
| 92 | + const FRealtimeMeshSectionKey PolyGroup1SectionKey = FRealtimeMeshSectionKey::CreateForPolyGroup(GroupKey, 1); |
| 93 | + |
| 94 | + // Now we create the section group, since the stream set has polygroups, this will create the sections as well |
| 95 | + RealtimeMesh->CreateSectionGroup(GroupKey, StreamSet); |
| 96 | + |
| 97 | + // Update the configuration of both the polygroup sections. |
| 98 | + RealtimeMesh->UpdateSectionConfig(PolyGroup0SectionKey, FRealtimeMeshSectionConfig(ERealtimeMeshSectionDrawType::Static, 0)); |
| 99 | + RealtimeMesh->UpdateSectionConfig(PolyGroup1SectionKey, FRealtimeMeshSectionConfig(ERealtimeMeshSectionDrawType::Static, 1)); |
| 100 | + |
| 101 | + Super::OnGenerateMesh_Implementation(); |
| 102 | +} |
| 103 | + |
0 commit comments