First working version of CarlaExporter after refactoring to use Chaos instead of PhysX
This commit is contained in:
parent
76dfbb1244
commit
2cbb528874
|
@ -18,6 +18,8 @@
|
|||
#include "LevelEditor.h"
|
||||
#include "EngineUtils.h"
|
||||
#include "PhysicsPublic.h"
|
||||
#include "Chaos/Core.h"
|
||||
#include "Chaos/TriangleMeshImplicitObject.h"
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
|
@ -191,8 +193,6 @@ void FCarlaExporterModule::PluginButtonClicked()
|
|||
|
||||
int32 FCarlaExporterModule::WriteObjectGeom(std::ofstream &f, FString ObjectName, UBodySetup *body, FTransform &CompTransform, AreaType Area, int32 Offset)
|
||||
{
|
||||
// @CARLAUE
|
||||
#if 0
|
||||
if (!body) return 0;
|
||||
|
||||
constexpr float TO_METERS = 0.01f;
|
||||
|
@ -200,139 +200,169 @@ int32 FCarlaExporterModule::WriteObjectGeom(std::ofstream &f, FString ObjectName
|
|||
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<FVector> boxVerts;
|
||||
TArray<int32> 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; j<nbVerts; j++)
|
||||
{
|
||||
const FVector &v = boxVerts[j];
|
||||
FVector vec(v.X, v.Y, v.Z);
|
||||
FVector vec3 = CompTransform.TransformVector(vec);
|
||||
FVector world(CompLocation.X + vec3.X, CompLocation.Y + vec3.Y, CompLocation.Z + vec3.Z);
|
||||
|
||||
f << "v " << std::fixed << world.X * TO_METERS << " " << world.Z * TO_METERS << " " << world.Y * TO_METERS << "\n";
|
||||
}
|
||||
// set the material in function of the area type
|
||||
switch (Area)
|
||||
{
|
||||
case AreaType::ROAD: f << "usemtl road" << "\n"; break;
|
||||
case AreaType::GRASS: f << "usemtl grass" << "\n"; break;
|
||||
case AreaType::SIDEWALK: f << "usemtl sidewalk" << "\n"; break;
|
||||
case AreaType::CROSSWALK: f << "usemtl crosswalk" << "\n"; break;
|
||||
case AreaType::BLOCK: f << "usemtl block" << "\n"; break;
|
||||
}
|
||||
// write all faces
|
||||
int k = 0;
|
||||
for (int32 i=0; i<indexBuffer.Num()/3; ++i)
|
||||
{
|
||||
// inverse order for left hand
|
||||
f << "f " << Offset + indexBuffer[k+2] << " " << Offset + indexBuffer[k+1] << " " << Offset + indexBuffer[k] << "\n";
|
||||
k += 3;
|
||||
}
|
||||
TotalVerticesAdded += nbVerts;
|
||||
Offset += nbVerts;
|
||||
Written = true;
|
||||
}
|
||||
|
||||
// try to write the simple collision mesh
|
||||
for (const auto &convex : body->AggGeom.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; j<nbVerts; j++)
|
||||
{
|
||||
const PxVec3 &v = convexVerts[j];
|
||||
FVector vec(v.x, v.y, v.z);
|
||||
FVector vec3 = CompTransform.TransformVector(vec);
|
||||
FVector world(CompLocation.X + vec3.X, CompLocation.Y + vec3.Y, CompLocation.Z + vec3.Z);
|
||||
|
||||
f << "v " << std::fixed << world.X * TO_METERS << " " << world.Z * TO_METERS << " " << world.Y * TO_METERS << "\n";
|
||||
}
|
||||
// set the material in function of the area type
|
||||
switch (Area)
|
||||
{
|
||||
case AreaType::ROAD: f << "usemtl road" << "\n"; break;
|
||||
case AreaType::GRASS: f << "usemtl grass" << "\n"; break;
|
||||
case AreaType::SIDEWALK: f << "usemtl sidewalk" << "\n"; break;
|
||||
case AreaType::CROSSWALK: f << "usemtl crosswalk" << "\n"; break;
|
||||
case AreaType::BLOCK: f << "usemtl block" << "\n"; break;
|
||||
}
|
||||
// write all faces
|
||||
for (PxU32 i=0; i<mesh->getNbPolygons(); ++i)
|
||||
{
|
||||
PxHullPolygon face;
|
||||
bool status = mesh->getPolygonData(i, face);
|
||||
const PxU8* faceIndices = indexBuffer + face.mIndexBase;
|
||||
int faceNbVerts = face.mNbVerts;
|
||||
for(int32 j=2; j<faceNbVerts; j++)
|
||||
{
|
||||
// inverse order for left hand
|
||||
f << "f " << Offset + faceIndices[j-1] << " " << Offset + faceIndices[j] << " " << Offset + faceIndices[0] << "\n";
|
||||
}
|
||||
}
|
||||
TotalVerticesAdded += nbVerts;
|
||||
Offset += nbVerts;
|
||||
Written = true;
|
||||
}
|
||||
|
||||
if (!Written)
|
||||
{
|
||||
auto WriteComplexCollision = [&]() {
|
||||
// write the mesh
|
||||
for (const auto &mesh : body->TriMeshes)
|
||||
for (const TSharedPtr<Chaos::FTriangleMeshImplicitObject, ESPMode::ThreadSafe> &mesh : body->ChaosTriMeshes)
|
||||
{
|
||||
// get data
|
||||
PxU32 nbVerts = mesh->getNbVertices();
|
||||
const PxVec3* convexVerts = mesh->getVertices();
|
||||
uint32_t nbVerts = mesh->Particles().Size();
|
||||
const Chaos::TParticles<Chaos::FRealSingle, 3> &convexVerts = mesh->Particles();
|
||||
const Chaos::FTrimeshIndexBuffer &convexIndices = mesh->Elements();
|
||||
|
||||
f << "o " << TCHAR_TO_ANSI(*(ObjectName +"_mesh")) << "\n";
|
||||
|
||||
// write all vertex
|
||||
for (PxU32 j=0; j<nbVerts; j++)
|
||||
for (uint32_t j=0; j < nbVerts; ++j)
|
||||
{
|
||||
const PxVec3 &v = convexVerts[j];
|
||||
FVector vec(v.x, v.y, v.z);
|
||||
const Chaos::FVec3 &v = convexVerts.X(j); //FVector(convexVerts.X(j*3), convexVerts.X(j*3+1), convexVerts.X(j*3+2));
|
||||
Chaos::FVec3 vec(v.X, v.Y, v.Z);
|
||||
Chaos::FVec3 vec3 = CompTransform.TransformVector(vec);
|
||||
Chaos::FVec3 world(CompLocation.X + vec3.X, CompLocation.Y + vec3.Y, CompLocation.Z + vec3.Z);
|
||||
|
||||
f << "v " << std::fixed << world.X * TO_METERS << " " << world.Z * TO_METERS << " " << world.Y * TO_METERS << "\n";
|
||||
}
|
||||
// set the material in function of the area type
|
||||
switch (Area)
|
||||
{
|
||||
case AreaType::ROAD: f << "usemtl road" << "\n"; break;
|
||||
case AreaType::GRASS: f << "usemtl grass" << "\n"; break;
|
||||
case AreaType::SIDEWALK: f << "usemtl sidewalk" << "\n"; break;
|
||||
case AreaType::CROSSWALK: f << "usemtl crosswalk" << "\n"; break;
|
||||
case AreaType::BLOCK: f << "usemtl block" << "\n"; break;
|
||||
}
|
||||
// write all faces
|
||||
// triangle indices can be of 16 or 32 bits
|
||||
if (!convexIndices.RequiresLargeIndices())
|
||||
{
|
||||
const TArray<Chaos::TVec3<uint16>>& Indices16 = convexIndices.GetIndexBuffer<uint16>();
|
||||
for (int32 i=0; i < Indices16.Num(); ++i)
|
||||
{
|
||||
// inverse order for left hand
|
||||
f << "f " << Offset + Indices16[i].Z << " " << Offset + Indices16[i].Y << " " << Offset + Indices16[i].X << "\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const TArray<Chaos::TVec3<int32>>& Indices32 = convexIndices.GetIndexBuffer<int32>();
|
||||
for (int32 i=0; i < Indices32.Num(); ++i)
|
||||
{
|
||||
// inverse order for left hand
|
||||
f << "f " << Offset + Indices32[i].Z << " " << Offset + Indices32[i].Y << " " << Offset + Indices32[i].X << "\n";
|
||||
}
|
||||
}
|
||||
TotalVerticesAdded += nbVerts;
|
||||
Offset += nbVerts;
|
||||
Written = true;
|
||||
}
|
||||
};
|
||||
|
||||
auto WriteSimpleCollision = [&]() {
|
||||
// try to write the simple collision mesh
|
||||
for (const FKConvexElem &convex : body->AggGeom.ConvexElems)
|
||||
{
|
||||
// get data
|
||||
//PxConvexMesh *mesh = convex.GetConvexMesh();
|
||||
//if (!mesh) continue;
|
||||
int32 nbVerts = convex.VertexData.Num();
|
||||
TArray<FVector> convexVerts = convex.VertexData;
|
||||
int32 nbIndices = convex.IndexData.Num();
|
||||
TArray<int32> indexBuffer = convex.IndexData;
|
||||
|
||||
f << "o " << TCHAR_TO_ANSI(*(ObjectName +"_convex")) << "\n";
|
||||
|
||||
// write all vertex
|
||||
for (int32 j=0; j<nbVerts; j++)
|
||||
{
|
||||
const FVector &v = convexVerts[j];
|
||||
FVector vec(v.X, v.Y, v.Z);
|
||||
FVector vec3 = CompTransform.TransformVector(vec);
|
||||
FVector world(CompLocation.X + vec3.X, CompLocation.Y + vec3.Y, CompLocation.Z + vec3.Z);
|
||||
|
||||
f << "v " << std::fixed << world.X * TO_METERS << " " << world.Z * TO_METERS << " " << world.Y * TO_METERS << "\n";
|
||||
}
|
||||
// set the material in function of the area type
|
||||
switch (Area)
|
||||
{
|
||||
case AreaType::ROAD: f << "usemtl road" << "\n"; break;
|
||||
case AreaType::GRASS: f << "usemtl grass" << "\n"; break;
|
||||
case AreaType::SIDEWALK: f << "usemtl sidewalk" << "\n"; break;
|
||||
case AreaType::CROSSWALK: f << "usemtl crosswalk" << "\n"; break;
|
||||
case AreaType::BLOCK: f << "usemtl block" << "\n"; break;
|
||||
}
|
||||
// write all faces
|
||||
//TArray<FPlane> planes;
|
||||
//convex->GetPlanes(planes);
|
||||
|
||||
// for (PxU32 i=0; i<mesh->getNbPolygons(); ++i) //planes.Num()
|
||||
// {
|
||||
// PxHullPolygon face; //planes[i]
|
||||
// bool status = mesh->getPolygonData(i, face);
|
||||
// const PxU8* faceIndices = indexBuffer + face.mIndexBase;
|
||||
// int faceNbVerts = face.mNbVerts;
|
||||
// for(int32 j=2; j<faceNbVerts; j++)
|
||||
// {
|
||||
// // inverse order for left hand
|
||||
// f << "f " << Offset + faceIndices[j-1] << " " << Offset + faceIndices[j] << " " << Offset + faceIndices[0] << "\n";
|
||||
// }
|
||||
// }
|
||||
|
||||
int32 NumTriangles = convex.IndexData.Num() / 3;
|
||||
for(int32 j=0; j<NumTriangles; ++j)
|
||||
{
|
||||
f << "f "
|
||||
<< Offset + indexBuffer[3 * j] << " "
|
||||
<< Offset + indexBuffer[3 * j + 1] << " "
|
||||
<< Offset + indexBuffer[3 * j + 2] << "\n";
|
||||
}
|
||||
|
||||
TotalVerticesAdded += nbVerts;
|
||||
Offset += nbVerts;
|
||||
Written = true;
|
||||
}
|
||||
};
|
||||
|
||||
auto WriteBoxCollision = [&]() {
|
||||
// try to write the box collision if any
|
||||
for (const FKBoxElem &box: body->AggGeom.BoxElems)
|
||||
{
|
||||
// get data
|
||||
const int32 nbVerts = 8;
|
||||
TArray<FVector> boxVerts;
|
||||
TArray<int32> 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; j<nbVerts; j++)
|
||||
{
|
||||
const FVector &v = boxVerts[j];
|
||||
FVector vec(v.X, v.Y, v.Z);
|
||||
FVector vec3 = CompTransform.TransformVector(vec);
|
||||
FVector world(CompLocation.X + vec3.X, CompLocation.Y + vec3.Y, CompLocation.Z + vec3.Z);
|
||||
|
||||
|
@ -349,31 +379,30 @@ int32 FCarlaExporterModule::WriteObjectGeom(std::ofstream &f, FString ObjectName
|
|||
}
|
||||
// write all faces
|
||||
int k = 0;
|
||||
// triangle indices can be of 16 or 32 bits
|
||||
if (mesh->getTriangleMeshFlags() & PxTriangleMeshFlag::e16_BIT_INDICES)
|
||||
for (int32 i=0; i<indexBuffer.Num()/3; ++i)
|
||||
{
|
||||
PxU16 *Indices16 = (PxU16 *) mesh->getTriangles();
|
||||
for (PxU32 i=0; i<mesh->getNbTriangles(); ++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; i<mesh->getNbTriangles(); ++i)
|
||||
{
|
||||
// inverse order for left hand
|
||||
f << "f " << Offset + Indices32[k+2] << " " << Offset + Indices32[k+1] << " " << Offset + Indices32[k] << "\n";
|
||||
k += 3;
|
||||
}
|
||||
// inverse order for left hand
|
||||
f << "f " << Offset + indexBuffer[k+2] << " " << Offset + indexBuffer[k+1] << " " << Offset + indexBuffer[k] << "\n";
|
||||
k += 3;
|
||||
}
|
||||
TotalVerticesAdded += nbVerts;
|
||||
Offset += nbVerts;
|
||||
Written = true;
|
||||
}
|
||||
};
|
||||
|
||||
if(ObjectName.Contains(TEXT("Road"))){
|
||||
WriteComplexCollision();
|
||||
if(!Written) WriteSimpleCollision();
|
||||
if(!Written) WriteBoxCollision();
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteSimpleCollision();
|
||||
if(!Written) WriteBoxCollision();
|
||||
if(!Written) WriteComplexCollision();
|
||||
}
|
||||
|
||||
return TotalVerticesAdded;
|
||||
#else
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue