bool Gu::checkOverlapOBB_sphereGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Box& box) { PX_ASSERT(geom.getType() == PxGeometryType::eSPHERE); const PxSphereGeometry& sphereGeom = static_cast<const PxSphereGeometry&>(geom); return intersectSphereBox(Gu::Sphere(pose.p, sphereGeom.radius), box); }
static void writeGeom(BatchQueryStream& stream, const PxGeometry& geom) { PxGeometryType::Enum geomType = geom.getType(); stream.write<PxU32>(PxU32(geomType)); switch (geomType) { case PxGeometryType::eCAPSULE: stream.write<PxCapsuleGeometry>(static_cast<const PxCapsuleGeometry&>(geom)); break; case PxGeometryType::eSPHERE: stream.write<PxSphereGeometry>(static_cast<const PxSphereGeometry&>(geom)); break; case PxGeometryType::eCONVEXMESH: stream.write<PxConvexMeshGeometry>(static_cast<const PxConvexMeshGeometry&>(geom)); break; case PxGeometryType::eBOX: stream.write<PxBoxGeometry>(static_cast<const PxBoxGeometry&>(geom)); break; case PxGeometryType::ePLANE: case PxGeometryType::eTRIANGLEMESH: case PxGeometryType::eHEIGHTFIELD: case PxGeometryType::eGEOMETRY_COUNT: case PxGeometryType::eINVALID: PX_ALWAYS_ASSERT_MESSAGE("Unsupported geometry type in writeGeom"); } }
// PT: TODO: optimize all these data copies void Gu::GeometryUnion::set(const PxGeometry& g) { switch(g.getType()) { case PxGeometryType::eBOX: { reinterpret_cast<PxBoxGeometry&>(mGeometry) = static_cast<const PxBoxGeometry&>(g); } break; case PxGeometryType::eCAPSULE: { reinterpret_cast<PxCapsuleGeometry&>(mGeometry) = static_cast<const PxCapsuleGeometry&>(g); } break; case PxGeometryType::eSPHERE: { reinterpret_cast<PxSphereGeometry&>(mGeometry) = static_cast<const PxSphereGeometry&>(g); reinterpret_cast<PxCapsuleGeometry&>(mGeometry).halfHeight = 0.0f; //AM: make sphere geometry also castable as a zero height capsule. } break; case PxGeometryType::ePLANE: { reinterpret_cast<PxPlaneGeometry&>(mGeometry) = static_cast<const PxPlaneGeometry&>(g); } break; case PxGeometryType::eCONVEXMESH: { reinterpret_cast<PxConvexMeshGeometry&>(mGeometry) = static_cast<const PxConvexMeshGeometry&>(g); reinterpret_cast<PxConvexMeshGeometryLL&>(mGeometry).hullData = &(::getConvexMesh(get<PxConvexMeshGeometryLL>().convexMesh).getHull()); reinterpret_cast<PxConvexMeshGeometryLL&>(mGeometry).gpuCompatible = ::getConvexMesh(get<PxConvexMeshGeometryLL>().convexMesh).isGpuCompatible(); } break; case PxGeometryType::eTRIANGLEMESH: { reinterpret_cast<PxTriangleMeshGeometry&>(mGeometry) = static_cast<const PxTriangleMeshGeometry&>(g); reinterpret_cast<PxTriangleMeshGeometryLL&>(mGeometry).meshData = &(::getTriangleMesh(get<PxTriangleMeshGeometryLL>().triangleMesh)); reinterpret_cast<PxTriangleMeshGeometryLL&>(mGeometry).materialIndices = (::getTriangleMesh(get<PxTriangleMeshGeometryLL>().triangleMesh).getMaterials()); reinterpret_cast<PxTriangleMeshGeometryLL&>(mGeometry).materials = MaterialIndicesStruct(); } break; case PxGeometryType::eHEIGHTFIELD: { reinterpret_cast<PxHeightFieldGeometry&>(mGeometry) = static_cast<const PxHeightFieldGeometry&>(g); reinterpret_cast<PxHeightFieldGeometryLL&>(mGeometry).heightFieldData = &::getHeightField(get<PxHeightFieldGeometryLL>().heightField).getData(); reinterpret_cast<PxHeightFieldGeometryLL&>(mGeometry).materials = MaterialIndicesStruct(); } break; case PxGeometryType::eGEOMETRY_COUNT: case PxGeometryType::eINVALID: PX_ALWAYS_ASSERT_MESSAGE("geometry type not handled"); break; } }
bool Gu::checkOverlapCapsule_sphereGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Capsule& worldCapsule) { PX_ASSERT(geom.getType() == PxGeometryType::eSPHERE); const PxSphereGeometry& sphereGeom = static_cast<const PxSphereGeometry&>(geom); return intersectSphereCapsule(Gu::Sphere(pose.p, sphereGeom.radius), worldCapsule); }
void RenderPhysX3Debug::addGeometry(const PxGeometry& geom, const PxTransform& tr, const RendererColor& color, PxU32 renderFlags) { switch(geom.getType()) { case PxGeometryType::eBOX: { addBox(static_cast<const PxBoxGeometry&>(geom), tr, color, renderFlags); } break; case PxGeometryType::eSPHERE: { addSphere(static_cast<const PxSphereGeometry&>(geom), tr, color, renderFlags); } break; case PxGeometryType::eCAPSULE: { addCapsule(static_cast<const PxCapsuleGeometry&>(geom), tr, color, renderFlags); } break; case PxGeometryType::eCONVEXMESH: { addConvex(static_cast<const PxConvexMeshGeometry&>(geom), tr, color, renderFlags); } break; case PxGeometryType::ePLANE: case PxGeometryType::eTRIANGLEMESH: case PxGeometryType::eHEIGHTFIELD: default: { PX_ASSERT(!"Not supported!"); break; } } }
bool Gu::GeometryQuery::sweep(const PxVec3& unitDir, const PxReal distance, const PxGeometry& geom, const PxTransform& pose, PxU32 triangleCount, const Gu::Triangle* triangles, PxSweepHit& sweepHit, PxSceneQueryFlags hintFlags, const PxU32* triangleFlags, const Gu::Triangle* triangleEdgeNormals, const PxU32* cachedIndex) { PX_CHECK_VALID(pose.p); PX_CHECK_VALID(pose.q); PX_CHECK_VALID(unitDir); PX_CHECK_VALID(distance); PX_CHECK_AND_RETURN_VAL(distance > 0, "PxGeometryQuery::sweep(): sweep distance must be greater than 0.", false); switch (geom.getType()) { case PxGeometryType::eSPHERE : { const PxSphereGeometry& sphereGeom = static_cast<const PxSphereGeometry&>(geom); PxCapsuleGeometry capsuleGeom; capsuleGeom.radius = sphereGeom.radius; capsuleGeom.halfHeight = 0.0f; return Gu::SweepCapsuleTriangles( triangleCount, triangles, triangleFlags, capsuleGeom, pose, unitDir, distance, cachedIndex, sweepHit.impact, sweepHit.normal, sweepHit.distance, sweepHit.faceIndex); } break; case PxGeometryType::eCAPSULE : { const PxCapsuleGeometry& capsGeom = static_cast<const PxCapsuleGeometry&>(geom); return Gu::SweepCapsuleTriangles( triangleCount, triangles, triangleFlags, capsGeom, pose, unitDir, distance, cachedIndex, sweepHit.impact, sweepHit.normal, sweepHit.distance, sweepHit.faceIndex); } break; case PxGeometryType::eBOX : { const PxBoxGeometry& boxGeom = static_cast<const PxBoxGeometry&>(geom); return Gu::SweepBoxTriangles( triangleCount, triangles, triangleEdgeNormals, triangleFlags, boxGeom, pose, unitDir, distance, sweepHit.impact, sweepHit.normal, sweepHit.distance, sweepHit.faceIndex, cachedIndex); } break; default : PX_CHECK_AND_RETURN_VAL(false, "PxGeometryQuery::sweep(): geometry object parameter must be sphere, capsule or box geometry.", false); break; } return false; }
bool Gu::checkOverlapCapsule_planeGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Capsule& worldCapsule) { PX_ASSERT(geom.getType() == PxGeometryType::ePLANE); PX_UNUSED(geom); // const PxPlaneGeometry& planeGeom = static_cast<const PxPlaneGeometry&>(geom); const PxPlane plane = getPlane(pose); return intersectPlaneCapsule(worldCapsule, plane); }
bool Gu::checkOverlapOBB_boxGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Box& box) { PX_ASSERT(geom.getType() == PxGeometryType::eBOX); const PxBoxGeometry& boxGeom = static_cast<const PxBoxGeometry&>(geom); return Gu::intersectOBBOBB( boxGeom.halfExtents, pose.p, PxMat33(pose.q), box.extents, box.center, box.rot, true); }
bool Gu::checkOverlapSphere_capsuleGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Sphere& sphere) { PX_ASSERT(geom.getType() == PxGeometryType::eCAPSULE); const PxCapsuleGeometry& capsuleGeom = static_cast<const PxCapsuleGeometry&>(geom); Gu::Capsule capsule; getCapsule(capsule, capsuleGeom, pose); return intersectSphereCapsule(sphere, capsule); }
bool Gu::checkOverlapSphere_planeGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Sphere& sphere) { PX_ASSERT(geom.getType() == PxGeometryType::ePLANE); PX_UNUSED(geom); // const PxPlaneGeometry& planeGeom = static_cast<const PxPlaneGeometry&>(geom); const PxPlane plane = getPlane(pose); return plane.distance(sphere.center) - sphere.radius <= 0.0f; }
bool Gu::checkOverlapSphere_boxGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Sphere& sphere) { PX_ASSERT(geom.getType() == PxGeometryType::eBOX); const PxBoxGeometry& boxGeom = static_cast<const PxBoxGeometry&>(geom); Gu::Box obb; buildFrom(obb, pose.p, boxGeom.halfExtents, pose.q); return intersectSphereBox(sphere, obb); }
bool Gu::checkOverlapOBB_planeGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Box& box) { PX_ASSERT(geom.getType() == PxGeometryType::ePLANE); PX_UNUSED(geom); // const PxPlaneGeometry& planeGeom = static_cast<const PxPlaneGeometry&>(geom); const PxPlane plane = getPlane(pose); return intersectPlaneBox(plane, box); }
bool Gu::checkOverlapCapsule_boxGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Capsule& worldCapsule) { PX_ASSERT(geom.getType() == PxGeometryType::eBOX); const PxBoxGeometry& boxGeom = static_cast<const PxBoxGeometry&>(geom); Gu::Box box; buildFrom(box, pose.p, boxGeom.halfExtents, pose.q); return intersectBoxCapsule(box, worldCapsule); }
bool Gu::checkOverlapOBB_capsuleGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Box& box) { PX_ASSERT(geom.getType() == PxGeometryType::eCAPSULE); const PxCapsuleGeometry& capsuleGeom = static_cast<const PxCapsuleGeometry&>(geom); Gu::Capsule capsule; getCapsule(capsule, capsuleGeom, pose); return intersectBoxCapsule(box, capsule); }
void PhysXMeshCollider::setGeometry(const PxGeometry& geometry) { PxShape* shape = getInternal()->_getShape(); if (shape->getGeometryType() != geometry.getType()) { PxShape* newShape = gPhysX().getPhysX()->createShape(geometry, *gPhysX().getDefaultMaterial(), true); getInternal()->_setShape(newShape); } else getInternal()->_getShape()->setGeometry(geometry); }
PxU32 physx::PxMeshQuery::findOverlapTriangleMesh( const PxGeometry& geom, const PxTransform& geomPose, const PxTriangleMeshGeometry& meshGeom, const PxTransform& meshPose, PxU32* results, PxU32 maxResults, PxU32 startIndex, bool& overflow) { PX_SIMD_GUARD; switch(geom.getType()) { case PxGeometryType::eBOX: { const PxBoxGeometry& boxGeom = static_cast<const PxBoxGeometry&>(geom); Box box; buildFrom(box, geomPose.p, boxGeom.halfExtents, geomPose.q); TriangleMesh* tm = static_cast<TriangleMesh*>(meshGeom.triangleMesh); return findOverlapOBBMesh(box, tm->getCollisionModel(), meshPose, meshGeom.scale, results, maxResults, startIndex, overflow); } case PxGeometryType::eCAPSULE: { const PxCapsuleGeometry& capsGeom = static_cast<const PxCapsuleGeometry&>(geom); Capsule capsule; getCapsule(capsule, capsGeom, geomPose); TriangleMesh* tm = static_cast<TriangleMesh*>(meshGeom.triangleMesh); return findOverlapCapsuleMesh( capsule, tm->getCollisionModel(), meshPose, meshGeom.scale, results, maxResults, startIndex, overflow); } case PxGeometryType::eSPHERE: { const PxSphereGeometry& sphereGeom = static_cast<const PxSphereGeometry&>(geom); TriangleMesh* tm = static_cast<TriangleMesh*>(meshGeom.triangleMesh); return findOverlapSphereMesh(Sphere(geomPose.p, sphereGeom.radius), tm->getCollisionModel(), meshPose, meshGeom.scale, results, maxResults, startIndex, overflow); } case PxGeometryType::ePLANE: case PxGeometryType::eCONVEXMESH: case PxGeometryType::eTRIANGLEMESH: case PxGeometryType::eHEIGHTFIELD: case PxGeometryType::eGEOMETRY_COUNT: case PxGeometryType::eINVALID: default: { overflow = false; PX_CHECK_MSG(false, "findOverlapTriangleMesh: Only box, capsule and sphere geometries are supported."); return false; } } }
bool Gu::checkOverlapCapsule_capsuleGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Capsule& worldCapsule) { PX_ASSERT(geom.getType() == PxGeometryType::eCAPSULE); const PxCapsuleGeometry& capsuleGeom = static_cast<const PxCapsuleGeometry&>(geom); Gu::Capsule thisWorldCapsule; getCapsule(thisWorldCapsule, capsuleGeom, pose); PxReal s,t; PxReal squareDist = Gu::distanceSegmentSegmentSquared(thisWorldCapsule, worldCapsule, &s, &t); PxReal totRad = thisWorldCapsule.radius + worldCapsule.radius; return squareDist <= totRad*totRad; // PT: objects are defined as closed, so we return 'true' in case of equality }
static bool FindOverlappedTriangleNormal(const UWorld* World, const PxGeometry& Geom, const PxTransform& QueryTM, const PxShape* PShape, const PxTransform& PShapeWorldPose, FVector& OutNormal, float Inflation, bool bCanDrawOverlaps = false) { bool bSuccess = false; if (CanFindOverlappedTriangle(PShape)) { if (Inflation <= 0.f) { bSuccess = FindOverlappedTriangleNormal_Internal(World, Geom, QueryTM, PShape, PShapeWorldPose, OutNormal, bCanDrawOverlaps); } else { // Try a slightly inflated test if possible. switch (Geom.getType()) { case PxGeometryType::eCAPSULE: { const PxCapsuleGeometry* InCapsule = static_cast<const PxCapsuleGeometry*>(&Geom); PxCapsuleGeometry InflatedCapsule(InCapsule->radius + Inflation, InCapsule->halfHeight); // don't inflate halfHeight, radius is added all around. bSuccess = FindOverlappedTriangleNormal_Internal(World, InflatedCapsule, QueryTM, PShape, PShapeWorldPose, OutNormal, bCanDrawOverlaps); break; } case PxGeometryType::eBOX: { const PxBoxGeometry* InBox = static_cast<const PxBoxGeometry*>(&Geom); PxBoxGeometry InflatedBox(InBox->halfExtents + PxVec3(Inflation)); bSuccess = FindOverlappedTriangleNormal_Internal(World, InflatedBox, QueryTM, PShape, PShapeWorldPose, OutNormal, bCanDrawOverlaps); break; } case PxGeometryType::eSPHERE: { const PxSphereGeometry* InSphere = static_cast<const PxSphereGeometry*>(&Geom); PxSphereGeometry InflatedSphere(InSphere->radius + Inflation); bSuccess = FindOverlappedTriangleNormal_Internal(World, InflatedSphere, QueryTM, PShape, PShapeWorldPose, OutNormal, bCanDrawOverlaps); break; } default: { // No inflation possible break; } } } } return bSuccess; }
PxU32 physx::Gu::MeshQuery::findOverlapTriangleMesh( const PxGeometry& geom0, const PxTransform& pose0, const PxTriangleMeshGeometry& geom1, const PxTransform& pose1, PxU32* results, PxU32 maxResults, PxU32 startIndex, bool& overflow) { switch(geom0.getType()) { case PxGeometryType::eBOX : { const PxBoxGeometry& boxGeom = static_cast<const PxBoxGeometry&>(geom0); Gu::Box box; buildFrom(box, pose0.p, boxGeom.halfExtents, pose0.q); Gu::TriangleMesh* tm = static_cast<Gu::TriangleMesh*>(geom1.triangleMesh); return Gu::findOverlapOBBMesh(box, tm->getOpcodeModel(), pose1, geom1.scale, results, maxResults, startIndex, overflow); } break; case PxGeometryType::eCAPSULE : { const PxCapsuleGeometry& capsGeom = static_cast<const PxCapsuleGeometry&>(geom0); Gu::Capsule worldCapsule; // PT: TODO: fix this wrong name Gu::getWorldCapsule(worldCapsule, capsGeom, pose0); Gu::TriangleMesh* tm = static_cast<Gu::TriangleMesh*>(geom1.triangleMesh); return Gu::findOverlapCapsuleMesh(worldCapsule, tm->getOpcodeModel(), pose1, geom1.scale, results, maxResults, startIndex, overflow); } break; case PxGeometryType::eSPHERE : { const PxSphereGeometry& sphereGeom = static_cast<const PxSphereGeometry&>(geom0); Gu::TriangleMesh* tm = static_cast<Gu::TriangleMesh*>(geom1.triangleMesh); return Gu::findOverlapSphereMesh(Gu::Sphere(pose0.p, sphereGeom.radius), tm->getOpcodeModel(), pose1, geom1.scale, results, maxResults, startIndex, overflow); } break; default : PX_CHECK_AND_RETURN_VAL(false, "findOverlapTriangleMesh: Only box, capsule and sphere geometries are supported.", false); break; } return 0; }
PxU32 physx::Gu::MeshQuery::findOverlapHeightField(const PxGeometry& geom0, const PxTransform& pose0, const PxHeightFieldGeometry& geom1, const PxTransform& pose1, PxU32* results, PxU32 maxResults, PxU32 startIndex, bool& overflow) { const PxTransform localPose0 = pose1.transformInv(pose0); switch(geom0.getType()) { case PxGeometryType::eBOX : { const PxBoxGeometry& boxGeom = static_cast<const PxBoxGeometry&>(geom0); const bool isAABB = ((localPose0.q.x == 0.0f) && (localPose0.q.y == 0.0f) && (localPose0.q.z == 0.0f)); PxBounds3 bounds; if (isAABB) bounds = PxBounds3::centerExtents(localPose0.p, boxGeom.halfExtents); else bounds = PxBounds3::poseExtent(localPose0, boxGeom.halfExtents); // box.halfExtents is really extent Gu::HeightFieldUtil hfUtil(geom1); HfTrianglesEntityReport2 entityReport(results, maxResults, startIndex, hfUtil, localPose0.p, boxGeom.halfExtents, localPose0.q, isAABB); // PT: TODO: add a helper to expose this number? /* const PxU32 maxNbOverlapRows = static_cast<PxU32>( Ps::ceil(((bounds.getDimensions().x * (1.0f / geom1.rowScale)) + 1.0f)) ); const PxU32 maxNbOverlapCols = static_cast<PxU32>( Ps::ceil(((bounds.getDimensions().z * (1.0f / geom1.columnScale)) + 1.0f)) ); PxU32 maxNbTriangles = (maxNbOverlapCols * maxNbOverlapRows) << 1; // maximum number of height field triangles overlapping the local AABB maxNbTriangles = PxMax(maxNbTriangles, (PxU32)8); // No matter how small the AABB is, it can always have its center at the shared point of 4 cells*/ hfUtil.overlapAABBTriangles(pose1, bounds, 0, &entityReport); overflow = entityReport.mOverflow; return entityReport.mNbResults; } break; case PxGeometryType::eCAPSULE : case PxGeometryType::eSPHERE : default : PX_CHECK_AND_RETURN_VAL(false, "findOverlapHeightField: Only box queries are supported.", false); break; } return 0; }
void PvdSceneQueryCollector::overlapMultiple(const PxGeometry& geometry, const PxTransform& pose, const PxOverlapHit* hit, PxU32 hitsNum, const PxQueryFilterData& fd) { Ps::Mutex::ScopedLock lock(mMutex); PvdOverlap overlapQuery; pushBackT(mGeometries[mInUse], PxGeometryHolder(geometry), overlapQuery.mGeometries, getArrayName(mGeometries[mInUse])); // PT: TODO: optimize this. We memcopy once to the stack, then again to the array.... const PxGeometryType::Enum type = geometry.getType(); if(type==PxGeometryType::eBOX) overlapQuery.mType = pose.q.isIdentity() ? QueryID::QUERY_OVERLAP_AABB_ALL_OBJECTS : QueryID::QUERY_OVERLAP_OBB_ALL_OBJECTS; else if(type==PxGeometryType::eSPHERE) overlapQuery.mType = QueryID::QUERY_OVERLAP_SPHERE_ALL_OBJECTS; else if(type==PxGeometryType::eCAPSULE) overlapQuery.mType = QueryID::QUERY_OVERLAP_CAPSULE_ALL_OBJECTS; else if(type==PxGeometryType::eCONVEXMESH) overlapQuery.mType = QueryID::QUERY_OVERLAP_CONVEX_ALL_OBJECTS; else PX_ASSERT(0); overlapQuery.mPose = pose; overlapQuery.mFilterData = fd.data; accumulate(overlapQuery, mAccumulatedOverlapQueries, getArrayName(mPvdSqHits), mPvdSqHits, hit, hitsNum, fd); }
bool Gu::checkOverlapSphere_convexGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Sphere& sphere) { PX_ASSERT(geom.getType() == PxGeometryType::eCONVEXMESH); const PxConvexMeshGeometry& cvGeom = static_cast<const PxConvexMeshGeometry&>(geom); GU_FETCH_CONVEX_DATA(cvGeom); // PT: TODO: why do we bother doing this first test? //TODO: Support scaling if(cvGeom.scale.isIdentity()) { // Test if sphere center is inside convex PxVec3 sphereCenter = pose.transformInv(sphere.center); if(convexHullContains(cm->getHull(), sphereCenter)) return true; } return intersectSphereConvex(sphere, *cm, cvGeom.scale, pose, NULL); }
bool Gu::checkOverlapOBB_convexGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Box& box) { PX_ASSERT(geom.getType() == PxGeometryType::eCONVEXMESH); const PxConvexMeshGeometry& cvGeom = static_cast<const PxConvexMeshGeometry&>(geom); GU_FETCH_CONVEX_DATA(cvGeom); // PT: TODO: why do we bother doing this first test? //TODO: Support scaling if(cvGeom.scale.isIdentity()) { const PxVec3 boxCenter = pose.transformInv(box.center); if(convexHullContains(cm->getHull(), boxCenter)) return true; } // PT: ### USELESS CONVERSION - PxBoxGeometry & PxTransform are not necessary here return intersectBoxConvex(PxBoxGeometry(box.extents), PxTransform(box.center, PxQuat(box.rot)), *cm, cvGeom.scale, pose, NULL); }
void PvdSceneQueryCollector::sweep(const PxGeometry& geometry, const PxTransform& pose, const PxVec3& unitDir, PxReal distance, const PxSweepHit* hit, PxU32 hitsNum, const PxQueryFilterData& fd, bool multipleHits) { Ps::Mutex::ScopedLock lock(mMutex); PvdSweep sweepQuery; pushBackT(mGeometries[mInUse], PxGeometryHolder(geometry), sweepQuery.mGeometries, getArrayName(mGeometries[mInUse])); // PT: TODO: optimize this. We memcopy once to the stack, then again to the array.... pushBackT(mPoses, pose, sweepQuery.mPoses, getArrayName(mPoses)); pushBackT(mFilterData, fd.data, sweepQuery.mFilterData, getArrayName(mFilterData)); const PxGeometryType::Enum type = geometry.getType(); // PT: TODO: QueryID::QUERY_LINEAR_xxx_SWEEP_ALL_OBJECTS are never used! if(type==PxGeometryType::eBOX) sweepQuery.mType = QueryID::QUERY_LINEAR_OBB_SWEEP_CLOSEST_OBJECT; else if(type==PxGeometryType::eSPHERE || type==PxGeometryType::eCAPSULE) sweepQuery.mType = QueryID::QUERY_LINEAR_CAPSULE_SWEEP_CLOSEST_OBJECT; else if(type==PxGeometryType::eCONVEXMESH) sweepQuery.mType = QueryID::QUERY_LINEAR_CONVEX_SWEEP_CLOSEST_OBJECT; else PX_ASSERT(0); sweepQuery.mUnitDir = unitDir; sweepQuery.mDistance = distance; clampNbHits(hitsNum, fd, multipleHits); accumulate(sweepQuery, mAccumulatedSweepQueries, getArrayName(mPvdSqHits), mPvdSqHits, hit, hitsNum, fd); }
float CEntity::getLogicPivotOffset(const PxGeometry& geometry) { switch( geometry.getType() ) { case PxGeometryType::eBOX: // Devolver la altura media de la caja return static_cast<const PxBoxGeometry*>(&geometry)->halfExtents.y; break; case PxGeometryType::eSPHERE: // Devolver el radio de la esfera return static_cast<const PxSphereGeometry*>(&geometry)->radius; break; case PxGeometryType::eCAPSULE: // Devolver el radio de la cupula mas la mitad de la altura return static_cast<const PxCapsuleGeometry*>(&geometry)->halfHeight; break; } return 0; }
void Gu::GeometryUnion::set(const PxGeometry& g) { switch(g.getType()) { case PxGeometryType::eBOX : reinterpret_cast<PxBoxGeometry&>(geometry) = static_cast<const PxBoxGeometry&>(g); break; case PxGeometryType::eCAPSULE : reinterpret_cast<PxCapsuleGeometry&>(geometry) = static_cast<const PxCapsuleGeometry&>(g); break; case PxGeometryType::eSPHERE : reinterpret_cast<PxSphereGeometry&>(geometry) = static_cast<const PxSphereGeometry&>(g); reinterpret_cast<PxCapsuleGeometry&>(geometry).halfHeight = 0.0f; //AM: make sphere geometry also castable as a zero height capsule. break; case PxGeometryType::ePLANE : reinterpret_cast<PxPlaneGeometry&>(geometry) = static_cast<const PxPlaneGeometry&>(g); break; case PxGeometryType::eCONVEXMESH : { reinterpret_cast<PxConvexMeshGeometry&>(geometry) = static_cast<const PxConvexMeshGeometry&>(g); reinterpret_cast<PxConvexMeshGeometryLL&>(geometry).hullData = &(Gu::getConvexMesh(get<PxConvexMeshGeometryLL>().convexMesh).getHull()); } break; case PxGeometryType::eTRIANGLEMESH : { reinterpret_cast<PxTriangleMeshGeometry&>(geometry) = static_cast<const PxTriangleMeshGeometry&>(g); reinterpret_cast<PxTriangleMeshGeometryLL&>(geometry).meshData = &(Gu::getTriangleMesh(get<PxTriangleMeshGeometryLL>().triangleMesh).mesh.mData); } break; case PxGeometryType::eHEIGHTFIELD : { reinterpret_cast<PxHeightFieldGeometry&>(geometry) = static_cast<const PxHeightFieldGeometry&>(g); reinterpret_cast<PxHeightFieldGeometryLL&>(geometry).heightFieldData = &Gu::getHeightField(get<PxHeightFieldGeometryLL>().heightField).getData(); } break; default : PX_ASSERT(0 && "geometry type not handled"); break; } }
bool sweepConvex_CapsuleGeom( const PxGeometry& geom, const PxTransform& pose, const PxConvexMeshGeometry& convexGeom, const PxTransform& convexPose, const PxVec3& unitDir, const PxReal distance, PxSweepHit& sweepHit, PxHitFlags hintFlags, const PxReal inflation) { PX_ASSERT(geom.getType() == PxGeometryType::eCAPSULE); const PxCapsuleGeometry& capsuleGeom = static_cast<const PxCapsuleGeometry&>(geom); Capsule capsule; getCapsule(capsule, capsuleGeom, pose); if(sweepCapsule_ConvexGeom(convexGeom, convexPose, capsule, -unitDir, distance, sweepHit, hintFlags, inflation)) { // do not write to position if it has not been set (initialOverlap) if (sweepHit.flags & PxHitFlag::ePOSITION) { sweepHit.position += unitDir * sweepHit.distance; } sweepHit.normal = -sweepHit.normal; sweepHit.faceIndex = 0xffffffff; return true; } return false; }
bool sweepConvex_BoxGeom( const PxGeometry& geom, const PxTransform& pose, const PxConvexMeshGeometry& convexGeom, const PxTransform& convexPose, const PxVec3& unitDir, const PxReal distance, PxSweepHit& sweepHit, PxHitFlags hintFlags, const PxReal inflation) { PX_ASSERT(geom.getType() == PxGeometryType::eBOX); const PxBoxGeometry& boxGeom = static_cast<const PxBoxGeometry&>(geom); Box box; buildFrom1(box, pose.p, boxGeom.halfExtents, pose.q); //pxPrintf("sweepConvex begin\n"); if(sweepBox_ConvexGeom(convexGeom, convexPose, box, -unitDir, distance, sweepHit, hintFlags, inflation)) { // do not write to position if it has not been set (initialOverlap) if (sweepHit.flags & PxHitFlag::ePOSITION) { sweepHit.position += unitDir * sweepHit.distance; } sweepHit.normal = -sweepHit.normal; sweepHit.faceIndex = 0xffffffff; return true; } return false; }
bool Gu::checkOverlapCapsule_convexGeom(const PxGeometry& geom, const PxTransform& pose, const Gu::Capsule& worldCapsule) { PX_ASSERT(geom.getType() == PxGeometryType::eCONVEXMESH); const PxConvexMeshGeometry& cvGeom = static_cast<const PxConvexMeshGeometry&>(geom); GU_FETCH_CONVEX_DATA(cvGeom); // PT: TODO: why do we bother doing this first test? //TODO: Support scaling if(cvGeom.scale.isIdentity()) { // Test if capsule center is inside convex PxVec3 capsuleCenter = (worldCapsule.p0 + worldCapsule.p1) * 0.5f; capsuleCenter = pose.transformInv(capsuleCenter); if(convexHullContains(cm->getHull(),capsuleCenter)) return true; } PxCapsuleGeometry cg; cg.radius = worldCapsule.radius; PxTransform capsuleTransform = getCapsuleTransform(worldCapsule, cg.halfHeight); return intersectCapsuleConvex(cg, capsuleTransform, *cm, cvGeom.scale, pose, NULL); }
bool Gu::GeometryQuery::overlap(const PxGeometry& geom0, const PxTransform& pose0, const PxGeometry& geom1, const PxTransform& pose1) { PX_CHECK_VALID(pose0.p); PX_CHECK_VALID(pose0.q); PX_CHECK_VALID(pose1.p); PX_CHECK_VALID(pose1.q); if(geom0.getType() > geom1.getType()) { Gu::GeomOverlapFunc overlapFunc = Gu::gGeomOverlapMethodTable[geom1.getType()][geom0.getType()]; PX_ASSERT(overlapFunc); return overlapFunc(geom1, pose1, geom0, pose0, NULL); } else { Gu::GeomOverlapFunc overlapFunc = Gu::gGeomOverlapMethodTable[geom0.getType()][geom1.getType()]; PX_ASSERT(overlapFunc); return overlapFunc(geom0, pose0, geom1, pose1, NULL); } }