add reportHitNumber to allow reporting a specific ray intersection hit

(by default, pybullet.rayTestBatch reports the closest hit, so you can report 2nd closest or 3rd closest hit etc)
Fix pybullet.createCollisionShape, in some cases (concave trimesh, convex mesh) two instances were created.
This commit is contained in:
Erwin Coumans
2020-05-07 23:23:24 -07:00
parent 5fd11fe90b
commit daa0a27403
6 changed files with 54 additions and 35 deletions

View File

@@ -4993,30 +4993,7 @@ bool PhysicsServerCommandProcessor::processCreateCollisionShapeCommand(const str
CommonFileIOInterface* fileIO = m_data->m_pluginManager.getFileIOInterface();
glmesh = LoadMeshFromObj(relativeFileName, pathPrefix, fileIO);
}
if (glmesh)
{
if (compound == 0)
{
compound = worldImporter->createCompoundShape();
}
btTriangleMesh* meshInterface = new btTriangleMesh();
m_data->m_meshInterfaces.push_back(meshInterface);
for (int i = 0; i < glmesh->m_numIndices / 3; i++)
{
float* v0 = glmesh->m_vertices->at(glmesh->m_indices->at(i * 3)).xyzw;
float* v1 = glmesh->m_vertices->at(glmesh->m_indices->at(i * 3 + 1)).xyzw;
float* v2 = glmesh->m_vertices->at(glmesh->m_indices->at(i * 3 + 2)).xyzw;
meshInterface->addTriangle(
btVector3(v0[0], v0[1], v0[2])* meshScale,
btVector3(v1[0], v1[1], v1[2])* meshScale,
btVector3(v2[0], v2[1], v2[2])* meshScale);
}
btBvhTriangleMeshShape* trimesh = new btBvhTriangleMeshShape(meshInterface, true, true);
compound->addChildShape(childTransform, trimesh);
}
//btBvhTriangleMeshShape is created below
}
else
{
@@ -5049,6 +5026,8 @@ bool PhysicsServerCommandProcessor::processCreateCollisionShapeCommand(const str
convexHull->optimizeConvexHull();
compound->addChildShape(childTransform, convexHull);
delete glmesh;
glmesh = 0;
}
if (out_type == UrdfGeometry::FILE_OBJ)
{
@@ -5963,9 +5942,10 @@ struct BatchRayCaster
const b3RayData* m_rayInputBuffer;
b3RayHitInfo* m_hitInfoOutputBuffer;
int m_numRays;
int m_reportHitNumber;
BatchRayCaster(b3ThreadPool* threadPool, const btCollisionWorld* world, const b3RayData* rayInputBuffer, b3RayHitInfo* hitInfoOutputBuffer, int numRays)
: m_threadPool(threadPool), m_world(world), m_rayInputBuffer(rayInputBuffer), m_hitInfoOutputBuffer(hitInfoOutputBuffer), m_numRays(numRays)
BatchRayCaster(b3ThreadPool* threadPool, const btCollisionWorld* world, const b3RayData* rayInputBuffer, b3RayHitInfo* hitInfoOutputBuffer, int numRays, int reportHitNumber)
: m_threadPool(threadPool), m_world(world), m_rayInputBuffer(rayInputBuffer), m_hitInfoOutputBuffer(hitInfoOutputBuffer), m_numRays(numRays), m_reportHitNumber(reportHitNumber)
{
m_syncInfo = new CastSyncInfo;
}
@@ -6022,6 +6002,10 @@ struct BatchRayCaster
{
for (int i = 0; i < m_numRays; i++)
{
if (i == 17)
{
printf("!\n");
}
processRay(i);
}
}
@@ -6036,8 +6020,24 @@ struct BatchRayCaster
btCollisionWorld::ClosestRayResultCallback rayResultCallback(rayFromWorld, rayToWorld);
rayResultCallback.m_flags |= btTriangleRaycastCallback::kF_UseGjkConvexCastRaytest;
m_world->rayTest(rayFromWorld, rayToWorld, rayResultCallback);
if (m_reportHitNumber >= 0)
{
//compute all hits, and select the m_reportHitNumber, if available
btCollisionWorld::AllHitsRayResultCallback allResultsCallback(rayFromWorld, rayToWorld);
allResultsCallback.m_flags |= btTriangleRaycastCallback::kF_UseGjkConvexCastRaytest;
m_world->rayTest(rayFromWorld, rayToWorld, allResultsCallback);
if (allResultsCallback.m_collisionObjects.size() > m_reportHitNumber)
{
rayResultCallback.m_collisionObject = allResultsCallback.m_collisionObjects[m_reportHitNumber];
rayResultCallback.m_closestHitFraction = allResultsCallback.m_hitFractions[m_reportHitNumber];
rayResultCallback.m_hitNormalWorld = allResultsCallback.m_hitNormalWorld[m_reportHitNumber];
rayResultCallback.m_hitPointWorld = allResultsCallback.m_hitPointWorld[m_reportHitNumber];
}
}
else
{
m_world->rayTest(rayFromWorld, rayToWorld, rayResultCallback);
}
b3RayHitInfo& hit = m_hitInfoOutputBuffer[ray];
if (rayResultCallback.hasHit())
@@ -6114,6 +6114,7 @@ bool PhysicsServerCommandProcessor::processRequestRaycastIntersectionsCommand(co
const int numStreamingRays = clientCmd.m_requestRaycastIntersections.m_numStreamingRays;
const int totalRays = numCommandRays + numStreamingRays;
int numThreads = clientCmd.m_requestRaycastIntersections.m_numThreads;
int reportHitNumber = clientCmd.m_requestRaycastIntersections.m_reportHitNumber;
if (numThreads == 0)
{
// When 0 is specified, Bullet can decide how many threads to use.
@@ -6182,7 +6183,7 @@ bool PhysicsServerCommandProcessor::processRequestRaycastIntersectionsCommand(co
}
}
BatchRayCaster batchRayCaster(m_data->m_threadPool, m_data->m_dynamicsWorld, &rays[0], (b3RayHitInfo*)bufferServerToClient, totalRays);
BatchRayCaster batchRayCaster(m_data->m_threadPool, m_data->m_dynamicsWorld, &rays[0], (b3RayHitInfo*)bufferServerToClient, totalRays, reportHitNumber);
batchRayCaster.castRays(numThreads);
serverStatusOut.m_numDataStreamBytes = totalRays * sizeof(b3RayData);