|
1 | 1 | // Copyright TriAxis Games, L.L.C. All Rights Reserved.
|
2 | 2 |
|
3 | 3 | #include "RealtimeMeshLibrary.h"
|
| 4 | +#include "RealtimeMeshSimple.h" |
4 | 5 |
|
5 | 6 | FRealtimeMeshLODKey URealtimeMeshBlueprintFunctionLibrary::Conv_IntToRealtimeMeshLODKey(int32 LODIndex)
|
6 | 7 | {
|
7 | 8 | return FRealtimeMeshLODKey(LODIndex);
|
8 | 9 | }
|
| 10 | + |
| 11 | +FRealtimeMeshLODKey URealtimeMeshBlueprintFunctionLibrary::MakeLODKey(int32 LODIndex) |
| 12 | +{ |
| 13 | + return FRealtimeMeshLODKey(LODIndex); |
| 14 | +} |
| 15 | + |
| 16 | +FRealtimeMeshSectionGroupKey URealtimeMeshBlueprintFunctionLibrary::MakeSectionGroupKey(FRealtimeMeshLODKey LODKey, int32 SectionGroupIndex) |
| 17 | +{ |
| 18 | + return FRealtimeMeshSectionGroupKey(LODKey, SectionGroupIndex); |
| 19 | +} |
| 20 | + |
| 21 | +FRealtimeMeshSectionKey URealtimeMeshBlueprintFunctionLibrary::MakeSectionKey(FRealtimeMeshSectionGroupKey SectionGroupKey, int32 SectionIndex) |
| 22 | +{ |
| 23 | + return FRealtimeMeshSectionKey(SectionGroupKey, SectionIndex); |
| 24 | +} |
| 25 | + |
| 26 | +void URealtimeMeshBlueprintFunctionLibrary::BreakLODKey(const FRealtimeMeshLODKey& LODKey, int32& LODIndex) |
| 27 | +{ |
| 28 | + LODIndex = RealtimeMesh::FRealtimeMeshKeyHelpers::GetLODIndex(LODKey); |
| 29 | +} |
| 30 | + |
| 31 | +FRealtimeMeshStreamRange URealtimeMeshBlueprintFunctionLibrary::MakeStreamRange(int32 VerticesLowerInclusive, |
| 32 | + int32 VerticesUpperExclusive, int32 IndicesLowerInclusive, int32 IndicesUpperExclusive) |
| 33 | +{ |
| 34 | + return FRealtimeMeshStreamRange(VerticesLowerInclusive, VerticesUpperExclusive, IndicesLowerInclusive, IndicesUpperExclusive); |
| 35 | +} |
| 36 | + |
| 37 | +static void ConvertQuadToTriangles(TArray<int32>& Triangles, int32 Vert0, int32 Vert1, int32 Vert2, int32 Vert3) |
| 38 | +{ |
| 39 | + Triangles.Add(Vert0); |
| 40 | + Triangles.Add(Vert1); |
| 41 | + Triangles.Add(Vert3); |
| 42 | + |
| 43 | + Triangles.Add(Vert1); |
| 44 | + Triangles.Add(Vert2); |
| 45 | + Triangles.Add(Vert3); |
| 46 | +} |
| 47 | + |
| 48 | +FRealtimeMeshSimpleMeshData& URealtimeMeshBlueprintFunctionLibrary::AppendBoxMesh(FVector BoxRadius, FTransform BoxTransform, FRealtimeMeshSimpleMeshData& MeshData) |
| 49 | +{ |
| 50 | + // Generate verts |
| 51 | + FVector BoxVerts[8]; |
| 52 | + BoxVerts[0] = BoxTransform.TransformPosition(FVector(-BoxRadius.X, BoxRadius.Y, BoxRadius.Z)); |
| 53 | + BoxVerts[1] = BoxTransform.TransformPosition(FVector(BoxRadius.X, BoxRadius.Y, BoxRadius.Z)); |
| 54 | + BoxVerts[2] = BoxTransform.TransformPosition(FVector(BoxRadius.X, -BoxRadius.Y, BoxRadius.Z)); |
| 55 | + BoxVerts[3] = BoxTransform.TransformPosition(FVector(-BoxRadius.X, -BoxRadius.Y, BoxRadius.Z)); |
| 56 | + |
| 57 | + BoxVerts[4] = BoxTransform.TransformPosition(FVector(-BoxRadius.X, BoxRadius.Y, -BoxRadius.Z)); |
| 58 | + BoxVerts[5] = BoxTransform.TransformPosition(FVector(BoxRadius.X, BoxRadius.Y, -BoxRadius.Z)); |
| 59 | + BoxVerts[6] = BoxTransform.TransformPosition(FVector(BoxRadius.X, -BoxRadius.Y, -BoxRadius.Z)); |
| 60 | + BoxVerts[7] = BoxTransform.TransformPosition(FVector(-BoxRadius.X, -BoxRadius.Y, -BoxRadius.Z)); |
| 61 | + |
| 62 | + // Generate triangles (from quads) |
| 63 | + const int32 StartVertex = MeshData.Positions.Num(); |
| 64 | + const int32 NumVerts = 24; // 6 faces x 4 verts per face |
| 65 | + const int32 NumIndices = 36; |
| 66 | + |
| 67 | + // Make sure the secondary arrays are the same length, zeroing them if necessary |
| 68 | + MeshData.Normals.SetNumZeroed(StartVertex); |
| 69 | + MeshData.Tangents.SetNumZeroed(StartVertex); |
| 70 | + MeshData.UV0.SetNumZeroed(StartVertex); |
| 71 | + |
| 72 | + MeshData.Positions.Reserve(StartVertex + NumVerts); |
| 73 | + MeshData.Normals.Reserve(StartVertex + NumVerts); |
| 74 | + MeshData.Tangents.Reserve(StartVertex + NumVerts); |
| 75 | + MeshData.UV0.Reserve(StartVertex + NumVerts); |
| 76 | + MeshData.Triangles.Reserve(MeshData.Triangles.Num() + NumIndices); |
| 77 | + |
| 78 | + const auto WriteToNextFour = [](TArray<FVector>& Array, const FVector& Value) |
| 79 | + { |
| 80 | + Array.Add(Value); |
| 81 | + Array.Add(Value); |
| 82 | + Array.Add(Value); |
| 83 | + Array.Add(Value); |
| 84 | + }; |
| 85 | + |
| 86 | + const auto WriteQuadPositions = [&MeshData](const FVector& VertA, const FVector& VertB, const FVector& VertC, const FVector& VertD) |
| 87 | + { |
| 88 | + MeshData.Positions.Add(VertA); |
| 89 | + MeshData.Positions.Add(VertB); |
| 90 | + MeshData.Positions.Add(VertC); |
| 91 | + MeshData.Positions.Add(VertD); |
| 92 | + }; |
| 93 | + |
| 94 | + WriteQuadPositions(BoxVerts[0], BoxVerts[1], BoxVerts[2], BoxVerts[3]); |
| 95 | + WriteToNextFour(MeshData.Normals, BoxTransform.TransformVectorNoScale(FVector(0.0f, 0.0f, 1.0f))); |
| 96 | + WriteToNextFour(MeshData.Tangents, BoxTransform.TransformVectorNoScale(FVector(0.0f, -1.0f, 0.0f))); |
| 97 | + ConvertQuadToTriangles(MeshData.Triangles, StartVertex + 0, StartVertex + 1, StartVertex + 2, StartVertex + 3); |
| 98 | + |
| 99 | + WriteQuadPositions(BoxVerts[4], BoxVerts[0], BoxVerts[3], BoxVerts[7]); |
| 100 | + WriteToNextFour(MeshData.Normals, BoxTransform.TransformVectorNoScale(FVector(-1.0, 0.0, 0.0))); |
| 101 | + WriteToNextFour(MeshData.Tangents, BoxTransform.TransformVectorNoScale(FVector(0.0f, -1.0f, 0.0f))); |
| 102 | + ConvertQuadToTriangles(MeshData.Triangles, StartVertex + 4, StartVertex + 5, StartVertex + 6, StartVertex + 7); |
| 103 | + |
| 104 | + WriteQuadPositions(BoxVerts[5], BoxVerts[1], BoxVerts[0], BoxVerts[4]); |
| 105 | + WriteToNextFour(MeshData.Normals, BoxTransform.TransformVectorNoScale(FVector(0.0, 1.0, 0.0))); |
| 106 | + WriteToNextFour(MeshData.Tangents, BoxTransform.TransformVectorNoScale(FVector(-1.0f, 0.0f, 0.0f))); |
| 107 | + ConvertQuadToTriangles(MeshData.Triangles, StartVertex + 8, StartVertex + 9, StartVertex + 10, StartVertex + 11); |
| 108 | + |
| 109 | + WriteQuadPositions(BoxVerts[6], BoxVerts[2], BoxVerts[1], BoxVerts[5]); |
| 110 | + WriteToNextFour(MeshData.Normals, BoxTransform.TransformVectorNoScale(FVector(1.0, 0.0, 0.0))); |
| 111 | + WriteToNextFour(MeshData.Tangents, BoxTransform.TransformVectorNoScale(FVector(0.0f, 1.0f, 0.0f))); |
| 112 | + ConvertQuadToTriangles(MeshData.Triangles, StartVertex + 12, StartVertex + 13, StartVertex + 14, StartVertex + 15); |
| 113 | + |
| 114 | + WriteQuadPositions(BoxVerts[7], BoxVerts[3], BoxVerts[2], BoxVerts[6]); |
| 115 | + WriteToNextFour(MeshData.Normals, BoxTransform.TransformVectorNoScale(FVector(0.0, -1.0, 0.0))); |
| 116 | + WriteToNextFour(MeshData.Tangents, BoxTransform.TransformVectorNoScale(FVector(1.0f, 0.0f, 0.0f))); |
| 117 | + ConvertQuadToTriangles(MeshData.Triangles, StartVertex + 16, StartVertex + 17, StartVertex + 18, StartVertex + 19); |
| 118 | + |
| 119 | + WriteQuadPositions(BoxVerts[7], BoxVerts[6], BoxVerts[5], BoxVerts[4]); |
| 120 | + WriteToNextFour(MeshData.Normals, BoxTransform.TransformVectorNoScale(FVector(0.0, 0.0, -1.0))); |
| 121 | + WriteToNextFour(MeshData.Tangents, BoxTransform.TransformVectorNoScale(FVector(0.0f, 1.0f, 0.0f))); |
| 122 | + ConvertQuadToTriangles(MeshData.Triangles, StartVertex + 20, StartVertex + 21, StartVertex + 22, StartVertex + 23); |
| 123 | + |
| 124 | + // UVs |
| 125 | + for (int32 Index = 0; Index < 6; Index++) |
| 126 | + { |
| 127 | + MeshData.UV0.Add(FVector2D(0.0f, 0.0f)); |
| 128 | + MeshData.UV0.Add(FVector2D(0.0f, 1.0f)); |
| 129 | + MeshData.UV0.Add(FVector2D(1.0f, 1.0f)); |
| 130 | + MeshData.UV0.Add(FVector2D(1.0f, 0.0f)); |
| 131 | + } |
| 132 | + |
| 133 | + return MeshData; |
| 134 | +} |
| 135 | + |
| 136 | +template<typename Type> |
| 137 | +static void AppendVertexArrayIfContains(TArray<Type>& Destination, const TArray<Type>& Source, int32 VertexOffset, int32 FinalLength) |
| 138 | +{ |
| 139 | + if (Source.Num() > 0) |
| 140 | + { |
| 141 | + Destination.SetNumZeroed(VertexOffset); |
| 142 | + Destination.Append(Source.GetData(), FMath::Min(FinalLength - VertexOffset, Source.Num())); |
| 143 | + } |
| 144 | +} |
| 145 | + |
| 146 | +static void AppendTransformedTangentArray(TArray<FVector>& Destination, const TArray<FVector>& Source, int32 VertexOffset, int32 FinalLength, const FTransform& Transform) |
| 147 | +{ |
| 148 | + if (Source.Num() > 0) |
| 149 | + { |
| 150 | + const int32 NumToCopy = FMath::Min(FinalLength - VertexOffset, Source.Num()); |
| 151 | + Destination.SetNumZeroed(FinalLength); |
| 152 | + for (int32 Index = 0; Index < NumToCopy; Index++) |
| 153 | + { |
| 154 | + Destination[VertexOffset + Index] = Transform.TransformVector(Source[Index]); |
| 155 | + } |
| 156 | + } |
| 157 | +} |
| 158 | + |
| 159 | + |
| 160 | +FRealtimeMeshSimpleMeshData& URealtimeMeshBlueprintFunctionLibrary::AppendMesh(FRealtimeMeshSimpleMeshData& TargetMeshData, const FRealtimeMeshSimpleMeshData& MeshDataToAdd, const FTransform& Transform) |
| 161 | +{ |
| 162 | + const int32 StartVertex = TargetMeshData.Positions.Num(); |
| 163 | + |
| 164 | + // Skip slower transform logic if transform == identity |
| 165 | + if (Transform.Equals(FTransform::Identity)) |
| 166 | + { |
| 167 | + TargetMeshData.Positions.Append(MeshDataToAdd.Positions); |
| 168 | + AppendVertexArrayIfContains(TargetMeshData.Normals, MeshDataToAdd.Normals, StartVertex, TargetMeshData.Positions.Num()); |
| 169 | + AppendVertexArrayIfContains(TargetMeshData.Binormals, MeshDataToAdd.Binormals, StartVertex, TargetMeshData.Positions.Num()); |
| 170 | + AppendVertexArrayIfContains(TargetMeshData.Tangents, MeshDataToAdd.Tangents, StartVertex, TargetMeshData.Positions.Num()); |
| 171 | + } |
| 172 | + else |
| 173 | + { |
| 174 | + TargetMeshData.Positions.Reserve(TargetMeshData.Positions.Num() + MeshDataToAdd.Positions.Num()); |
| 175 | + for (int32 Index = 0; Index < MeshDataToAdd.Positions.Num(); Index++) |
| 176 | + { |
| 177 | + TargetMeshData.Positions.Add(Transform.TransformPosition(MeshDataToAdd.Positions[Index])); |
| 178 | + } |
| 179 | + AppendTransformedTangentArray(TargetMeshData.Normals, MeshDataToAdd.Normals, StartVertex, TargetMeshData.Positions.Num(), Transform); |
| 180 | + AppendTransformedTangentArray(TargetMeshData.Binormals, MeshDataToAdd.Binormals, StartVertex, TargetMeshData.Positions.Num(), Transform); |
| 181 | + AppendTransformedTangentArray(TargetMeshData.Tangents, MeshDataToAdd.Tangents, StartVertex, TargetMeshData.Positions.Num(), Transform); |
| 182 | + } |
| 183 | + |
| 184 | + AppendVertexArrayIfContains(TargetMeshData.Colors, MeshDataToAdd.Colors, StartVertex, TargetMeshData.Positions.Num()); |
| 185 | + AppendVertexArrayIfContains(TargetMeshData.LinearColors, MeshDataToAdd.LinearColors, StartVertex, TargetMeshData.Positions.Num()); |
| 186 | + |
| 187 | + AppendVertexArrayIfContains(TargetMeshData.UV0, MeshDataToAdd.UV0, StartVertex, TargetMeshData.Positions.Num()); |
| 188 | + AppendVertexArrayIfContains(TargetMeshData.UV1, MeshDataToAdd.UV1, StartVertex, TargetMeshData.Positions.Num()); |
| 189 | + AppendVertexArrayIfContains(TargetMeshData.UV2, MeshDataToAdd.UV2, StartVertex, TargetMeshData.Positions.Num()); |
| 190 | + AppendVertexArrayIfContains(TargetMeshData.UV3, MeshDataToAdd.UV3, StartVertex, TargetMeshData.Positions.Num()); |
| 191 | + |
| 192 | + return TargetMeshData; |
| 193 | +} |
0 commit comments