| 210 | } |
| 211 | |
| 212 | static bool doRaycastCCD(PxScene* scene, const RaycastCCDManagerInternal::CCDObject& object, PxTransform& newPose, PxVec3& newShapeCenter, bool dyna_dyna) |
| 213 | { |
| 214 | PxRigidDynamic* dyna = canDoCCD(*object.mActor, object.mShape); |
| 215 | if(!dyna) |
| 216 | return true; |
| 217 | |
| 218 | bool updateCCDWitness = true; |
| 219 | |
| 220 | const PxVec3 offset = newPose.p - newShapeCenter; |
| 221 | const PxVec3& origin = object.mWitness; |
| 222 | const PxVec3& dest = newShapeCenter; |
| 223 | |
| 224 | PxVec3 dir = dest - origin; |
| 225 | const PxReal length = dir.magnitude(); |
| 226 | if(length!=0.0f) |
| 227 | { |
| 228 | dir /= length; |
| 229 | |
| 230 | const PxReal internalRadius = computeInternalRadius(object.mActor, object.mShape, dir); |
| 231 | |
| 232 | PxRaycastHit hit; |
| 233 | if(internalRadius!=0.0f && CCDRaycast(scene, object.mActor, object.mShape, origin, dir, length, hit, dyna_dyna)) |
| 234 | { |
| 235 | updateCCDWitness = false; |
| 236 | |
| 237 | const PxReal radiusLimit = internalRadius * 0.75f; |
| 238 | if(hit.distance>radiusLimit) |
| 239 | { |
| 240 | newShapeCenter = origin + dir * (hit.distance - radiusLimit); |
| 241 | } |
| 242 | else |
| 243 | { |
| 244 | if(hit.actor->getConcreteType()==PxConcreteType::eRIGID_DYNAMIC) |
| 245 | return true; |
| 246 | |
| 247 | newShapeCenter = origin; |
| 248 | } |
| 249 | |
| 250 | newPose.p = offset + newShapeCenter; |
| 251 | const PxTransform shapeLocalPose = object.mShape->getLocalPose(); |
| 252 | const PxTransform inverseShapeLocalPose = shapeLocalPose.getInverse(); |
| 253 | const PxTransform newGlobalPose = newPose * inverseShapeLocalPose; |
| 254 | dyna->setGlobalPose(newGlobalPose); |
| 255 | } |
| 256 | } |
| 257 | return updateCCDWitness; |
| 258 | } |
| 259 | |
| 260 | bool RaycastCCDManagerInternal::registerRaycastCCDObject(PxRigidDynamic* actor, PxShape* shape) |
| 261 | { |
no test coverage detected