void GodotRayWorldAlgorithm::processCollision(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, const btDispatcherInfo &dispatchInfo, btManifoldResult *resultOut) { if (!m_manifoldPtr) { if (m_isSwapped) { m_manifoldPtr = m_dispatcher->getNewManifold(body1Wrap->getCollisionObject(), body0Wrap->getCollisionObject()); } else { m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(), body1Wrap->getCollisionObject()); } m_ownManifold = true; } m_manifoldPtr->clearManifold(); resultOut->setPersistentManifold(m_manifoldPtr); const btRayShape *ray_shape; btTransform ray_transform; const btCollisionObjectWrapper *other_co_wrapper; if (m_isSwapped) { ray_shape = static_cast<const btRayShape *>(body1Wrap->getCollisionShape()); ray_transform = body1Wrap->getWorldTransform(); other_co_wrapper = body0Wrap; } else { ray_shape = static_cast<const btRayShape *>(body0Wrap->getCollisionShape()); ray_transform = body0Wrap->getWorldTransform(); other_co_wrapper = body1Wrap; } btTransform to(ray_transform * ray_shape->getSupportPoint()); btCollisionWorld::ClosestRayResultCallback btResult(ray_transform.getOrigin(), to.getOrigin()); m_world->rayTestSingleInternal(ray_transform, to, other_co_wrapper, btResult); if (btResult.hasHit()) { btScalar depth(ray_shape->getScaledLength() * (btResult.m_closestHitFraction - 1)); if (depth > -RAY_PENETRATION_DEPTH_EPSILON) depth = 0.0; if (ray_shape->getSlipsOnSlope()) resultOut->addContactPoint(btResult.m_hitNormalWorld, btResult.m_hitPointWorld, depth); else { resultOut->addContactPoint((ray_transform.getOrigin() - to.getOrigin()).normalize(), btResult.m_hitPointWorld, depth); } } }
bool Physics3DWorld::rayCast(const cocos2d::Vec3& startPos, const cocos2d::Vec3& endPos, Physics3DWorld::HitResult* result) { auto btStart = convertVec3TobtVector3(startPos); auto btEnd = convertVec3TobtVector3(endPos); btCollisionWorld::ClosestRayResultCallback btResult(btStart, btEnd); _btPhyiscsWorld->rayTest(btStart, btEnd, btResult); if (btResult.hasHit()) { result->hitObj = getPhysicsObject(btResult.m_collisionObject); result->hitPosition = convertbtVector3ToVec3(btResult.m_hitPointWorld); result->hitNormal = convertbtVector3ToVec3(btResult.m_hitNormalWorld); return true; } result->hitObj = nullptr; return false; }
bool Physics3DWorld::sweepShape(Physics3DShape* shape, const cocos2d::Mat4& startTransform, const cocos2d::Mat4& endTransform, Physics3DWorld::HitResult* result) { CC_ASSERT(shape->getShapeType() != Physics3DShape::ShapeType::HEIGHT_FIELD && shape->getShapeType() != Physics3DShape::ShapeType::MESH); auto btStart = convertMat4TobtTransform(startTransform); auto btEnd = convertMat4TobtTransform(endTransform); btCollisionWorld::ClosestConvexResultCallback btResult(btStart.getOrigin(), btEnd.getOrigin()); _btPhyiscsWorld->convexSweepTest((btConvexShape*)shape->getbtShape(), btStart, btEnd, btResult); if (btResult.hasHit()) { result->hitObj = getPhysicsObject(btResult.m_hitCollisionObject); result->hitPosition = convertbtVector3ToVec3(btResult.m_hitPointWorld); result->hitNormal = convertbtVector3ToVec3(btResult.m_hitNormalWorld); return true; } result->hitObj = nullptr; return false; }