void FPaperSpriteVertex::SetTangentsFromPaperAxes() { PackedNormalX = PaperAxisX; PackedNormalZ = PaperAxisZ; // store determinant of basis in w component of normal vector PackedNormalZ.Vector.W = (GetBasisDeterminantSign(PaperAxisX, PaperAxisY, PaperAxisZ) < 0.0f) ? 0 : 255; }
void URuntimeMeshLibrary::CalculateTangentsForMeshPacked(TArray<FRuntimeMeshBlueprintVertexSimple>& Vertices, const TArray<int32>& Triangles, bool bCreateSmoothNormals) { CalculateTangentsForMesh( [&Triangles](int32 Index) -> int32 { return Triangles[Index]; }, [&Vertices](int32 Index) -> FVector { return Vertices[Index].Position; }, [&Vertices](int32 Index) -> FVector2D { return Vertices[Index].UV0; }, [&Vertices](int32 Index, FVector TangentX, FVector TangentY, FVector TangentZ) { Vertices[Index].Normal = TangentZ; Vertices[Index].Tangent.TangentX = TangentX; Vertices[Index].Tangent.bFlipTangentY = GetBasisDeterminantSign(TangentX, TangentY, TangentZ) < 0; }, Vertices.Num(), Vertices.Num(), Triangles.Num(), bCreateSmoothNormals); }
void URuntimeMeshLibrary::CalculateTangentsForMesh(const TArray<FVector>& Vertices, const TArray<int32>& Triangles, TArray<FVector>& Normals, const TArray<FVector2D>& UVs, TArray<FRuntimeMeshTangent>& Tangents, bool bCreateSmoothNormals) { Normals.SetNum(Vertices.Num()); Tangents.SetNum(Vertices.Num()); CalculateTangentsForMesh( [&Triangles](int32 Index) -> int32 { return Triangles[Index]; }, [&Vertices](int32 Index) -> FVector { return Vertices[Index]; }, [&UVs](int32 Index) -> FVector2D { return UVs[Index]; }, [&Normals, &Tangents](int32 Index, FVector TangentX, FVector TangentY, FVector TangentZ) { Normals[Index] = TangentZ; Tangents[Index].TangentX = TangentX; Tangents[Index].bFlipTangentY = GetBasisDeterminantSign(TangentX, TangentY, TangentZ) < 0; }, Vertices.Num(), UVs.Num(), Triangles.Num(), bCreateSmoothNormals); }
void URuntimeMeshLibrary::GetStaticMeshSection(UStaticMesh* InMesh, int32 LODIndex, int32 SectionIndex, TArray<FVector>& Vertices, TArray<int32>& Triangles, TArray<FVector>& Normals, TArray<FVector2D>& UVs, TArray<FColor>& Colors, TArray<FRuntimeMeshTangent>& Tangents) { Vertices.Empty(); Triangles.Empty(); Normals.Empty(); UVs.Empty(); Colors.Empty(); Tangents.Empty(); GetStaticMeshSection(InMesh, LODIndex, SectionIndex, 1, [&Vertices, &Normals, &Tangents](FVector Position, FVector TangentX, FVector TangentY, FVector TangentZ) -> int32 { int32 NewIndex = Vertices.Add(Position); Normals.Add(TangentZ); Tangents.Add(FRuntimeMeshTangent(TangentX, GetBasisDeterminantSign(TangentX, TangentY, TangentZ) < 0)); return NewIndex; }, [&UVs](int32 Index, int32 UVIndex, FVector2D UV) { check(UVIndex == 0); UVs.SetNum(Index + 1); UVs[Index] = UV; }, [&Colors](int32 Index, FColor Color) { Colors.SetNum(Index + 1); Colors[Index] = Color; }, [&Triangles](int32 Index) { Triangles.Add(Index); }, [](int32 Index) { }); }
void URuntimeMeshLibrary::GetStaticMeshSectionPacked(UStaticMesh* InMesh, int32 LODIndex, int32 SectionIndex, TArray<FRuntimeMeshBlueprintVertexSimple>& Vertices, TArray<int32>& Triangles) { Vertices.Empty(); Triangles.Empty(); GetStaticMeshSection(InMesh, LODIndex, SectionIndex, 1, [&Vertices](FVector Position, FVector TangentX, FVector TangentY, FVector TangentZ) -> int32 { return Vertices.Add(FRuntimeMeshBlueprintVertexSimple(Position, TangentZ, FRuntimeMeshTangent(TangentX, GetBasisDeterminantSign(TangentX, TangentY, TangentZ) < 0), FVector2D::ZeroVector)); }, [&Vertices](int32 Index, int32 UVIndex, FVector2D UV) { check(UVIndex == 0); Vertices[Index].UV0 = UV; }, [&Vertices](int32 Index, FColor Color) { Vertices[Index].Color = Color; }, [&Triangles](int32 Index) { Triangles.Add(Index); }, [](int32 Index) { }); }