void physx::PxSetGroupsMask(const PxRigidActor& actor, const PxGroupsMask& mask) { PxFilterData tmp; PxFilterData fd = convert(mask); if (actor.getNbShapes() == 1) { PxShape* shape = NULL; actor.getShapes(&shape, 1); // retrieve current group tmp = shape->getSimulationFilterData(); fd.word0 = tmp.word0; // set new filter data shape->setSimulationFilterData(fd); } else { PxShape* shape; PxU32 numShapes = actor.getNbShapes(); shdfnd::InlineArray<PxShape*, 64> shapes; if(numShapes > 64) { shapes.resize(64); } else { shapes.resize(numShapes); } PxU32 iter = 1 + numShapes/64; for(PxU32 i=0; i < iter; i++) { PxU32 offset = i * 64; PxU32 size = numShapes - offset; if(size > 64) size = 64; actor.getShapes(shapes.begin(), size, offset); for(PxU32 j = size; j--;) { // retrieve current group mask shape = shapes[j]; // retrieve current group tmp = shape->getSimulationFilterData(); fd.word0 = tmp.word0; // set new filter data shape->setSimulationFilterData(fd); } } } }
void physx::PxSetGroup(const PxRigidActor& actor, const PxU16 collisionGroup) { PX_CHECK_AND_RETURN(collisionGroup < 32,"Collision group must be less than 32"); PxFilterData fd; if (actor.getNbShapes() == 1) { PxShape* shape = NULL; actor.getShapes(&shape, 1); // retrieve current group mask fd = shape->getSimulationFilterData(); fd.word0 = collisionGroup; // set new filter data shape->setSimulationFilterData(fd); } else { PxShape* shape; PxU32 numShapes = actor.getNbShapes(); shdfnd::InlineArray<PxShape*, 64> shapes; if(numShapes > 64) { shapes.resize(64); } else { shapes.resize(numShapes); } PxU32 iter = 1 + numShapes/64; for(PxU32 i=0; i < iter; i++) { PxU32 offset = i * 64; PxU32 size = numShapes - offset; if(size > 64) size = 64; actor.getShapes(shapes.begin(), size, offset); for(PxU32 j = size; j--;) { // retrieve current group mask shape = shapes[j]; fd = shape->getSimulationFilterData(); fd.word0 = collisionGroup; // set new filter data shape->setSimulationFilterData(fd); } } } }
//================================================================================= // Single closest hit compound sweep bool PxRigidBodyExt::linearSweepSingle( PxRigidBody& body, PxScene& scene, const PxVec3& unitDir, const PxReal distance, PxHitFlags outputFlags, PxSweepHit& closestHit, PxU32& shapeIndex, const PxQueryFilterData& filterData, PxQueryFilterCallback* filterCall, const PxQueryCache* cache, const PxReal inflation) { shapeIndex = 0xFFFFffff; PxReal closestDist = distance; PxU32 nbShapes = body.getNbShapes(); for(PxU32 i=0; i < nbShapes; i++) { PxShape* shape = NULL; body.getShapes(&shape, 1, i); PX_ASSERT(shape != NULL); PxTransform pose = PxShapeExt::getGlobalPose(*shape, body); PxQueryFilterData fd; fd.flags = filterData.flags; PxU32 or4 = (filterData.data.word0 | filterData.data.word1 | filterData.data.word2 | filterData.data.word3); fd.data = or4 ? filterData.data : shape->getSimulationFilterData(); PxGeometryHolder anyGeom = shape->getGeometry(); PxSweepBuffer subHit; // touching hits are not allowed to be returned from the filters scene.sweep(anyGeom.any(), pose, unitDir, distance, subHit, outputFlags, fd, filterCall, cache, inflation); if (subHit.hasBlock && subHit.block.distance < closestDist) { closestDist = subHit.block.distance; closestHit = subHit.block; shapeIndex = i; } } return (shapeIndex != 0xFFFFffff); }
void SampleNorthPole::setCCDActive(PxShape& shape) { shape.setFlag(PxShapeFlag::eUSE_SWEPT_BOUNDS,true); PxFilterData fd = shape.getSimulationFilterData(); fd.word3 |= CCD_FLAG; shape.setSimulationFilterData(fd); }
PxGroupsMask physx::PxGetGroupsMask(const PxRigidActor& actor) { PX_CHECK_AND_RETURN_VAL(actor.getNbShapes() >= 1,"At least one shape must be in actor",PxGroupsMask()); PxShape* shape = NULL; actor.getShapes(&shape, 1); PxFilterData fd = shape->getSimulationFilterData(); return convert(fd); }
PxU16 physx::PxGetGroup(const PxRigidActor& actor) { PX_CHECK_AND_RETURN_NULL(actor.getNbShapes() >= 1,"There must be a shape in actor"); PxShape* shape = NULL; actor.getShapes(&shape, 1); PxFilterData fd = shape->getSimulationFilterData(); return (PxU16)fd.word0; }
void SampleNorthPole::onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, PxU32 nbPairs) { for(PxU32 i=0; i < nbPairs; i++) { PxU32 n = 2; const PxContactPairFlag::Enum delShapeFlags[] = { PxContactPairFlag::eDELETED_SHAPE_0, PxContactPairFlag::eDELETED_SHAPE_1 }; const PxContactPair& cp = pairs[i]; while(n--) { if(!(cp.flags & delShapeFlags[n])) { PxShape* shape = cp.shapes[n]; PxFilterData fd = shape->getSimulationFilterData(); if(isDetachable(fd)) { mDetaching.push_back(shape); } } } } }
bool copyStaticProperties(PxRigidActor& to, const PxRigidActor& from,NxMirrorScene::MirrorFilter &mirrorFilter) { physx::shdfnd::InlineArray<PxShape*, 64> shapes; shapes.resize(from.getNbShapes()); PxU32 shapeCount = from.getNbShapes(); from.getShapes(shapes.begin(), shapeCount); physx::shdfnd::InlineArray<PxMaterial*, 64> materials; for(PxU32 i = 0; i < shapeCount; i++) { PxShape* s = shapes[i]; if ( mirrorFilter.shouldMirror(*s) ) { PxU32 materialCount = s->getNbMaterials(); materials.resize(materialCount); s->getMaterials(materials.begin(), materialCount); PxShape* shape = to.createShape(s->getGeometry().any(), materials.begin(), static_cast<physx::PxU16>(materialCount)); shape->setLocalPose( s->getLocalPose()); shape->setContactOffset(s->getContactOffset()); shape->setRestOffset(s->getRestOffset()); shape->setFlags(s->getFlags()); shape->setSimulationFilterData(s->getSimulationFilterData()); shape->setQueryFilterData(s->getQueryFilterData()); mirrorFilter.reviseMirrorShape(*shape); } } to.setActorFlags(from.getActorFlags()); to.setOwnerClient(from.getOwnerClient()); to.setDominanceGroup(from.getDominanceGroup()); if ( to.getNbShapes() ) { mirrorFilter.reviseMirrorActor(to); } return to.getNbShapes() != 0; }
void SampleNorthPole::setDetachable(PxShape& shape) { PxFilterData fd = shape.getSimulationFilterData(); fd.word3 |= PxU32(DETACHABLE_FLAG); shape.setSimulationFilterData(fd); }
void SampleNorthPole::setSnowball(PxShape& shape) { PxFilterData fd = shape.getSimulationFilterData(); fd.word3 |= SNOWBALL_FLAG; shape.setSimulationFilterData(fd); }
//================================================================================= // Multiple hits compound sweep // AP: we might be able to improve the return results API but no time for it in 3.3 PxU32 PxRigidBodyExt::linearSweepMultiple( PxRigidBody& body, PxScene& scene, const PxVec3& unitDir, const PxReal distance, PxHitFlags outputFlags, PxSweepHit* hitBuffer, PxU32* hitShapeIndices, PxU32 hitBufferSize, PxSweepHit& block, PxI32& blockingHitShapeIndex, bool& overflow, const PxQueryFilterData& filterData, PxQueryFilterCallback* filterCall, const PxQueryCache* cache, const PxReal inflation) { overflow = false; blockingHitShapeIndex = -1; for (PxU32 i = 0; i < hitBufferSize; i++) hitShapeIndices[i] = 0xFFFFffff; PxI32 sumNbResults = 0; PxU32 nbShapes = body.getNbShapes(); PxF32 shrunkMaxDistance = distance; for(PxU32 i=0; i < nbShapes; i++) { PxShape* shape = NULL; body.getShapes(&shape, 1, i); PX_ASSERT(shape != NULL); PxTransform pose = PxShapeExt::getGlobalPose(*shape, body); PxQueryFilterData fd; fd.flags = filterData.flags; PxU32 or4 = (filterData.data.word0 | filterData.data.word1 | filterData.data.word2 | filterData.data.word3); fd.data = or4 ? filterData.data : shape->getSimulationFilterData(); PxGeometryHolder anyGeom = shape->getGeometry(); PxU32 bufSizeLeft = hitBufferSize-sumNbResults; PxSweepHit extraHit; PxSweepBuffer buffer(bufSizeLeft == 0 ? &extraHit : hitBuffer+sumNbResults, bufSizeLeft == 0 ? 1 : hitBufferSize-sumNbResults); scene.sweep(anyGeom.any(), pose, unitDir, shrunkMaxDistance, buffer, outputFlags, fd, filterCall, cache, inflation); // Check and abort on overflow. Assume overflow if result count is bufSize. PxU32 nbNewResults = buffer.getNbTouches(); overflow |= (nbNewResults >= bufSizeLeft); if (bufSizeLeft == 0) // this is for when we used the extraHit buffer nbNewResults = 0; // set hitShapeIndices for each new non-blocking hit for (PxU32 j = 0; j < nbNewResults; j++) if (sumNbResults + PxU32(j) < hitBufferSize) hitShapeIndices[sumNbResults+j] = i; if (buffer.hasBlock) // there's a blocking hit in the most recent sweepMultiple results { // overwrite the return result blocking hit with the new blocking hit if under if (blockingHitShapeIndex == -1 || buffer.block.distance < block.distance) { blockingHitShapeIndex = (PxI32)i; block = buffer.block; } // Remove all the old touching hits below the new maxDist // sumNbResults is not updated yet at this point // and represents the count accumulated so far excluding the very last query PxI32 nbNewResultsSigned = PxI32(nbNewResults); // need a signed version, see nbNewResultsSigned-- below for (PxI32 j = sumNbResults-1; j >= 0; j--) // iterate over "old" hits (up to shapeIndex-1) if (buffer.block.distance < hitBuffer[j].distance) { // overwrite with last "new" hit PxI32 sourceIndex = PxI32(sumNbResults)+nbNewResultsSigned-1; PX_ASSERT(sourceIndex >= j); hitBuffer[j] = hitBuffer[sourceIndex]; hitShapeIndices[j] = hitShapeIndices[sourceIndex]; nbNewResultsSigned--; // can get negative, that means we are shifting the last results array } sumNbResults += nbNewResultsSigned; } else // if there was no new blocking hit we don't need to do anything special, simply append all results to touch array sumNbResults += nbNewResults; PX_ASSERT(sumNbResults >= 0 && sumNbResults <= PxI32(hitBufferSize)); } return (PxU32)sumNbResults; }