void PhysicsComponent::handleEvent_ClosestRayCast(Event_ClosestHitRayCast* event_ClosestRayCast) { btVector3 from = convert(event_ClosestRayCast->from); btVector3 to = convert(event_ClosestRayCast->to); btCollisionWorld::ClosestRayResultCallback closestResults(from, to); closestResults.m_flags |= btTriangleRaycastCallback::kF_KeepUnflippedNormal; //check, what is this? (2013-02-20 11.24) closestResults.m_collisionFilterGroup = XKILL_Enums::PhysicsAttributeType::RAY; closestResults.m_collisionFilterMask = event_ClosestRayCast->collisionFilterMask; dynamicsWorld_->rayTest(from, to, closestResults); //Bullet Physics ray cast //-------------------------------------------------------------------------------------- // Special case event handling: the result of the event is stored in the event. //-------------------------------------------------------------------------------------- if(closestResults.hasHit()) { const PhysicsObject* hitObject = static_cast<const PhysicsObject*>(closestResults.m_collisionObject); event_ClosestRayCast->EntityIdOfOwnerToClosestPhysicsObjectHitByRay = itrPhysics.ownerIdAt(hitObject->getAttributeIndex()); const btVector3 closestHitPoint = from.lerp(to,closestResults.m_closestHitFraction); event_ClosestRayCast->ClosestHitPoint = convert(&closestHitPoint); } else //Ray did not hit anything { event_ClosestRayCast->EntityIdOfOwnerToClosestPhysicsObjectHitByRay = 0; //0 denotes that no physics object was hit by the ray event_ClosestRayCast->ClosestHitPoint = event_ClosestRayCast->to; //There was no closest hit point, i.e. the closest hit point was the destination point of the ray } }
void RaytestDemo::castRays() { static float up = 0.f; static float dir = 1.f; //add some simple animation if (!m_idle) { up+=0.01*dir; if (btFabs(up)>2) { dir*=-1.f; } btTransform tr = m_dynamicsWorld->getCollisionObjectArray()[1]->getWorldTransform(); static float angle = 0.f; angle+=0.01f; tr.setRotation(btQuaternion(btVector3(0,1,0),angle)); m_dynamicsWorld->getCollisionObjectArray()[1]->setWorldTransform(tr); } ///step the simulation if (m_dynamicsWorld) { m_dynamicsWorld->updateAabbs(); m_dynamicsWorld->computeOverlappingPairs(); btVector3 red(1,0,0); btVector3 blue(0,0,1); ///all hits { btVector3 from(-30,1+up,0); btVector3 to(30,1,0); sDebugDraw.drawLine(from,to,btVector4(0,0,0,1)); btCollisionWorld::AllHitsRayResultCallback allResults(from,to); allResults.m_flags |= btTriangleRaycastCallback::kF_KeepUnflippedNormal; //kF_UseGjkConvexRaytest flag is now enabled by default, use the faster but more approximate algorithm allResults.m_flags |= btTriangleRaycastCallback::kF_UseSubSimplexConvexCastRaytest; m_dynamicsWorld->rayTest(from,to,allResults); for (int i=0;i<allResults.m_hitFractions.size();i++) { btVector3 p = from.lerp(to,allResults.m_hitFractions[i]); sDebugDraw.drawSphere(p,0.1,red); } } ///first hit { btVector3 from(-30,1.2,0); btVector3 to(30,1.2,0); sDebugDraw.drawLine(from,to,btVector4(0,0,1,1)); btCollisionWorld::ClosestRayResultCallback closestResults(from,to); closestResults.m_flags |= btTriangleRaycastCallback::kF_FilterBackfaces; m_dynamicsWorld->rayTest(from,to,closestResults); if (closestResults.hasHit()) { btVector3 p = from.lerp(to,closestResults.m_closestHitFraction); sDebugDraw.drawSphere(p,0.1,blue); sDebugDraw.drawLine(p,p+closestResults.m_hitNormalWorld,blue); } } } }