void physx::Pt::collideCellsWithStaticMesh(ParticleCollData* collData, const LocalCellHash& localCellHash, const GeometryUnion& meshShape, const PxTransform& world2Shape, const PxTransform& shape2World, PxReal /*cellSize*/, PxReal /*collisionRange*/, PxReal proxRadius, const PxVec3& /*packetCorner*/) { PX_ASSERT(collData); PX_ASSERT(localCellHash.isHashValid); PX_ASSERT(localCellHash.numParticles <= PT_SUBPACKET_PARTICLE_LIMIT_COLLISION); PX_ASSERT(localCellHash.numHashEntries <= PT_LOCAL_HASH_SIZE_MESH_COLLISION); const PxTriangleMeshGeometryLL& meshShapeData = meshShape.get<const PxTriangleMeshGeometryLL>(); const TriangleMesh* meshData = meshShapeData.meshData; PX_ASSERT(meshData); // mesh bounds in world space (conservative) const PxBounds3 shapeBounds = meshData->getLocalBoundsFast().transformSafe(world2Shape.getInverse() * meshShapeData.scale); const bool idtScaleMesh = meshShapeData.scale.isIdentity(); Cm::FastVertex2ShapeScaling meshScaling; if(!idtScaleMesh) meshScaling.init(meshShapeData.scale); // process the particle cells for(PxU32 c = 0; c < localCellHash.numHashEntries; c++) { const ParticleCell& cell = localCellHash.hashEntries[c]; if(cell.numParticles == PX_INVALID_U32) continue; PxBounds3 cellBounds; cellBounds.setEmpty(); PxBounds3 cellBoundsNew(PxBounds3::empty()); PxU32* it = localCellHash.particleIndices + cell.firstParticle; const PxU32* end = it + cell.numParticles; for(; it != end; it++) { const ParticleCollData& particle = collData[*it]; cellBounds.include(particle.oldPos); cellBoundsNew.include(particle.newPos); } PX_ASSERT(!cellBoundsNew.isEmpty()); cellBoundsNew.fattenFast(proxRadius); cellBounds.include(cellBoundsNew); if(!cellBounds.intersects(shapeBounds)) continue; // early out if (inflated) cell doesn't intersect mesh bounds // opcode query: cell bounds against shape bounds in unscaled mesh space PxcContactCellMeshCallback callback(collData, &(localCellHash.particleIndices[cell.firstParticle]), cell.numParticles, *meshData, meshScaling, proxRadius, NULL, shape2World); testBoundsMesh(*meshData, world2Shape, meshScaling, idtScaleMesh, cellBounds, callback); } }
bool AABBTreeOfVerticesBuilder::ComputeGlobalBox(const PxU32* primitives, PxU32 nb_prims, PxBounds3& global_box) const { // Checkings if(!primitives || !nb_prims) return false; // Initialize global box global_box.setEmpty(); // Loop through vertices for(PxU32 i=0;i<nb_prims;i++) { // Update global box global_box.include(mVertexArray[primitives[i]]); } return true; }
////////////////////////////////////////////////////////////////////////// // checks if points form a valid AABB cube, if not construct a default CUBE static bool checkPointsAABBValidity(PxU32 numPoints, const PxVec3* points, PxU32 stride , float distanceEpsilon, float resizeValue, PxVec3& center, PxVec3& scale, PxU32& vcount, PxVec3* vertices, bool fCheck = false) { const char* vtx = reinterpret_cast<const char *> (points); PxBounds3 bounds; bounds.setEmpty(); // get the bounding box for (PxU32 i = 0; i < numPoints; i++) { const PxVec3& p = *reinterpret_cast<const PxVec3 *> (vtx); vtx += stride; bounds.include(p); } PxVec3 dim = bounds.getDimensions(); center = bounds.getCenter(); // special case, the AABB is very thin or user provided us with only input 2 points // we construct an AABB cube and return it if ( dim.x < distanceEpsilon || dim.y < distanceEpsilon || dim.z < distanceEpsilon || numPoints < 3 ) { float len = FLT_MAX; // pick the shortest size bigger than the distance epsilon if ( dim.x > distanceEpsilon && dim.x < len ) len = dim.x; if ( dim.y > distanceEpsilon && dim.y < len ) len = dim.y; if ( dim.z > distanceEpsilon && dim.z < len ) len = dim.z; // if the AABB is small in all dimensions, resize it if ( len == FLT_MAX ) { dim = PxVec3(resizeValue); } // if one edge is small, set to 1/5th the shortest non-zero edge. else { if ( dim.x < distanceEpsilon ) dim.x = len * 0.05f; else dim.x *= 0.5f; if ( dim.y < distanceEpsilon ) dim.y = len * 0.05f; else dim.y *= 0.5f; if ( dim.z < distanceEpsilon ) dim.z = len * 0.05f; else dim.z *= 0.5f; } // construct the AABB const PxVec3 extPos = center + dim; const PxVec3 extNeg = center - dim; if(fCheck) vcount = 0; vertices[vcount++] = extNeg; vertices[vcount++] = PxVec3(extPos.x,extNeg.y,extNeg.z); vertices[vcount++] = PxVec3(extPos.x,extPos.y,extNeg.z); vertices[vcount++] = PxVec3(extNeg.x,extPos.y,extNeg.z); vertices[vcount++] = PxVec3(extNeg.x,extNeg.y,extPos.z); vertices[vcount++] = PxVec3(extPos.x,extNeg.y,extPos.z); vertices[vcount++] = extPos; vertices[vcount++] = PxVec3(extNeg.x,extPos.y,extPos.z); return true; // return cube } else { scale = dim; } return false; }