//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; }
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; }
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; }
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; }
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); } } }
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; }
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); } } } }
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; } } }
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()); } } }
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; }
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; }
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; }
// 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; }
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; } }
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; }
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; }
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; }
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; } }
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; }
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(); }
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: { } } }