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
	}
}
Exemple #2
0
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);

			}
		}
	}

}