| 189 | struct GeomQueryAny |
| 190 | { |
| 191 | static PX_FORCE_INLINE PxU32 geomHit( |
| 192 | const NpSceneQueries& sceneQueries, const MultiQueryInput& input, const ShapeData& sd, |
| 193 | const PxGeometry& sceneGeom, const PxTransform& pose, PxHitFlags hitFlags, |
| 194 | PxU32 maxHits, HitType* hits, const PxReal shrunkMaxDistance, PxBounds3* precomputedBounds) |
| 195 | { |
| 196 | const PxGeometry& geom0 = *input.geometry; |
| 197 | const PxTransform& pose0 = *input.pose; |
| 198 | const PxGeometry& geom1 = sceneGeom; |
| 199 | const PxTransform& pose1 = pose; |
| 200 | |
| 201 | // Handle raycasts |
| 202 | if(HitTypeSupport<HitType>::IsRaycast) |
| 203 | { |
| 204 | // the test for mesh AABB is archived in //sw/physx/dev/apokrovsky/graveyard/sqMeshAABBTest.cpp |
| 205 | // TODO: investigate performance impact (see US12801) |
| 206 | PX_CHECK_AND_RETURN_VAL(input.getDir().isFinite(), "PxScene::raycast(): rayDir is not valid.", 0); |
| 207 | PX_CHECK_AND_RETURN_VAL(input.getOrigin().isFinite(), "PxScene::raycast(): rayOrigin is not valid.", 0); |
| 208 | PX_CHECK_AND_RETURN_VAL(pose1.isValid(), "PxScene::raycast(): pose is not valid.", 0); |
| 209 | PX_CHECK_AND_RETURN_VAL(shrunkMaxDistance >= 0.0f, "PxScene::raycast(): maxDist is negative.", 0); |
| 210 | PX_CHECK_AND_RETURN_VAL(PxIsFinite(shrunkMaxDistance), "PxScene::raycast(): maxDist is not valid.", 0); |
| 211 | PX_CHECK_AND_RETURN_VAL(PxAbs(input.getDir().magnitudeSquared()-1)<1e-4f, |
| 212 | "PxScene::raycast(): ray direction must be unit vector.", 0); |
| 213 | |
| 214 | // PT: TODO: investigate perf difference |
| 215 | const RaycastFunc func = sceneQueries.mCachedRaycastFuncs[geom1.getType()]; |
| 216 | return func(geom1, pose1, input.getOrigin(), input.getDir(), shrunkMaxDistance, |
| 217 | hitFlags, maxHits, reinterpret_cast<PxRaycastHit*>(hits)); |
| 218 | } |
| 219 | // Handle sweeps |
| 220 | else if(HitTypeSupport<HitType>::IsSweep) |
| 221 | { |
| 222 | PX_ASSERT(precomputedBounds != NULL); |
| 223 | // b0 = query shape bounds |
| 224 | // b1 = scene shape bounds |
| 225 | // AP: Here we clip the sweep to bounds with sum of extents. This is needed for GJK stability. |
| 226 | // because sweep is equivalent to a raycast vs a scene shape with inflated bounds. |
| 227 | // This also may (or may not) provide an optimization for meshes because top level of rtree has multiple boxes |
| 228 | // and there is no bounds test for the whole mesh elsewhere |
| 229 | PxBounds3 b0 = *precomputedBounds, b1; |
| 230 | // compute the scene geometry bounds |
| 231 | // PT: TODO: avoid recomputing the bounds here |
| 232 | Gu::computeBounds(b1, sceneGeom, pose, 0.0f, NULL, 1.0f); |
| 233 | const PxVec3 combExt = (b0.getExtents() + b1.getExtents())*1.01f; |
| 234 | |
| 235 | PxF32 tnear, tfar; |
| 236 | if(!intersectRayAABB2(-combExt, combExt, b0.getCenter() - b1.getCenter(), input.getDir(), shrunkMaxDistance, tnear, tfar)) // returns (tnear<tfar) |
| 237 | if(tnear>tfar) // this second test is needed because shrunkMaxDistance can be 0 for 0 length sweep |
| 238 | return 0; |
| 239 | PX_ASSERT(input.getDir().isNormalized()); |
| 240 | // tfar is now the t where the ray exits the AABB. input.getDir() is normalized |
| 241 | |
| 242 | const PxVec3& unitDir = input.getDir(); |
| 243 | PxSweepHit& sweepHit = reinterpret_cast<PxSweepHit&>(hits[0]); |
| 244 | |
| 245 | // if we don't start inside the AABB box, offset the start pos, because of precision issues with large maxDist |
| 246 | const bool offsetPos = (tnear > GU_RAY_SURFACE_OFFSET); |
| 247 | const PxReal offset = offsetPos ? (tnear - GU_RAY_SURFACE_OFFSET) : 0.0f; |
| 248 | const PxVec3 offsetVec(offsetPos ? (unitDir*offset) : PxVec3(0.0f)); |
nothing calls this directly
no test coverage detected