Example Bullet Code, needs 1 last issue figured out

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
kendric
Posts: 71
Joined: Tue May 29, 2007 9:05 pm

Example Bullet Code, needs 1 last issue figured out

Post by kendric »

I thought I would share my projectile code with people and hopefully somebody will also have an idea why about 10-20% of the time bullets seem to be able to go through an enemy without a collision detected.

You will have to modify this depending on your model domain, as this uses all my game classes.

Just to sum up the logic:
Every frame the following happens for a bullet in the air:
First frame: calculate the distance to wall we will hit so we don't have to calculate collisions with the world scene node

All other frames:
take current position and create a line from there to next position given amount of time passed and flight speed

Do a ray cast check with custom ray cast code along that line(custom ray cast will be at the bottom)

If any collisions along the line, stop there and perform a hit

else move to the end of the line.

And here is the code (If you know how to make it preserve indentation please let me know)

Code: Select all

void Projectile::passTime(f32 amount)
{
       Object::passTime(amount);
	if(firstTick)
	{
		firstTick=false;
		line3df totalTravelLine;
		totalTravelLine.start=getSceneNode()->getPosition();
		totalTravelLine.end=direction*50000.0f;
wallDecal=myGameSceneManager->getSceneCollisionManager()->getCollisionPoint(totalTravelLine,game->world->getSceneNode()->getTriangleSelector(),expirePoint,expireTriangle);
		if(wallDecal)
		{
expireDistanceRemaining=expirePoint.getDistanceFrom(totalTravelLine.start);
		}
		else
		{
			printf("No wall hit.\n");// This should not happen
			expireDistanceRemaining=2500000000.0f;
		}
	}
	line3d<f32> line;
	line.start=getSceneNode()->getPosition();
	line.end = line.start + direction*speed*amount;
	lines.push_back(line);//i track these just so i can draw the incramental trajectories for debugging only(this is how i see that the line passes right through a scene node)
	expireDistanceRemaining-=line.getLength();
	ISceneNode* selectedSceneNode=NULL;
	f32 distanceSquared;
	vector3df collisionPoint;
	triangle3df collisionTriangle;
collisionCheck(myGameSceneManager->getRootSceneNode(),line,ProjectileSceneNodeFilter(thisProjectilePtr()),selectedSceneNode,collisionPoint,collisionTriangle,distanceSquared);
	bool hit=false;
	if(selectedSceneNode)
	{
		handleImpact(selectedSceneNode,collisionPoint,collisionTriangle,line);
		destroy();
	}
	else if(expireDistanceRemaining<=0.0f)
	{
		if(wallDecal&&hasBulletHole)
		{	
			shared_ptr<Decal> temp(new Decal());
			temp->init(game->world->getSceneNode(),expireTriangle,expirePoint,bulletHoleTexture,2);
			game->zone->addDecal(temp);
		}
		destroy();
	}
	else
	{
		getSceneNode()->setPosition(line.end);
	}
}


and the collision function(this is a modifcation to the one in irrlicht 
//! recursive method for going through all scene nodes and looking for the best triangle collision
void collisionCheck(ISceneNode* root,
					 const line3df& ray,SceneNodeFilter &filter,ISceneNode*& outBestNode,vector3df &outPoint,triangle3df &outTriangle,f32 &outDistanceSQ)
{
	core::vector3df edges[8];
	const core::list<ISceneNode*>& children = root->getChildren();
	core::list<ISceneNode*>::Iterator it = children.begin();
	for (; it != children.end(); ++it)
	{
		ISceneNode* current = *it;
		if (filter.allowNode(current))
		{
			// get world to object space transform
			core::matrix4 mat;
			if (!current->getAbsoluteTransformation().getInverse(mat))
			{
				continue;
			}
			// transform vector from world space to object space
			core::line3df line(ray);
			mat.transformVect(line.start);
			mat.transformVect(line.end);
			const core::aabbox3df& box = current->getBoundingBox();
			// do triangle intersection test in object space
			if (box.intersectsWithLine(line))
			{
				vector3df point;
				triangle3df triangle;
				bool hit=myGameSceneManager->getSceneCollisionManager()->getCollisionPoint(ray,current->getTriangleSelector(),point,triangle);
				if(hit)
				{
					float newDistance=point.getDistanceFromSQ(line.end);
					if(!outBestNode||newDistance<outDistanceSQ)
					{
						outBestNode = current;
						outDistanceSQ=newDistance;
						outPoint=point;
						outTriangle=triangle;
					}
				}
			}
		}
		collisionCheck(current, ray, filter,outBestNode,outPoint,outTriangle,outDistanceSQ);
	}
}
Also every node has this happen once at the beginning

ITriangleSelector* selector=myGameSceneManager->createTriangleSelectorFromBoundingBox(sceneNode);
sceneNode->setTriangleSelector(selector);
beshrkayali
Posts: 85
Joined: Mon Jun 11, 2007 11:22 am
Location: Damascus - Syria
Contact:

Post by beshrkayali »

i'm not clear over here :?

is your problem some kind of collision detection??

if it is, this might help
http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=22971
Robert Y.
Posts: 212
Joined: Sun Jan 28, 2007 11:23 pm

Re: Example Bullet Code, needs 1 last issue figured out

Post by Robert Y. »

kendric wrote:... and hopefully somebody will also have an idea why about 10-20% of the time bullets seem to be able to go through an enemy without a collision detected.
Maybe it is because you don't use a metaselector? Also, which version of Irrlicht are you using?
kendric
Posts: 71
Joined: Tue May 29, 2007 9:05 pm

Post by kendric »

Yes my problem is collision detection. This code works most of the time. However wether its certain angles or what but you get into a state where you can shoot through an enemey over and over. If you move enough you get back to hitting them again..


As to the other question the latest build.
Post Reply