[Incomplete]First person Shooter - achieve bullets with raycast

[Incomplete]First person Shooter - achieve bullets with raycast

I spent quite some time searching in this forum to achieve the code i have so far, I will share it with the community to save some time to the next guy that will try to achieve the same thing.
There are a lot of demos but i didn't find any using raycast with setUserData() and getUserData() and i think it's important.
I saw some posts of guys that are using a hkrigidbody for each bullet which i believe it's a lot "heavier" than this solution.
This solution is incomplete and i will need some help to finish a realistic bullet effect.
So far i only accomplished a basic collision detection, i press the mouse button and I see some particles effect in the collision area.
Here is the code:

void cWeaponsGraphics::useWeapon(Ogre::Real timer)
{
	if(m_pWeapons->fireAgain(timer, m_pWeapons->getRateOfFire()))
	{
		Ogre::Ray weaponRay = cGraphicalInterface::getSingleton().getCameraToViewportRay(0.5f,0.5f);
		Ogre::Vector3 start = weaponRay.getOrigin();
		Ogre::Vector3 end = weaponRay.getOrigin() + weaponRay.getDirection() * m_pWeapons->getRange();

		// Cast down to landscape to get an accurate position
		hkpWorldRayCastInput ray;

		// Reverse direction for collision detection
		ray.m_from = hkVector4(start.x,start.y,start.z);
		ray.m_to = hkVector4(end.x,end.y,end.z);

		hkpClosestRayHitCollector output;

		cPhysicsManager::getSingleton().getOgreHavokWorld()->getWorld()->castRay( ray, output);

		if(output.ha****())
		{
			const hkpCollidable* col = output.getHit().m_rootCollidable;
			hkpRigidBody* body = hkpGetRigidBody(col);
			
			Ogre::Vector3 collisionCoordinates = weaponRay.getOrigin() + weaponRay.getDirection() * (output.getHit().m_hitFraction * m_pWeapons->getRange());

			cEntityGraphics* entity = (cEntityGraphics*)body->getUserData();
			entity->setCollisionCoordinates(collisionCoordinates);
			entity->setCollisionDirection(weaponRay.getDirection());
			entity->setBodyBehavior(m_pWeapons->getDamage(),true);

			return;
		}

		if(m_pWeapons->getShowMuzzleFlash())
			showMuzzleFlash();
		if(m_pWeapons->getShowWeaponTrail())
			showWeaponTrail();
	}
	else
		getMuzzleFlashParticles()->setEmitting(false);
}

Now I need to give a realistic physics effect to the bullet and i have several questions:

1) I believe i can find the force applied by the bullet in the target object after collision with this formula Force = mass(bullet weight?) * bullet_velocity but how i can apply it to the rigid body?

2) Since each kind of ammo has a different velocity(Ex: rocket launcher vs pistol ammo) , how i simulate that?

ray.m_to = bullet_velocity * time_elapsed + direction ??

3) Is this solution really less expensive than use rigid bodies?

By the way, sorry my bad english and thanks in advance!

3 posts / novo 0
Último post
Para obter mais informações sobre otimizações de compiladores, consulte Aviso sobre otimizações.

Hi,

Thanks for adding this - it's good to see forum users sharing their work.

To address your questions:

1)
First, to implement bullet impact you can use hkRigidBody::applyPointImpulse() at the point where the bullet hits the body.
As for calculating the magnitude of the impulse to apply, my instinct would be to decouple it from the simulation.

Impulse signifies a change in momentum.
Momentum is mass*velocity (and impulse has the same dimensions, namely kg*metres/seconds) .
This is not the same as force, but rather the result of some force being applied over an interval of time.

So you could calculate the bullet impact impulse by deciding that some percentage of the bullet's momentum gets imparted to the body (impulse = bulletMass*bulletVelocity*fraction)

However, what if you want different types of ammo, or critical hit buffs or something else you haven't thought of yet?
Balancing your game design will be easier if you have direct control over the hit parameters rather than having to tune them indirectly by changing bullet velocity and mass parameters.

So my advice is, get a rough idea of the impulse from typical bullet parameters but then tune your game parameters directly to be whatever feels most satisfying.

2)
Raycasts are effectively instantaneous so I suppose you'd have to implement some kind of extra solution for different muzzle velocities.
You might, say, calculate the raycast direction as soon as the player pulls the trigger and do the raycast in segments along that direction.
At each successive frame while the bullet hasn't hit anything, raycast another segment that represents the continuing path of the bullet in the current frame.

3)
Yes, I'd say this raycasting solution is less expensive than using bullet rigid bodies.
The continuous simulation should allow you to use a rigid body as a bullet, as long as it has the correct collision quality type but of course the collision queries and integration will be more expensive than a raycast.

Bear in mind though there are reasons someone might want to simulate an actual projectile travelling through space.
For instance,
- in a high-fidelity sniper game where factors like bullet drop and wind are important
- slower-moving rocket or grenade projectiles might be better simulated as rigid bodies

Nevertheless the raycast solution is a useful optimization (particularly if there are a lot of bullets).
Thanks for posting!

Cormac

Thanks a lot for your quick reply, I will try the solution you gave me and when I finish it I will post here the solution and if you wish you can integrate it in a demo at your will, of course some parts must be replaced.

Deixar um comentário

Faça login para adicionar um comentário. Não é membro? Inscreva-se hoje mesmo!