From 827508fcead836c4d00be637bab6d1152114a92a Mon Sep 17 00:00:00 2001 From: bernatx Date: Thu, 19 Oct 2023 10:37:06 +0200 Subject: [PATCH] CarlaExporter tool now exports the box collider and convex collider of the object if it has one, otherwise the mesh (fixed problem with big meshes) --- .gitignore | 1 + CHANGELOG.md | 2 + .../CarlaExporter/Private/CarlaExporter.cpp | 283 ++++++++++++------ .../CarlaExporter/Public/CarlaExporter.h | 10 + 4 files changed, 210 insertions(+), 86 deletions(-) diff --git a/.gitignore b/.gitignore index d922129e0..02e40f0eb 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ Util/Build Install Plugins !Unreal/CarlaUE4/Plugins +Unreal/CarlaUE4/Plugins/HoudiniEngine /ExportedMaps /Import/* diff --git a/CHANGELOG.md b/CHANGELOG.md index d82abeca2..76037cde4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,11 +3,13 @@ * Added build support for VS2022 and Ninja for LibCarla and osm2odr on Windows * Fixed bug causing the TM's unstuck logic to incorrectly remove the vehicles in some situations. * Fixed the extra data in Directx textures, so we need to copy row by row on Windows to remove extra bytes on images + * Fixed vertices of big meshes (more than 65k vertices) in CarlaExporter * Fixed sensors to check for the stream to be ready (race condition) * Added empty actor * The spectator will be used to load tiles and actor in Large Maps when no other actors with the rolename 'ego_vehicle' or 'hero' are present. Added the `spectator_as_ego` to the `carla.WorldSettings()` to allow users to disable this behavior. * Fixed the import script, where could use any other TilesInfo.txt if the destination folder has many * Restored gamma value to 2.2 instead of 2.4 + * CarlaExporter tool now exports the box collider and convex collider of the object if it has one, otherwise the mesh * Pedestrians with AI or in replayer are now faster around 10x. They have collisions disabled until they hit a vehicle. * Added API function to avoid replaying the spectator * `Client.set_replayer_ignore_spectator(bool)` diff --git a/Unreal/CarlaUE4/Plugins/CarlaExporter/Source/CarlaExporter/Private/CarlaExporter.cpp b/Unreal/CarlaUE4/Plugins/CarlaExporter/Source/CarlaExporter/Private/CarlaExporter.cpp index 1e47dc7f6..364c320d5 100644 --- a/Unreal/CarlaUE4/Plugins/CarlaExporter/Source/CarlaExporter/Private/CarlaExporter.cpp +++ b/Unreal/CarlaUE4/Plugins/CarlaExporter/Source/CarlaExporter/Private/CarlaExporter.cpp @@ -19,7 +19,10 @@ #include "PxVec3.h" #include "LevelEditor.h" #include "EngineUtils.h" - +#include "PhysXPublic.h" +#include "PhysicsPublic.h" +#include "PhysXIncludes.h" +#include "PxSimpleTypes.h" #include #include @@ -27,15 +30,6 @@ static const FName CarlaExporterTabName("CarlaExporter"); #define LOCTEXT_NAMESPACE "FCarlaExporterModule" -enum AreaType -{ - ROAD, - GRASS, - SIDEWALK, - CROSSWALK, - BLOCK -}; - void FCarlaExporterModule::StartupModule() { // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module @@ -148,7 +142,7 @@ void FCarlaExporterModule::PluginButtonClicked() continue; } - f << "o " << TCHAR_TO_ANSI(*(ActorName)) << "\n"; + f << "g " << TCHAR_TO_ANSI(*(ActorName)) << "\n"; TArray Components = TempActor->GetComponentsByClass(UStaticMeshComponent::StaticClass()); for (auto *Component : Components) @@ -163,49 +157,15 @@ void FCarlaExporterModule::PluginButtonClicked() for (int i=0; iGetInstanceCount(); ++i) { - f << "g instance_" << i << "\n"; + // f << " instance_" << i << "\n"; + FString ObjectName = ActorName +"_"+FString::FromInt(i); // get the component position and transform FTransform InstanceTransform; comp2->GetInstanceTransform(i, InstanceTransform, true); FVector InstanceLocation = InstanceTransform.GetTranslation(); - - // through all convex elements - for (const auto &mesh : body->TriMeshes) - { - // get data - PxU32 nbVerts = mesh->getNbVertices(); - const PxVec3* convexVerts = mesh->getVertices(); - const PxU16* indexBuffer = (PxU16 *) mesh->getTriangles(); - - // write all vertex - for(PxU32 j=0;jgetNbTriangles()*3;k+=3) - { - // inverse order for left hand - f << "f " << offset + indexBuffer[k+2] << " " << offset + indexBuffer[k+1] << " " << offset + indexBuffer[k] << "\n"; - } - offset += nbVerts; - } + offset += WriteObjectGeom(f, ObjectName, body, InstanceTransform, areaType, offset); } } else @@ -218,49 +178,14 @@ void FCarlaExporterModule::PluginButtonClicked() if (!body) continue; - f << "g " << TCHAR_TO_ANSI(*(comp->GetName())) << "\n"; + // f << "o " << TCHAR_TO_ANSI(*(comp->GetName())) << "\n"; + FString ObjectName = ActorName +"_"+comp->GetName(); // get the component position and transform FTransform CompTransform = comp->GetComponentTransform(); FVector CompLocation = CompTransform.GetTranslation(); - // through all convex elements - for (const auto &mesh : body->TriMeshes) - { - // get data - PxU32 nbVerts = mesh->getNbVertices(); - const PxVec3* convexVerts = mesh->getVertices(); - const PxU16* indexBuffer = (PxU16 *) mesh->getTriangles(); - - // write all vertex - for(PxU32 j=0;jgetNbTriangles(); ++i) - { - // inverse order for left hand - f << "f " << offset + indexBuffer[k+2] << " " << offset + indexBuffer[k+1] << " " << offset + indexBuffer[k] << "\n"; - k += 3; - } - offset += nbVerts; - } + offset += WriteObjectGeom(f, ObjectName, body, CompTransform, areaType, offset); } } } @@ -268,6 +193,192 @@ void FCarlaExporterModule::PluginButtonClicked() f.close(); } +int32 FCarlaExporterModule::WriteObjectGeom(std::ofstream &f, FString ObjectName, UBodySetup *body, FTransform &CompTransform, AreaType Area, int32 Offset) +{ + if (!body) return 0; + + constexpr float TO_METERS = 0.01f; + FVector CompLocation = CompTransform.GetTranslation(); + int TotalVerticesAdded = 0; + bool Written = false; + + // try to write the box collision if any + for (const auto &box: body->AggGeom.BoxElems) + { + // get data + const int32 nbVerts = 8; + TArray boxVerts; + TArray indexBuffer; + + FVector HalfExtent(box.X / 2.0f, box.Y / 2.0f, box.Z / 2.0f); + + f << "o " << TCHAR_TO_ANSI(*(ObjectName +"_box")) << "\n"; + + // define the 8 vertices + boxVerts.Add(box.Center + box.Rotation.RotateVector(FVector(-HalfExtent.X, -HalfExtent.Y, -HalfExtent.Z))); + boxVerts.Add(box.Center + box.Rotation.RotateVector(FVector(-HalfExtent.X, -HalfExtent.Y, +HalfExtent.Z))); + boxVerts.Add(box.Center + box.Rotation.RotateVector(FVector(-HalfExtent.X, +HalfExtent.Y, -HalfExtent.Z))); + boxVerts.Add(box.Center + box.Rotation.RotateVector(FVector(-HalfExtent.X, +HalfExtent.Y, +HalfExtent.Z))); + boxVerts.Add(box.Center + box.Rotation.RotateVector(FVector(+HalfExtent.X, -HalfExtent.Y, -HalfExtent.Z))); + boxVerts.Add(box.Center + box.Rotation.RotateVector(FVector(+HalfExtent.X, -HalfExtent.Y, +HalfExtent.Z))); + boxVerts.Add(box.Center + box.Rotation.RotateVector(FVector(+HalfExtent.X, +HalfExtent.Y, -HalfExtent.Z))); + boxVerts.Add(box.Center + box.Rotation.RotateVector(FVector(+HalfExtent.X, +HalfExtent.Y, +HalfExtent.Z))); + + // define the 12 faces (36 indices) + indexBuffer.Add(0); indexBuffer.Add(1); indexBuffer.Add(3); + indexBuffer.Add(0); indexBuffer.Add(3); indexBuffer.Add(2); + indexBuffer.Add(2); indexBuffer.Add(3); indexBuffer.Add(7); + indexBuffer.Add(2); indexBuffer.Add(7); indexBuffer.Add(6); + indexBuffer.Add(6); indexBuffer.Add(7); indexBuffer.Add(5); + indexBuffer.Add(6); indexBuffer.Add(5); indexBuffer.Add(4); + indexBuffer.Add(4); indexBuffer.Add(5); indexBuffer.Add(1); + indexBuffer.Add(4); indexBuffer.Add(1); indexBuffer.Add(0); + indexBuffer.Add(2); indexBuffer.Add(6); indexBuffer.Add(4); + indexBuffer.Add(2); indexBuffer.Add(4); indexBuffer.Add(0); + indexBuffer.Add(7); indexBuffer.Add(3); indexBuffer.Add(1); + indexBuffer.Add(7); indexBuffer.Add(1); indexBuffer.Add(5); + + // write all vertex + for (int32 j=0; jAggGeom.ConvexElems) + { + // get data + PxConvexMesh *mesh = convex.GetConvexMesh(); + if (!mesh) continue; + int32 nbVerts = mesh->getNbVertices(); + const PxVec3* convexVerts = mesh->getVertices(); + const PxU8* indexBuffer = (PxU8 *) mesh->getIndexBuffer(); + + f << "o " << TCHAR_TO_ANSI(*(ObjectName +"_convex")) << "\n"; + + // write all vertex + for (int32 j=0; jgetNbPolygons(); ++i) + { + PxHullPolygon face; + bool status = mesh->getPolygonData(i, face); + const PxU8* faceIndices = indexBuffer + face.mIndexBase; + int faceNbVerts = face.mNbVerts; + for(int32 j=2; jTriMeshes) + { + // get data + PxU32 nbVerts = mesh->getNbVertices(); + const PxVec3* convexVerts = mesh->getVertices(); + + f << "o " << TCHAR_TO_ANSI(*(ObjectName +"_mesh")) << "\n"; + + // write all vertex + for (PxU32 j=0; jgetTriangleMeshFlags() & PxTriangleMeshFlag::e16_BIT_INDICES) + { + PxU16 *Indices16 = (PxU16 *) mesh->getTriangles(); + for (PxU32 i=0; igetNbTriangles(); ++i) + { + // inverse order for left hand + f << "f " << Offset + Indices16[k+2] << " " << Offset + Indices16[k+1] << " " << Offset + Indices16[k] << "\n"; + k += 3; + } + } + else + { + PxU32 *Indices32 = (PxU32 *) mesh->getTriangles(); + for (PxU32 i=0; igetNbTriangles(); ++i) + { + // inverse order for left hand + f << "f " << Offset + Indices32[k+2] << " " << Offset + Indices32[k+1] << " " << Offset + Indices32[k] << "\n"; + k += 3; + } + } + TotalVerticesAdded += nbVerts; + Offset += nbVerts; + } + } + return TotalVerticesAdded; +} + void FCarlaExporterModule::AddMenuExtension(FMenuBuilder& Builder) { Builder.AddMenuEntry(FCarlaExporterCommands::Get().PluginActionExportAll); diff --git a/Unreal/CarlaUE4/Plugins/CarlaExporter/Source/CarlaExporter/Public/CarlaExporter.h b/Unreal/CarlaUE4/Plugins/CarlaExporter/Source/CarlaExporter/Public/CarlaExporter.h index 76a321e6c..3127f12e5 100644 --- a/Unreal/CarlaUE4/Plugins/CarlaExporter/Source/CarlaExporter/Public/CarlaExporter.h +++ b/Unreal/CarlaUE4/Plugins/CarlaExporter/Source/CarlaExporter/Public/CarlaExporter.h @@ -13,6 +13,15 @@ class FToolBarBuilder; class FMenuBuilder; +enum AreaType +{ + ROAD, + GRASS, + SIDEWALK, + CROSSWALK, + BLOCK +}; + class FCarlaExporterModule : public IModuleInterface { public: @@ -27,6 +36,7 @@ public: private: void AddMenuExtension(FMenuBuilder& Builder); + int32 WriteObjectGeom(std::ofstream &f, FString ObjectName, UBodySetup *body, FTransform &CompTransform, AreaType Area, int32 Offset); private: TSharedPtr PluginCommands;