//Modifica la dist. to target de la camara en el caso que esta colisione con alguna cosa
void CameraController3rd::placeByCollisionsPosition(float delta, btVector3& targetPos)
{
	btVector3 btRayFrom = _targetTransform->getOrigin();
	//posicion a la que deberia situarse la camra en condiciones normales
	btVector3 desiredPosition = targetPos - _current_dist_to_target * _front;
	btVector3 position, direction;

	//Creamos callback para obtener resultado de la colision
	btCollisionWorld::ClosestRayResultCallback rayCallback(btRayFrom,desiredPosition);
	rayCallback.m_collisionFilterMask = PhysicsSystem::get().colMaskNavigation; //Para no colisionar con la misma capsula del player
	PhysicsSystem::get().getCollisionWorld()->rayTest(btRayFrom,desiredPosition, rayCallback); //(Test de colision)

	//Si colisiona modificamos la desired dist de la camara
	if (rayCallback.hasHit())
	{
		position = rayCallback.m_hitPointWorld;
		direction = btRayFrom - position;
		position += direction * 0.3f; //************************************************** JUGAR UN POCO CON ESTE VALOR 
		//-->Sin normalizar se asegura que la linea anterior de como resultado un punto entre la desired_pos y el player

		_desiredDistance = (position-targetPos).length();
	}
	else _desiredDistance = _current_dist_to_target;
	
	_position = targetPos - _distance_to_target * _front;
}
示例#2
0
bool Context::closestRayCast( const ci::vec3 &startPosition, const ci::vec3 &direction, RayResult &result )
{
	if( ! world() )
		return false;
	
	btVector3 rayTo = toBullet( direction * 1000.0f );
	btVector3 rayFrom = toBullet( startPosition );
	
	btCollisionWorld::ClosestRayResultCallback rayCallback( rayFrom, rayTo );
	
	world()->rayTest( rayFrom, rayTo, rayCallback );
	
	if( rayCallback.hasHit() ) {
		
		btRigidBody* pBody = (btRigidBody*) btRigidBody::upcast( rayCallback.m_collisionObject );
		
		if(!pBody)
			return false;
		
		result.pBody = pBody;
		result.hitPoint = fromBullet( rayCallback.m_hitPointWorld );
		result.hitNormal = fromBullet( rayCallback.m_hitNormalWorld );
		
		return true;
	}
	
	return false;
}
//--------------------------------------------------------------
ofxBulletRaycastData ofxBulletWorldRigid::raycastTest( ofVec3f a_rayStart, ofVec3f a_rayEnd, short int a_filterMask) {
    ofxBulletRaycastData data;
    data.bHasHit = false;

    btVector3 rayStart( a_rayStart.x, a_rayStart.y, a_rayStart.z );
    btVector3 rayEnd( a_rayEnd.x, a_rayEnd.y, a_rayEnd.z );

    btCollisionWorld::ClosestRayResultCallback rayCallback( rayStart, rayEnd );
    rayCallback.m_collisionFilterMask = a_filterMask;
    world->rayTest( rayStart, rayEnd, rayCallback );

    if (rayCallback.hasHit()) {
        btRigidBody* body = btRigidBody::upcast( (btCollisionObject*)rayCallback.m_collisionObject );
        if (body) {
            data.bHasHit			= true;
            data.userData			= (ofxBulletUserData*)body->getUserPointer();
            data.body				= body;
            data.rayWorldPos		= a_rayEnd;
            btVector3 pickPos		= rayCallback.m_hitPointWorld;
            data.pickPosWorld		= ofVec3f(pickPos.getX(), pickPos.getY(), pickPos.getZ());
            btVector3 localPos		= body->getCenterOfMassTransform().inverse() * pickPos;
            data.localPivotPos		= ofVec3f(localPos.getX(), localPos.getY(), localPos.getZ() );
        }
    }
    return data;
}
示例#4
0
bool NavigationGraph::checkSpaceForNode(OgreBulletDynamics::DynamicsWorld* world, const Vector3& position) const
{
	const Vector3 offset[] = { 
		Vector3(0.0f, 0.0f, 0.0f), 
		Vector3(-NavigationNode::NODE_SIZE_HALF, 0.0f, 0.0f), 
		Vector3(NavigationNode::NODE_SIZE_HALF, 0.0f, 0.0f), 
		Vector3(0.0f, 0.0f, -NavigationNode::NODE_SIZE_HALF), 
		Vector3(0.0f, 0.0f, NavigationNode::NODE_SIZE_HALF) 
	};

	// send multiple rays to check if spot is free.
	for (int i = 0; i < 5; i++)
	{
		btVector3 start(position.x + offset[i].x, 100.0f, position.z + offset[i].z);
		btVector3 end(position.x + offset[i].x, 1.0f, position.z + offset[i].z);
			
		btCollisionWorld::ClosestRayResultCallback rayCallback(start, end);
 
		// Perform raycast
		world->getBulletCollisionWorld()->rayTest(start, end, rayCallback);
 
		if(rayCallback.hasHit()) 
		{
			return false;
		}
	}

	return true;
}
示例#5
0
PhysicsRaycastResult* PhysicsWorld::Raycast(const float3& origin, const float3& direction, float maxdistance, int collisiongroup, int collisionmask)
{
    PROFILE(PhysicsWorld_Raycast);
    
    static PhysicsRaycastResult result;
    
    float3 normalizedDir = direction.Normalized();
    
    btCollisionWorld::ClosestRayResultCallback rayCallback(origin, origin + maxdistance * normalizedDir);
    rayCallback.m_collisionFilterGroup = collisiongroup;
    rayCallback.m_collisionFilterMask = collisionmask;
    
    world_->rayTest(rayCallback.m_rayFromWorld, rayCallback.m_rayToWorld, rayCallback);
    
    result.entity = 0;
    result.distance = 0;
    
    if (rayCallback.hasHit())
    {
        result.pos = rayCallback.m_hitPointWorld;
        result.normal = rayCallback.m_hitNormalWorld;
        result.distance = (result.pos - origin).Length();
        if (rayCallback.m_collisionObject)
        {
            EC_RigidBody* body = static_cast<EC_RigidBody*>(rayCallback.m_collisionObject->getUserPointer());
            if (body)
                result.entity = body->ParentEntity();
        }
    }
    
    return &result;
}
示例#6
0
void PhysicsEngine::shootRay(const btVector3 &rayFromWorld, const btVector3 &rayToWorld, const btVector3& impulse)
{
	// Create a closest ray result callback
	btCollisionWorld::ClosestRayResultCallback rayCallback(rayFromWorld, rayToWorld);

	// Shoot a ray given a start and end position and fills in the ray callback
	mDynamicsWorld->rayTest(rayFromWorld, rayToWorld, rayCallback);
	
	// Check whether the ray hit anything
	if(rayCallback.hasHit())
	{
		// Get the object that the ray hit
		btRigidBody* body = const_cast<btRigidBody*>(btRigidBody::upcast(rayCallback.m_collisionObject));

		// If the rigid body exists
		if(body)
		{
			// Activate the object dynamics
			body->setActivationState(ACTIVE_TAG);

			// Compute the direction to apply the impulse
			btVector3 relPos = rayCallback.m_hitPointWorld - body->getCenterOfMassPosition();

			// Apply the impulse
			body->applyImpulse(impulse, relPos);
		}
	}
}
示例#7
0
void SpaceObject::fire_laser() {
	if(weapons[activeWeapon]->ammo<600)
		return;
	btTransform trans;
	body->getMotionState()->getWorldTransform(trans);
	btVector3 from = trans.getOrigin() + quatRotate(trans.getRotation() , btVector3(0,0,-10));
	std::cout << body->getOrientation().getX() << "," << body->getOrientation().getY() << "," << body->getOrientation().getZ() << "," << body->getOrientation().getW() << "\n";
	btVector3 to = from + quatRotate(trans.getRotation() , btVector3(0,0,-500));
		
	//Perform ray test.
	btCollisionWorld::ClosestRayResultCallback rayCallback( from, to );
	world->dynamicsWorld->rayTest(from,to,rayCallback);
	//get results.
	if ( rayCallback.hasHit() ) {
		to = rayCallback.m_hitPointWorld;
		// to = ((SpaceObject*)rayCallback.m_collisionObject->getUserPointer())->getRigidBody()->getCenterOfMassPosition();
		ship_hit = (SpaceObject*)rayCallback.m_collisionObject->getUserPointer();
		if(ship_hit->getType() != SKYRISE_TALL && ship_hit->getType()!= SKYRISE_FAT && ship_hit->getType()!= ENDPOINT)
			wasHit = true;
	} //else, do nothing.
	weapons[activeWeapon] -> fireProjectile(from,to);
	fireFrom = from;
	fireTo = to;
	fired = true;
}
示例#8
0
void ShotGun::shoot_hook()
{
    Ogre::Vector3 cam_dir = ((Camera*)(player->controller->fps_camera))->camera->getDirection();
    Ogre::Vector3 cam_pos = ((Camera*)(player->controller->fps_camera))->camera->getPosition();

    Ogre::Vector3 shoot_vector = shoot_pos->node->convertLocalToWorldPosition(shoot_pos->node->getPosition());

    btVector3 from = btVector3(cam_pos.x, cam_pos.y, cam_pos.z) + (btVector3(cam_dir.x, cam_dir.y, cam_dir.z) * shoot_from_offset);
    btVector3 pre_to = btVector3(cam_pos.x, cam_pos.y, cam_pos.z) + (btVector3(cam_dir.x, cam_dir.y, cam_dir.z) * shoot_distance);

    btVector3 to;

    for (int i = 0; i < SHOOT_NUM; ++i)
    {
        int rand_shoot_offset = 300;
        to = pre_to + btVector3(RAND_RANGE(0, rand_shoot_offset) - rand_shoot_offset, RAND_RANGE(0, rand_shoot_offset) - rand_shoot_offset, 
            RAND_RANGE(0, rand_shoot_offset) - rand_shoot_offset);

        btCollisionWorld::ClosestRayResultCallback rayCallback(from, to);

        rayCallback.m_collisionFilterGroup = COL_BULLET;
        rayCallback.m_collisionFilterMask = COL_BULLET_COLLIDER_WITH;

        Component::_gameObject->scene->physics_world->rayTest(from, to, rayCallback);
        if(rayCallback.hasHit())
        {
            btVector3 point = rayCallback.m_hitPointWorld;
            
            if(rayCallback.m_collisionObject->getUserPointer() != NULL)
            {
                HitBox* hit_box = (HitBox*)(rayCallback.m_collisionObject->getUserPointer());
                if(hit_box->player->player_id != NetworkManager::instance()->player_id
                    && ((GameState::instance()->team_mode != TEAM) || (hit_box->player->team_id != GameState::instance()->player->team_id)
                        || (GameState::instance()->game_mode == PINTO)))
                {
                    int damage_sent = hit_box->getDamage(damage);
                    uint32_t enemy_id = hit_box->player->player_id;

                    NetworkManager::instance()->vital->setDamage(damage_sent, enemy_id);
                    AudioManager::instance()->playBlootSplat(Ogre::Vector3(point.x(), point.y(), point.z()));
                    ParticleManager::instance()->EmitBloodSpurt(Ogre::Vector3(point.x(), point.y(), point.z()), -cam_dir);
                    NetworkManager::instance()->particle->setBlood(point.x(), point.y() , point.z(), -cam_dir.x, -cam_dir.y, -cam_dir.z);
                }
            }
            else
            {
                AudioManager::instance()->playBulletDirtCollision(Ogre::Vector3(point.x(), point.y(), point.z()));
                
                ParticleManager::instance()->EmitDust(Ogre::Vector3(point.x(), point.y(), point.z()), -cam_dir);

                NetworkManager::instance()->particle->setDust(point.x(), point.y() , point.z(), -cam_dir.x, -cam_dir.y, -cam_dir.z);
            }
        }
    }
}
示例#9
0
void duCharacter::castRays(btCollisionWorld* collisionWorld)
{
    const btVector3 forward = btVector3(0.f, -1.f, 0.f);
    const btVector3 down    = btVector3(0.f, 0.f, -1.f);

    btTransform xform = m_rigidBody->getWorldTransform();
    m_raySource = xform.getOrigin();

    // cast rays in forward and down directions
    m_rayTarget[0] = m_raySource + down * (m_halfHeight + m_maxStepHeight);
    m_rayTarget[1] = m_raySource + forward * m_halfHeight * btScalar(1.1);

    class ClosestNotMe : public btCollisionWorld::ClosestRayResultCallback
    {
    public:
        ClosestNotMe (btRigidBody* me, btScalar& collisionGroup, btScalar& collisionMask) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.f, 0.f, 0.f), btVector3(0.f, 0.f, 0.f))
        {
            m_me = me;
			m_collisionFilterGroup = collisionGroup;
			m_collisionFilterMask = collisionMask;
        }


        virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace)
        {
            if (rayResult.m_collisionObject == m_me)
                return 1.f;

            return ClosestRayResultCallback::addSingleResult (rayResult, normalInWorldSpace);
        }
    protected:
        btRigidBody* m_me;
    };

    ClosestNotMe rayCallback(m_rigidBody, m_collisionGroup, m_collisionMask);

    int i = 0;
    for (i = 0; i < 2; i++)
    {
        rayCallback.m_closestHitFraction = 1.f;
        collisionWorld->rayTest(m_raySource, m_rayTarget[i], rayCallback);
        if (rayCallback.hasHit())
        {
            m_rayLambda[i] = rayCallback.m_closestHitFraction;
        } else {
            m_rayLambda[i] = 1.f;
        }
    }

    if (m_water != NULL) {
        btScalar waterLevel = m_water->getWaterLevel(m_raySource[0],
                                                    -m_raySource[1], m_waterInd);
        m_distToWater = m_raySource[2] - waterLevel;
    }
}
void DynamicCharacterController::preSimulation(btScalar timeStep) {
    if (_enabled && _dynamicsWorld) {
        glm::quat rotation = _avatarData->getOrientation();

        // TODO: update gravity if up has changed
        updateUpAxis(rotation);

        glm::vec3 position = _avatarData->getPosition() + rotation * _shapeLocalOffset;
        _rigidBody->setWorldTransform(btTransform(glmToBullet(rotation), glmToBullet(position)));

        // the rotation is dictated by AvatarData
        btTransform xform = _rigidBody->getWorldTransform();
        xform.setRotation(glmToBullet(rotation));
        _rigidBody->setWorldTransform(xform);

        // scan for distant floor
        // rayStart is at center of bottom sphere
        btVector3 rayStart = xform.getOrigin() - _halfHeight * _currentUp;
    
        // rayEnd is straight down MAX_FALL_HEIGHT
        btScalar rayLength = _radius + MAX_FALL_HEIGHT;
        btVector3 rayEnd = rayStart - rayLength * _currentUp;
    
        ClosestNotMe rayCallback(_rigidBody);
        rayCallback.m_closestHitFraction = 1.0f;
        _dynamicsWorld->rayTest(rayStart, rayEnd, rayCallback);
        if (rayCallback.hasHit()) {
            _floorDistance = rayLength * rayCallback.m_closestHitFraction - _radius;
            const btScalar MIN_HOVER_HEIGHT = 3.0f;
            if (_isHovering && _floorDistance < MIN_HOVER_HEIGHT && !_isPushingUp) {
                setHovering(false);
            } 
            // TODO: use collision events rather than ray-trace test to disable jumping
            const btScalar JUMP_PROXIMITY_THRESHOLD = 0.1f * _radius;
            if (_floorDistance < JUMP_PROXIMITY_THRESHOLD) {
                _isJumping = false;
            }
        } else {
            _floorDistance = FLT_MAX;
            setHovering(true);
        }

        _walkVelocity = glmToBullet(_avatarData->getTargetVelocity());

        if (_pendingFlags & PENDING_FLAG_JUMP) {
            _pendingFlags &= ~ PENDING_FLAG_JUMP;
            if (onGround()) {
                _isJumping = true;
                btVector3 velocity = _rigidBody->getLinearVelocity();
                velocity += _jumpSpeed * _currentUp;
                _rigidBody->setLinearVelocity(velocity);
            }
        }
    }
}
void DynamicCharacterController::preStep (btCollisionWorld* collisionWorld)
{
	btTransform xform;
	m_rigidBody->getMotionState()->getWorldTransform (xform);
	btVector3 down = -xform.getBasis()[1];
	btVector3 forward = xform.getBasis()[2];
	down.normalize ();
	forward.normalize();

	m_raySource[0] = xform.getOrigin();
	m_raySource[1] = xform.getOrigin();

	m_rayTarget[0] = m_raySource[0] + down * m_halfHeight * btScalar(1.1);
	m_rayTarget[1] = m_raySource[1] + forward * m_halfHeight * btScalar(1.1);

	class ClosestNotMe : public btCollisionWorld::ClosestRayResultCallback
	{
	public:
		ClosestNotMe (btRigidBody* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0))
		{
			m_me = me;
		}

		virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace)
		{
			if (rayResult.m_collisionObject == m_me)
				return 1.0;

			return ClosestRayResultCallback::addSingleResult (rayResult, normalInWorldSpace
		);
	}
	protected:
		btRigidBody* m_me;
	};

	ClosestNotMe rayCallback(m_rigidBody);

	int i = 0;
	for (i = 0; i < 2; i++)
	{
		rayCallback.m_closestHitFraction = 1.0;
		collisionWorld->rayTest (m_raySource[i], m_rayTarget[i], rayCallback);
		if (rayCallback.hasHit())
		{
			m_rayLambda[i] = rayCallback.m_closestHitFraction;
		} else {
			m_rayLambda[i] = 1.0;
		}
	}
}
示例#12
0
void GrabberKinematicObject::grabNearestObjectAhead() {
    // first, try to find the object ahead.
    // trace a ray in the direction of the end affector and get the first object hit
    btTransform trans; motionState->getWorldTransform(trans);
    btVector3 rayFrom = trans(btVector3(0, 0, 0)); // some point in the middle of the stick
    btVector3 rayTo = trans(constraintPivot); // the end affector
    rayTo = (rayTo - rayFrom).normalize()*MAX_RAYCAST_DISTANCE + rayTo;

    printf("from: %f %f %f\nto:%f %f %f\n", rayFrom.x(), rayFrom.y(), rayFrom.z(), rayTo.x(), rayTo.y(), rayTo.z());
    // send the ray
    btCollisionWorld::ClosestRayResultCallback rayCallback(rayFrom, rayTo);
    getEnvironment()->bullet->dynamicsWorld->rayTest(rayFrom, rayTo, rayCallback);
    printf("tracing!\n");
    if (rayCallback.hasHit()) {
        printf("hit!\n");
        btRigidBody *hitBody = btRigidBody::upcast(rayCallback.m_collisionObject);
        if (hitBody && !hitBody->isStaticObject() && !hitBody->isKinematicObject()) {
            hitBody->setActivationState(DISABLE_DEACTIVATION);

            releaseConstraint();

            // the constraint in the grabber's coordinate system
            btTransform grabberFrame;
            grabberFrame.setIdentity();
            grabberFrame.setOrigin(constraintPivot);
            grabberFrame.setRotation(trans.inverse().getRotation());

            // the constraint in the target's coordinate system
            const btTransform &hitBodyTransInverse = hitBody->getCenterOfMassTransform().inverse();
            btVector3 localHitPoint = hitBodyTransInverse * rayCallback.m_hitPointWorld;
            btTransform hitFrame;
            hitFrame.setIdentity();
            hitFrame.setOrigin(localHitPoint);
            hitFrame.setRotation(hitBodyTransInverse.getRotation());

            constraint.reset(new btGeneric6DofConstraint(*rigidBody, *hitBody, grabberFrame, hitFrame, false));
            // make the constraint completely rigid
            constraint->setLinearLowerLimit(btVector3(0., 0., 0.));
            constraint->setLinearUpperLimit(btVector3(0., 0., 0.));
            constraint->setAngularLowerLimit(btVector3(0., 0., 0.));
            constraint->setAngularUpperLimit(btVector3(0., 0., 0.));

            getEnvironment()->bullet->dynamicsWorld->addConstraint(constraint.get());
        }
    }
}
示例#13
0
void Blaster::shoot_hook()
{
    Ogre::Vector3 cam_dir = ((Camera*)(player->controller->fps_camera))->camera->getDirection();
    Ogre::Vector3 cam_pos = ((Camera*)(player->controller->fps_camera))->camera->getPosition();

    Ogre::Vector3 shoot_vector = shoot_pos->node->convertLocalToWorldPosition(shoot_pos->node->getPosition());

    btVector3 from = btVector3(cam_pos.x, cam_pos.y, cam_pos.z) + (btVector3(cam_dir.x, cam_dir.y, cam_dir.z) * shoot_from_offset);
    btVector3 to = btVector3(cam_pos.x, cam_pos.y, cam_pos.z) + (btVector3(cam_dir.x, cam_dir.y, cam_dir.z) * shoot_distance);

    btCollisionWorld::ClosestRayResultCallback rayCallback(from, to);

    rayCallback.m_collisionFilterGroup = COL_BULLET;
    rayCallback.m_collisionFilterMask = COL_BULLET_COLLIDER_WITH;

    Component::_gameObject->scene->physics_world->rayTest(from, to, rayCallback);
    if(rayCallback.hasHit())
    {
        btVector3 point = rayCallback.m_hitPointWorld;
        float radius = blast_radius * charge_scale;
        int damage_sent = damage * charge_scale;

        ParticleManager::instance()->EmitRocketExplosion(Ogre::Vector3(point.x(), point.y(), point.z()), radius / blast_radius);
        NetworkManager::instance()->particle->setBlasterExplosion(point.x(), point.y(), point.z(), radius / blast_radius);

        for(std::map<int,bool>::iterator iter = GameState::instance()->playerConnections.begin();
            iter != GameState::instance()->playerConnections.end(); ++iter)
        {
            int i = iter->first;
            if(GameState::instance()->players[i] != NULL
                && ((GameState::instance()->team_mode != TEAM) || (GameState::instance()->players[i]->team_id != GameState::instance()->player->team_id)
                    || (GameState::instance()->game_mode == PINTO)))
            {
                Transform* tran = GameState::instance()->players[i]->transform;
                btVector3 tran_vector = btVector3(tran->posX, tran->posY, tran->posZ);
                if(tran_vector.distance(point) <= radius)
                {
                    uint32_t enemy_id = GameState::instance()->players[i]->player_id;
                    if(GameState::instance()->players[i]->in_pinto_form)
                        damage_sent *= (1 / (float)GameState::instance()->num_player);
                    NetworkManager::instance()->vital->setDamage(damage_sent, enemy_id);
                }
            }
        }
    }
}
//--------------------------------------------------------------
ofxBulletRaycastData ofxBulletWorldSoft::raycastTest( ofVec3f a_rayStart, ofVec3f a_rayEnd, short int a_filterMask) {
	ofxBulletRaycastData data;
	data.bHasHit = false;
	if(_camera == NULL) {
		ofLog( OF_LOG_ERROR, "ofxBulletWorldSoft :: raycastTest : must set the camera first!!");
		return data;
	}
	
	btVector3 rayStart( a_rayStart.x, a_rayStart.y, a_rayStart.z );
	btVector3 rayEnd( a_rayEnd.x, a_rayEnd.y, a_rayEnd.z );
	
	btCollisionWorld::ClosestRayResultCallback rayCallback( rayStart, rayEnd );
	rayCallback.m_collisionFilterMask = a_filterMask;
	world->rayTest( rayStart, rayEnd, rayCallback );
	
	if (rayCallback.hasHit()) {
		if ( rayCallback.m_collisionObject->getInternalType() & btCollisionObject::CO_SOFT_BODY ) {
			// cast a ray into the soft body to get the point exactly
			//ofLogNotice("ofxBulletWorldSoft: soft body intersection");
			btSoftBody::sRayCast result;
#warning Casting (const btSoftBody*) to (btSoftBody*) -- not necessarily safe
			btSoftBody* body = (btSoftBody*)btSoftBody::upcast( rayCallback.m_collisionObject );
			if ( body->rayTest( rayStart, rayEnd, result ) ) {
				if ( result.fraction<1.0f ) {
					//ofLogNotice("ofxBulletWorldSoft") << "    at " << result.getFeatureName() << " index " << result.index;
				}
			}
			
		}
		else {
#warning Casting (const btRigidBody*) to (btRigidBody*) -- not necessarily safe
			btRigidBody* body = (btRigidBody*)btRigidBody::upcast(rayCallback.m_collisionObject);
			if (body) {
				data.bHasHit			= true;
				data.userData			= (ofxBulletUserData*)body->getUserPointer();
				data.body				= body;
				data.rayWorldPos		= a_rayEnd;
				btVector3 pickPos		= rayCallback.m_hitPointWorld;
				data.pickPosWorld		= ofVec3f(pickPos.getX(), pickPos.getY(), pickPos.getZ());
				btVector3 localPos		= body->getCenterOfMassTransform().inverse() * pickPos;
				data.localPivotPos		= ofVec3f(localPos.getX(), localPos.getY(), localPos.getZ() );
			}
		}
	}
	return data;
}
void* FilterableVehicleRaycaster::castRay(const btVector3& from, const btVector3& to, btVehicleRaycasterResult& result) {
	btCollisionWorld::ClosestRayResultCallback rayCallback(from,to);
	rayCallback.m_collisionFilterMask = m_collisionFilterMask;
	rayCallback.m_collisionFilterGroup = m_collisionFilterGroup;
	m_testWorld->rayTest(from, to, rayCallback);
	if (rayCallback.hasHit()) {
		const btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject);
		if (body && body->hasContactResponse()) {
			result.m_hitPointInWorld = rayCallback.m_hitPointWorld;
			result.m_hitNormalInWorld = rayCallback.m_hitNormalWorld;
			result.m_hitNormalInWorld.normalize();
			result.m_distFraction = rayCallback.m_closestHitFraction;
			return (void*)body;
		}
	}
	return 0;
}
示例#16
0
const btRigidBody* DyWorld::RayCast( const MtVector3& v3From,
									 const MtVector3& v3To,
									 DyCollision& collision
							 )
{
	btVector3 from = btVector3( v3From.x, v3From.y, v3From.z );
	btVector3 to   = btVector3( v3To.x,   v3To.y,   v3To.z );

	btCollisionWorld::ClosestRayResultCallback rayCallback( from, to );

	m_pDynamicsWorld->rayTest( from, to, rayCallback );

	if( rayCallback.hasHit() )
	{
		const btRigidBody* pBody = btRigidBody::upcast(rayCallback.m_collisionObject);

		if( pBody )
		{
			collision.m_hitPointInWorld = MtVector3( rayCallback.m_hitPointWorld.getX(),
													 rayCallback.m_hitPointWorld.getY(),
													 rayCallback.m_hitPointWorld.getZ() );

			collision.m_hitNormalInWorld = MtVector3( rayCallback.m_hitNormalWorld.getX(),
													  rayCallback.m_hitNormalWorld.getY(),
													  rayCallback.m_hitNormalWorld.getZ() );

			collision.m_hitNormalInWorld.Normalise();

			collision.m_distFraction = rayCallback.m_closestHitFraction;

			collision.m_pUserPointer = (void*)pBody->getUserPointer();

			return pBody;
		}
		else
		{
			collision.m_pUserPointer = BtNull;
		}
	}
	else
	{
		collision.m_pUserPointer = BtNull;
	}
	return BtNull;
}
示例#17
0
double heightSensor::getHeight() const
{
	double distance = -1.0;

	btVector3 origin=this->getWorldPosition();
	btVector3 end = origin;
	end.setY(-5000.0f);
	origin.setY(origin.getY()-1);
	btCollisionWorld::AllHitsRayResultCallback rayCallback(origin, end);
	btworld->rayTest(origin, end, rayCallback);
	if(rayCallback.hasHit())
	{
		int idx = 0;
		rayCallback.m_hitPointWorld[idx] = origin - rayCallback.m_hitPointWorld[idx];
		distance=rayCallback.m_hitPointWorld[idx].getY();
	}
	return distance;
}
示例#18
0
// calculates the ray intersection of all the laser points
void laserScanner::update(btTransform botTrans)
{
	// get the global position of the scanner
    btTransform tTrans = botTrans * m_scanTrans; 
    btVector3 rayFrom = tTrans.getOrigin();	

    for(int i=0;i<m_dataSize;i++){
        btVector3 rayTo = tTrans(m_beamVector[i] * maxRange);
        btCollisionWorld::ClosestRayResultCallback rayCallback(rayFrom,rayTo);
        arena->getDynamicsWorld()->rayTest(rayFrom,rayTo,rayCallback);
        if(rayCallback.hasHit()){
            btVector3 hitPoint = rayCallback.m_hitPointWorld;
            hitPoint -= rayFrom;
            m_rangeData[i] = hitPoint.length();
        }
        else m_rangeData[i] = maxRange;
    }
}
void MyCharacterController::preSimulation() {
    if (_enabled && _dynamicsWorld) {
        // slam body to where it is supposed to be
        _rigidBody->setWorldTransform(_avatarBodyTransform);

        // scan for distant floor
        // rayStart is at center of bottom sphere
        btVector3 rayStart = _avatarBodyTransform.getOrigin() - _halfHeight * _currentUp;
    
        // rayEnd is straight down MAX_FALL_HEIGHT
        btScalar rayLength = _radius + MAX_FALL_HEIGHT;
        btVector3 rayEnd = rayStart - rayLength * _currentUp;
    
        ClosestNotMe rayCallback(_rigidBody);
        rayCallback.m_closestHitFraction = 1.0f;
        _dynamicsWorld->rayTest(rayStart, rayEnd, rayCallback);
        if (rayCallback.hasHit()) {
            _floorDistance = rayLength * rayCallback.m_closestHitFraction - _radius;
            const btScalar MIN_HOVER_HEIGHT = 3.0f;
            if (_isHovering && _floorDistance < MIN_HOVER_HEIGHT && !_isPushingUp) {
                setHovering(false);
            } 
            // TODO: use collision events rather than ray-trace test to disable jumping
            const btScalar JUMP_PROXIMITY_THRESHOLD = 0.1f * _radius;
            if (_floorDistance < JUMP_PROXIMITY_THRESHOLD) {
                _isJumping = false;
            }
        } else {
            _floorDistance = FLT_MAX;
            setHovering(true);
        }

        if (_pendingFlags & PENDING_FLAG_JUMP) {
            _pendingFlags &= ~ PENDING_FLAG_JUMP;
            if (onGround()) {
                _isJumping = true;
                btVector3 velocity = _rigidBody->getLinearVelocity();
                velocity += _jumpSpeed * _currentUp;
                _rigidBody->setLinearVelocity(velocity);
            }
        }
    }
    _lastStepDuration = 0.0f;
}
示例#20
0
    void* castRay(const btVector3& from, const btVector3& to, btVehicleRaycasterResult& result)
    {
        ClosestNotMeRayResultCallback rayCallback(from, to, _me);
        _dynamicsWorld->rayTest(from, to, rayCallback);

        if (rayCallback.hasHit())
        {
            const btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject);
            if (body && body->hasContactResponse())
            {
                result.m_hitPointInWorld = rayCallback.m_hitPointWorld;
                result.m_hitNormalInWorld = rayCallback.m_hitNormalWorld;
                result.m_hitNormalInWorld.normalize();
                result.m_distFraction = rayCallback.m_closestHitFraction;
                return (void*)body;
            }
        }
        return 0;
    }
void MyCharacterController::preStep(btCollisionWorld* collisionWorld) {
    // trace a ray straight down to see if we're standing on the ground
    const btTransform& xform = _rigidBody->getWorldTransform();

    // rayStart is at center of bottom sphere
    btVector3 rayStart = xform.getOrigin() - _halfHeight * _currentUp;

    // rayEnd is some short distance outside bottom sphere
    const btScalar FLOOR_PROXIMITY_THRESHOLD = 0.3f * _radius;
    btScalar rayLength = _radius + FLOOR_PROXIMITY_THRESHOLD;
    btVector3 rayEnd = rayStart - rayLength * _currentUp;

    // scan down for nearby floor
    ClosestNotMe rayCallback(_rigidBody);
    rayCallback.m_closestHitFraction = 1.0f;
    collisionWorld->rayTest(rayStart, rayEnd, rayCallback);
    if (rayCallback.hasHit()) {
        _floorDistance = rayLength * rayCallback.m_closestHitFraction - _radius;
    }
}
示例#22
0
	void* castRay(const btVector3 &from, const btVector3 &to, btVehicleRaycasterResult &result)
	{
		ClosestNotMeRayResultCallback rayCallback( _vehicle->collision->getBulletBody(), from, to );
		const void *res = 0;

		_world->rayTest(from, to, rayCallback);

		if( rayCallback.hasHit() ) {
			const btRigidBody* body = btRigidBody::upcast( rayCallback.m_collisionObject );

			if( body && body->hasContactResponse() ) {
				result.m_hitPointInWorld = rayCallback.m_hitPointWorld;
				result.m_hitNormalInWorld = rayCallback.m_hitNormalWorld;
				result.m_hitNormalInWorld.normalize();
				result.m_distFraction = rayCallback.m_closestHitFraction;
				res = body;
			}
		}

		return (void* )res;
	}
示例#23
0
bool PhysicsEngine::RayCastNormal(const Eigen::Vector3d& dSource,
                                  const Eigen::Vector3d& dRayVector,
                                  Eigen::Vector3d& dNormal){
  bool hit = false;
  btVector3 source(dSource[0],dSource[1],dSource[2]);
  btVector3 vec(dRayVector[0],dRayVector[1],dRayVector[2]);
  source = source - vec*10;
  btVector3 target = source + vec*20;
  btCollisionWorld::ClosestRayResultCallback rayCallback(source, target);
  dynamics_world_->rayTest(source, target, rayCallback);
  //We need a default rotation... just make it the gravity vector, why not.
  btVector3 dNewNorm = dynamics_world_->getGravity();
  Eigen::Vector3d norm(dNewNorm[0], dNewNorm[1], dNewNorm[2]);
  dNormal = norm;
  if (rayCallback.hasHit()){
    dNewNorm = rayCallback.m_hitNormalWorld;
    Eigen::Vector3d norm(dNewNorm[0], dNewNorm[1], dNewNorm[2]);
    dNormal = norm;
    hit = true;
  }
  return hit;
}
示例#24
0
char DynamicsSolver::selectByRayHit(const Vector3F & origin, const Vector3F & ray, Vector3F & hitP)
{
    m_activeBody = 0;
    btVector3 fromP(origin.x, origin.y, origin.z);
    btVector3 toP(origin.x + ray.x, origin.y + ray.y, origin.z + ray.z);
    btCollisionWorld::ClosestRayResultCallback rayCallback(fromP, toP);
    m_dynamicsWorld->rayTest(fromP , toP, rayCallback);
    if(rayCallback.hasHit()) {
        btRigidBody * body = (btRigidBody *)btRigidBody::upcast(rayCallback.m_collisionObject);
        if(body) {
            body->setActivationState(DISABLE_DEACTIVATION);
            btVector3 pickPos = rayCallback.m_hitPointWorld;
            hitP.x = pickPos.getX();
            hitP.y = pickPos.getY();
            hitP.z = pickPos.getZ();
            m_activeBody = body;
            
            
            return 1;
        }
    }
    return 0;
}
示例#25
0
bool Physics::rayHit(glm::vec3 rayFrom, glm::vec3 rayTo, btVector3 &hitPointWorld )
{
	btVector3 btRayFrom = btVector3(rayFrom.x, rayFrom.y, rayFrom.z);
    btVector3 btRayTo = btVector3(rayTo.x, rayTo.y, rayTo.z);
    
	btCollisionWorld::ClosestRayResultCallback rayCallback(btRayFrom, btRayTo);
	
    dynamicsWorld->rayTest(btRayFrom, btRayTo, rayCallback);
	
	if (rayCallback.hasHit())
	{
    
        hitPointWorld = rayCallback.m_hitPointWorld;
        return true;

	}
	
    else
    {
        return false;
    }
	
}
示例#26
0
PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IPhysicsController* ignoreClient, float fromX,float fromY,float fromZ, float toX,float toY,float toZ, 
													   float& hitX,float& hitY,float& hitZ,float& normalX,float& normalY,float& normalZ)
{


	float minFraction = 1.f;

	SimdVector3 rayFrom(fromX,fromY,fromZ);
	SimdVector3 rayTo(toX,toY,toZ);

	SimdVector3	hitPointWorld,normalWorld;

	//Either Ray Cast with or without filtering

	//CollisionWorld::ClosestRayResultCallback rayCallback(rayFrom,rayTo);
	FilterClosestRayResultCallback	 rayCallback(ignoreClient,rayFrom,rayTo);


	PHY_IPhysicsController* nearestHit = 0;

	m_collisionWorld->RayTest(rayFrom,rayTo,rayCallback);
	if (rayCallback.HasHit())
	{
		nearestHit = static_cast<CcdPhysicsController*>(rayCallback.m_collisionObject->m_userPointer);
		hitX = 	rayCallback.m_hitPointWorld.getX();
		hitY = 	rayCallback.m_hitPointWorld.getY();
		hitZ = 	rayCallback.m_hitPointWorld.getZ();

		normalX = rayCallback.m_hitNormalWorld.getX();
		normalY = rayCallback.m_hitNormalWorld.getY();
		normalZ = rayCallback.m_hitNormalWorld.getZ();

	}	


	return nearestHit;
}
bool BulletOpenGLApplication::Raycast(const btVector3 &startPosition, const btVector3 &direction, RayResult &output, bool includeStatic) {
 	if (!m_pWorld) 
 		return false;
 		
 	// get the picking ray from where we clicked
 	btVector3 rayTo = direction;
 	btVector3 rayFrom = m_cameraPosition;
 		
 	// create our raycast callback object
 	btCollisionWorld::ClosestRayResultCallback rayCallback(rayFrom,rayTo);
 		
 	// perform the raycast
 	m_pWorld->rayTest(rayFrom,rayTo,rayCallback);
 		
 	// did we hit something?
 	if (rayCallback.hasHit())
 	{
 		// if so, get the rigid body we hit
 		btRigidBody* pBody = (btRigidBody*)btRigidBody::upcast(rayCallback.m_collisionObject);
 		if (!pBody)
 			return false;
 		
 		// prevent us from picking objects 
 		// like the ground plane
		if (!includeStatic) // skip this check if we want it to hit static objects
			if (pBody->isStaticObject() || pBody->isKinematicObject()) 
				return false;
 	    
 		// set the result data
 		output.pBody = pBody;
 		output.hitPoint = rayCallback.m_hitPointWorld;
 		return true;
 	}
 	
 	// we didn't hit anything
 	return false;
}
示例#28
0
void CharacterController::preSimulation() {
    if (_enabled && _dynamicsWorld) {
        // slam body to where it is supposed to be
        _rigidBody->setWorldTransform(_characterBodyTransform);
        btVector3 velocity = _rigidBody->getLinearVelocity();

        btVector3 actualVertVelocity = velocity.dot(_currentUp) * _currentUp;
        btVector3 actualHorizVelocity = velocity - actualVertVelocity;

        // scan for distant floor
        // rayStart is at center of bottom sphere
        btVector3 rayStart = _characterBodyTransform.getOrigin() - _halfHeight * _currentUp;

        // rayEnd is straight down MAX_FALL_HEIGHT
        btScalar rayLength = _radius + MAX_FALL_HEIGHT;
        btVector3 rayEnd = rayStart - rayLength * _currentUp;

        ClosestNotMe rayCallback(_rigidBody);
        rayCallback.m_closestHitFraction = 1.0f;
        _dynamicsWorld->rayTest(rayStart, rayEnd, rayCallback);
        if (rayCallback.hasHit()) {
            _floorDistance = rayLength * rayCallback.m_closestHitFraction - _radius;
        } else {
            _floorDistance = FLT_MAX;
        }

        const btScalar JUMP_PROXIMITY_THRESHOLD = 0.1f * _radius;
        const quint64 TAKE_OFF_TO_IN_AIR_PERIOD = 200 * MSECS_PER_SECOND;
        const btScalar MIN_HOVER_HEIGHT = 2.5f;
        const quint64 JUMP_TO_HOVER_PERIOD = 750 * MSECS_PER_SECOND;
        const btScalar MAX_WALKING_SPEED = 2.5f;

        quint64 now = usecTimestampNow();

        // record a time stamp when the jump button was first pressed.
        if ((_previousFlags & PENDING_FLAG_JUMP) != (_pendingFlags & PENDING_FLAG_JUMP)) {
            if (_pendingFlags & PENDING_FLAG_JUMP) {
                _jumpButtonDownStart = now;
                _jumpButtonDownCount++;
            }
        }

        bool jumpButtonHeld = _pendingFlags & PENDING_FLAG_JUMP;
        bool flyingFast = _state == State::Hover && actualHorizVelocity.length() > (MAX_WALKING_SPEED * 0.75f);

        switch (_state) {
        case State::Ground:
            if (!rayCallback.hasHit() && !_hasSupport) {
                SET_STATE(State::Hover, "no ground");
            } else if (_pendingFlags & PENDING_FLAG_JUMP) {
                _takeOffJumpButtonID = _jumpButtonDownCount;
                SET_STATE(State::Takeoff, "jump pressed");
            }
            break;
        case State::Takeoff:
            if (!rayCallback.hasHit() && !_hasSupport) {
                SET_STATE(State::Hover, "no ground");
            } else if ((now - _takeoffToInAirStart) > TAKE_OFF_TO_IN_AIR_PERIOD) {
                SET_STATE(State::InAir, "takeoff done");
                _takeoffToInAirStart = now + USECS_PER_SECOND * 86500.0f;
                velocity += _jumpSpeed * _currentUp;
                _rigidBody->setLinearVelocity(velocity);
            }
            break;
        case State::InAir: {
            if ((velocity.dot(_currentUp) <= (JUMP_SPEED / 2.0f)) && ((_floorDistance < JUMP_PROXIMITY_THRESHOLD) || _hasSupport)) {
                SET_STATE(State::Ground, "hit ground");
            } else if (jumpButtonHeld && (_takeOffJumpButtonID != _jumpButtonDownCount)) {
                SET_STATE(State::Hover, "double jump button");
            } else if (jumpButtonHeld && (now - _jumpButtonDownStart) > JUMP_TO_HOVER_PERIOD) {
                SET_STATE(State::Hover, "jump button held");
            }
            break;
        }
        case State::Hover:
            if ((_floorDistance < MIN_HOVER_HEIGHT) && !jumpButtonHeld && !flyingFast) {
                SET_STATE(State::InAir, "near ground");
            } else if (((_floorDistance < JUMP_PROXIMITY_THRESHOLD) || _hasSupport) && !flyingFast) {
                SET_STATE(State::Ground, "touching ground");
            }
            break;
        }
    }

    _previousFlags = _pendingFlags;
    _pendingFlags &= ~PENDING_FLAG_JUMP;

    _followTime = 0.0f;
    _followLinearDisplacement = btVector3(0, 0, 0);
    _followAngularDisplacement = btQuaternion::getIdentity();
}
示例#29
0
	bool	mouseButtonCallback(int button, int state, float x, float y)
	{

		if (state==1)
		{
			if(button==0)// && (m_data->m_altPressed==0 && m_data->m_controlPressed==0))
			{
				btVector3 camPos;
				m_glApp->m_instancingRenderer->getCameraPosition(camPos);

				btVector3 rayFrom = camPos;
				btVector3 rayTo = getRayTo(x,y);

				btCollisionWorld::ClosestRayResultCallback rayCallback(rayFrom,rayTo);
				m_dynamicsWorld->rayTest(rayFrom,rayTo,rayCallback);
				if (rayCallback.hasHit())
				{

					btVector3 pickPos = rayCallback.m_hitPointWorld;
					btRigidBody* body = (btRigidBody*)btRigidBody::upcast(rayCallback.m_collisionObject);
					if (body)
					{
						//other exclusions?
						if (!(body->isStaticObject() || body->isKinematicObject()))
						{
							m_pickedBody = body;
							m_pickedBody->setActivationState(DISABLE_DEACTIVATION);
							//printf("pickPos=%f,%f,%f\n",pickPos.getX(),pickPos.getY(),pickPos.getZ());
							btVector3 localPivot = body->getCenterOfMassTransform().inverse() * pickPos;
							btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*body,localPivot);
							m_dynamicsWorld->addConstraint(p2p,true);
							m_pickedConstraint = p2p;
							btScalar mousePickClamping = 30.f;
							p2p->m_setting.m_impulseClamp = mousePickClamping;
							//very weak constraint for picking
							p2p->m_setting.m_tau = 0.001f;
						}
					} else
					{
						btMultiBodyLinkCollider* multiCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(rayCallback.m_collisionObject);
						if (multiCol && multiCol->m_multiBody)
						{
							multiCol->m_multiBody->setCanSleep(false);

							btVector3 pivotInA = multiCol->m_multiBody->worldPosToLocal(multiCol->m_link, pickPos);

							btMultiBodyPoint2Point* p2p = new btMultiBodyPoint2Point(multiCol->m_multiBody,multiCol->m_link,0,pivotInA,pickPos);
							//if you add too much energy to the system, causing high angular velocities, simulation 'explodes'
							//see also http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=4&t=949
							//so we try to avoid it by clamping the maximum impulse (force) that the mouse pick can apply
							//it is not satisfying, hopefully we find a better solution (higher order integrator, using joint friction using a zero-velocity target motor with limited force etc?)

							p2p->setMaxAppliedImpulse(20*scaling);
		
							btMultiBodyDynamicsWorld* world = (btMultiBodyDynamicsWorld*) m_dynamicsWorld;
							world->addMultiBodyConstraint(p2p);
							m_pickingMultiBodyPoint2Point =p2p; 
						}
					}


//					pickObject(pickPos, rayCallback.m_collisionObject);
					m_oldPickingPos = rayTo;
					m_hitPos = pickPos;
					m_oldPickingDist  = (pickPos-rayFrom).length();
//					printf("hit !\n");
				//add p2p
				}
				
			}
		} else
		{
			if (button==0)
			{
				if (m_pickedConstraint)
				{
					m_dynamicsWorld->removeConstraint(m_pickedConstraint);
					delete m_pickedConstraint;
					m_pickedConstraint=0;
					m_pickedBody = 0;
				}

				if (m_pickingMultiBodyPoint2Point)
				{
					m_pickingMultiBodyPoint2Point->getMultiBodyA()->setCanSleep(true);
					btMultiBodyDynamicsWorld* world = (btMultiBodyDynamicsWorld*) m_dynamicsWorld;
					world->removeMultiBodyConstraint(m_pickingMultiBodyPoint2Point);
					delete m_pickingMultiBodyPoint2Point;
					m_pickingMultiBodyPoint2Point = 0;
				}
				//remove p2p
			}
		}

		//printf("button=%d, state=%d\n",button,state);
		return false;
	}
void DemoApplication::mouseFunc(int button, int state, int x, int y)
{
	if (state == 0) 
	{
        m_mouseButtons |= 1<<button;
    } else
	{
        m_mouseButtons = 0;
    }

	m_mouseOldX = x;
    m_mouseOldY = y;

	updateModifierKeys();
	if ((m_modifierKeys& BT_ACTIVE_ALT) && (state==0))
	{
		return;
	}

	//printf("button %i, state %i, x=%i,y=%i\n",button,state,x,y);
	//button 0, state 0 means left mouse down

	btVector3 rayTo = getRayTo(x,y);

	switch (button)
	{
	case 2:
		{
			if (state==0)
			{

				shootBox(rayTo);
			}
			break;
		};
	case 1:
		{


			if (state==0)
			{

#if 0
				//apply an impulse
				if (m_dynamicsWorld)
				{
					btCollisionWorld::ClosestRayResultCallback rayCallback(m_cameraPosition,rayTo);
					m_dynamicsWorld->rayTest(m_cameraPosition,rayTo,rayCallback);
					if (rayCallback.hasHit())
					{

						btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject);
						if (body)
						{
							body->setActivationState(ACTIVE_TAG);
							btVector3 impulse = rayTo;
							impulse.normalize();
							float impulseStrength = 10.f;
							impulse *= impulseStrength;
							btVector3 relPos = rayCallback.m_hitPointWorld - body->getCenterOfMassPosition();
							body->applyImpulse(impulse,relPos);
						}
					}
				}
#endif



			} else
			{

			}
			break;	
		}
	case 0:
		{
			if (state==0)
			{


				//add a point to point constraint for picking
				if (m_dynamicsWorld)
				{
					
					btVector3 rayFrom;
					if (m_ortho)
					{
						rayFrom = rayTo;
						rayFrom.setZ(-100.f);
					} else
					{
						rayFrom = m_cameraPosition;
					}
					
					btCollisionWorld::ClosestRayResultCallback rayCallback(rayFrom,rayTo);
					m_dynamicsWorld->rayTest(rayFrom,rayTo,rayCallback);
					if (rayCallback.hasHit())
					{


						btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject);
						if (body)
						{
							//other exclusions?
							if (!(body->isStaticObject() || body->isKinematicObject()))
							{
								pickedBody = body;
								pickedBody->setActivationState(DISABLE_DEACTIVATION);


								btVector3 pickPos = rayCallback.m_hitPointWorld;
								printf("pickPos=%f,%f,%f\n",pickPos.getX(),pickPos.getY(),pickPos.getZ());


								btVector3 localPivot = body->getCenterOfMassTransform().inverse() * pickPos;

								

								


								if (use6Dof)
								{
									btTransform tr;
									tr.setIdentity();
									tr.setOrigin(localPivot);
									btGeneric6DofConstraint* dof6 = new btGeneric6DofConstraint(*body, tr,false);
									dof6->setLinearLowerLimit(btVector3(0,0,0));
									dof6->setLinearUpperLimit(btVector3(0,0,0));
									dof6->setAngularLowerLimit(btVector3(0,0,0));
									dof6->setAngularUpperLimit(btVector3(0,0,0));

									m_dynamicsWorld->addConstraint(dof6);
									m_pickConstraint = dof6;

									dof6->setParam(BT_CONSTRAINT_STOP_CFM,0.8,0);
									dof6->setParam(BT_CONSTRAINT_STOP_CFM,0.8,1);
									dof6->setParam(BT_CONSTRAINT_STOP_CFM,0.8,2);
									dof6->setParam(BT_CONSTRAINT_STOP_CFM,0.8,3);
									dof6->setParam(BT_CONSTRAINT_STOP_CFM,0.8,4);
									dof6->setParam(BT_CONSTRAINT_STOP_CFM,0.8,5);

									dof6->setParam(BT_CONSTRAINT_STOP_ERP,0.1,0);
									dof6->setParam(BT_CONSTRAINT_STOP_ERP,0.1,1);
									dof6->setParam(BT_CONSTRAINT_STOP_ERP,0.1,2);
									dof6->setParam(BT_CONSTRAINT_STOP_ERP,0.1,3);
									dof6->setParam(BT_CONSTRAINT_STOP_ERP,0.1,4);
									dof6->setParam(BT_CONSTRAINT_STOP_ERP,0.1,5);
								} else
								{
									btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*body,localPivot);
									m_dynamicsWorld->addConstraint(p2p);
									m_pickConstraint = p2p;
									p2p->m_setting.m_impulseClamp = mousePickClamping;
									//very weak constraint for picking
									p2p->m_setting.m_tau = 0.001f;
/*
									p2p->setParam(BT_CONSTRAINT_CFM,0.8,0);
									p2p->setParam(BT_CONSTRAINT_CFM,0.8,1);
									p2p->setParam(BT_CONSTRAINT_CFM,0.8,2);
									p2p->setParam(BT_CONSTRAINT_ERP,0.1,0);
									p2p->setParam(BT_CONSTRAINT_ERP,0.1,1);
									p2p->setParam(BT_CONSTRAINT_ERP,0.1,2);
									*/
									

								}
								use6Dof = !use6Dof;

								//save mouse position for dragging
								gOldPickingPos = rayTo;
								gHitPos = pickPos;

								gOldPickingDist  = (pickPos-rayFrom).length();
							}
						}
					}
				}

			} else
			{

				if (m_pickConstraint && m_dynamicsWorld)
				{
					m_dynamicsWorld->removeConstraint(m_pickConstraint);
					delete m_pickConstraint;
					//printf("removed constraint %i",gPickingConstraintId);
					m_pickConstraint = 0;
					pickedBody->forceActivationState(ACTIVE_TAG);
					pickedBody->setDeactivationTime( 0.f );
					pickedBody = 0;
				}


			}

			break;

		}
	default:
		{
		}
	}

}