Exemplo n.º 1
0
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;
}