// Copyright Epic Games, Inc. All Rights Reserved. #include "Dataflow/ChaosFleshTriangleMeshSimulationPropertiesNode.h" #include "Async/ParallelFor.h" #include "Chaos/Deformable/Utilities.h" #include "ChaosFlesh/ChaosFlesh.h" #include "Chaos/Tetrahedron.h" #include "Chaos/Utilities.h" #include "Chaos/UniformGrid.h" #include "ChaosFlesh/FleshCollection.h" #include "ChaosFlesh/FleshCollectionUtility.h" #include "ChaosLog.h" #include "Dataflow/DataflowInputOutput.h" #include "DynamicMesh/DynamicMesh3.h" #include "DynamicMesh/DynamicMeshAABBTree3.h" #include "Engine/SkeletalMesh.h" #include "Engine/StaticMesh.h" #include "FTetWildWrapper.h" #include "Generate/IsosurfaceStuffing.h" #include "GeometryCollection/ManagedArrayCollection.h" #include "GeometryCollection/Facades/CollectionTetrahedralMetricsFacade.h" #include "GeometryCollection/GeometryCollectionAlgo.h" #include "MeshDescription.h" #include "MeshDescriptionToDynamicMesh.h" #include "Rendering/SkeletalMeshLODImporterData.h" #include "Rendering/SkeletalMeshModel.h" #include "SkeletalMeshLODModelToDynamicMesh.h" // MeshModelingBlueprints #include "Spatial/FastWinding.h" #include "Spatial/MeshAABBTree3.h" template using MType = FManagedArrayCollection::TManagedType; void FTriangleMeshSimulationPropertiesDataflowNodes::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const { TUniquePtr InCollection(GetValue(Context, &Collection).NewCopy()); if (Out->IsA(&Collection)) { TManagedArray* GroupNames = InCollection->FindAttribute("BoneName", FGeometryCollection::TransformGroup); TManagedArray* TransformIndex = InCollection->FindAttribute("TransformIndex", FGeometryCollection::GeometryGroup); TManagedArray& ParticleStiffness = InCollection->AddAttribute("Stiffness", FGeometryCollection::VerticesGroup); TManagedArray& ParticleDamping = InCollection->AddAttribute("Damping", FGeometryCollection::VerticesGroup); if (GroupNames && TransformIndex) { TSet TriangleMeshNameSet = TSet(MeshNames); TArray TriangleMeshIndices; for (int32 i = 0; i < TransformIndex->Num(); i++) { if (TriangleMeshNameSet.Contains((*GroupNames)[(*TransformIndex)[i]])) { TriangleMeshIndices.Add(i); } } if (TriangleMeshIndices.Num()) { const FName TriangleMeshGroup = "TriangleMesh"; int32 TriMeshIndex = InCollection->AddElements(TriangleMeshIndices.Num(), TriangleMeshGroup); if (TriMeshIndex == 0) { TManagedArray& TriangleMeshIndex = InCollection->AddAttribute("ObjectIndices", TriangleMeshGroup); } if (InCollection->HasAttributes({MType("ObjectIndices", TriangleMeshGroup) })) { TManagedArray* TriangleMeshIndexPtr = InCollection->FindAttribute("ObjectIndices", TriangleMeshGroup); for (int32 i = 0; i < TriangleMeshIndices.Num(); i++) { (*TriangleMeshIndexPtr)[i + TriMeshIndex] = TriangleMeshIndices[i]; } } } } if (const TManagedArray* TriangleMeshIndices = InCollection->FindAttribute("ObjectIndices", "TriangleMesh")) { if (const TManagedArray* Indices = InCollection->FindAttribute("Indices", FGeometryCollection::FacesGroup)) { if (const TManagedArray* FaceStarts = InCollection->FindAttribute("FaceStart", FGeometryCollection::GeometryGroup)) { if (const TManagedArray* FaceCounts = InCollection->FindAttribute("FaceCount", FGeometryCollection::GeometryGroup)) { if (const TManagedArray* Vertex = InCollection->FindAttribute("Vertex", "Vertices")) { if (TManagedArray* Mass = InCollection->FindAttribute("Mass", "Vertices")) { for (int32 i = 0; i < TriangleMeshIndices->Num(); i++) { const int32 ObjectIndex = (*TriangleMeshIndices)[i]; const int32 FaceStartIndex = (*FaceStarts)[ObjectIndex]; const int32 FaceNum = (*FaceCounts)[ObjectIndex]; for (int32 e = FaceStartIndex; e < FaceStartIndex + FaceNum; e++) { const FVector3f X0 = (*Vertex)[(*Indices)[e][0]]; const FVector3f X1 = (*Vertex)[(*Indices)[e][1]]; const FVector3f X2 = (*Vertex)[(*Indices)[e][2]]; float SingleElementMass = FVector3f::CrossProduct(X1 - X0, X2 - X0).Size() * TriangleMeshDensity/ 2.f; if (SingleElementMass < 0.f) { SingleElementMass = -SingleElementMass; } for (int32 k = 0; k < 3; k++) { const int32 MassIndex = (*Indices)[e][k]; (*Mass)[MassIndex] += SingleElementMass/3.f; } } } } } } } } if (const TManagedArray* VertexStarts = InCollection->FindAttribute("VertexStart", FGeometryCollection::GeometryGroup)) { if (const TManagedArray* VertexCounts = InCollection->FindAttribute("VertexCount", FGeometryCollection::GeometryGroup)) { for (int32 i = 0; i < TriangleMeshIndices->Num(); i++) { const int32 ObjectIndex = (*TriangleMeshIndices)[i]; const int32 VertexStartIndex = (*VertexStarts)[ObjectIndex]; const int32 VertexNum = (*VertexCounts)[ObjectIndex]; for (int32 ParticleIndex = VertexStartIndex; ParticleIndex < VertexStartIndex + VertexNum; ParticleIndex++) { ParticleStiffness[ParticleIndex] = VertexTriangleMeshStiffness; ParticleDamping[ParticleIndex] = VertexTriangleMeshDamping; } } } } } SetValue(Context, *InCollection, &Collection); } }