Shooting Query

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
bronxbomber92
Posts: 27
Joined: Mon Oct 30, 2006 11:55 pm

Shooting Query

Post by bronxbomber92 »

Is the Demo's way of shooting the most sensible or easy way to do shooting (besides making a class to handle that function, I mean the function only)? Also, I'm rendering a model of a gun, and I have setup the gun like this:

Code: Select all

void playerWeapon::createWeapon( char* file, char* texture ) 
{
	gunMesh = sm->getMesh( resPath( argv, file ) );
	gunNode = sm->addAnimatedMeshSceneNode( gunMesh );
	gunNode->setMaterialTexture( 0, driver->getTexture( resPath( argv, texture ) ) );
	gunNode->setPosition(core::vector3df(5,-12,17)); 
	gunNode->setMaterialFlag(video::EMF_LIGHTING, false); 
	gunNode->setScale(core::vector3df(0.38,0.38,0.38)); 
	gunNode->setRotation(core::vector3df(-80,5,7));

void playerWeapon::addCamera( ICameraSceneNode* camera )
{
	gunNode->setParent( camera );
}
}
Then, when shooting the start variable is equal ro "camera->getPosition()". Could I get the position of the gun by changing the camera to gunNode? Same quesrion applies to the end variable and collision with an object that isn't part of the map.

Thanks.
sgt_pinky
Posts: 149
Joined: Sat Oct 14, 2006 11:20 am
Location: Melbourne, Australia

Post by sgt_pinky »

To do shooting you do collision between a ray (the path of the bullet), and the objects in your scene. Have a look at tutorial 7 for an example. The process is:

1. Find the x,y coords of where the user clicked the mouse.
2. Work out the ray in your 3D world (a point in 2D will represent a ray in 3D)
3. Calculated collision position between your ray and your world objects.

Cheers,

Pinky
Intellectuals solve problems - geniuses prevent them. -- Einstein
#irrlicht on irc.freenode.net
bronxbomber92
Posts: 27
Joined: Mon Oct 30, 2006 11:55 pm

Post by bronxbomber92 »

Ah, thanks :)
But could I use gunNode->getPosition() (j/w for future reference)?

One more question, would I need to loop through the start and end line of the shooting projection and draw the "shot" at the current number being looped for the Z-coordinate?

Thanks again!
bronxbomber92
Posts: 27
Joined: Mon Oct 30, 2006 11:55 pm

Post by bronxbomber92 »

Ok, I've got what you have mentioned (with some help form the tutorial)

Code: Select all

void shoot( char* shotTexture ) {
	
	scene::ISceneManager* smgr = device->getSceneManager();
	scene::ICameraSceneNode* camera = smgr->getActiveCamera();
	
	struct {
		core::vector3df pos;
	}MouseClickPosition;
	
	struct {
		bool hitIsTrue;
		core::vector3df collisionPos;
		core::vector3df collisionVector;
	}Impact;
	
	Impact hit;
	
	MouseClickPosition click;
	
	click.pos = camera->getPosition();
	core::vector3df end = (camera->getTarget() - click );
	end.normalize();
	click += end*5.0f;
	end = sclick + (end * camera->getFarValue());
	
	core::triangle3df tri;
       core::line3d<f32> ray( click, end );
       scene::ITriangleSelector* collisionSelector;
	
	if( /*MOUSE CLICK*/ ) {
		if( sm->getSceneCollisionManager()->getCollisionPoint( ray, collisionSelector, end, tri ) ) {
			hit.hitIsTrue = true;
			core::vector3df temp = tri.normalize() 
			temp.setLength(0.03f);
What I have commented at the end, would that be correct?
Also, would it be better to check for a mouse click in the function, or but if( mouse clicked ) { shoot(); }
?

Thanks again, and sorry about the double post.
sgt_pinky
Posts: 149
Joined: Sat Oct 14, 2006 11:20 am
Location: Melbourne, Australia

Post by sgt_pinky »

Yeah, that's a pretty good start, but you need to have a look at how event handling works in Irrlicht. That tutorial 7 is a good a place as any. The question is, what are you really shooting from, and to.

For example, in an FPS, you are really shooting from the position of the camera, through the center of the screen - your bullet will hit the first thing in the way.

In a third person view, you are shooting from the character (perhaps their hand, chest, or other simplified position), through a point that is determined by calculating a ray from the camera, to a collision in the scene.

Have a closer look at how tutorial 7 works, but you are on the right track.
Intellectuals solve problems - geniuses prevent them. -- Einstein
#irrlicht on irc.freenode.net
bronxbomber92
Posts: 27
Joined: Mon Oct 30, 2006 11:55 pm

Post by bronxbomber92 »

For example, in an FPS, you are really shooting from the position of the camera, through the center of the screen - your bullet will hit the first thing in the way.
That is what I am trying to accomplish.
Events sort of confuse, how they akk rekate to each other...
bronxbomber92
Posts: 27
Joined: Mon Oct 30, 2006 11:55 pm

Post by bronxbomber92 »

Sorry for bumping my old thread, but I eventually got around to creating a weapon class and shooting... But the problem is, it doesn't shoot >.<

Here's the shooting functions (and its file)

Code: Select all

#include <OpenGL/OpenGL.h>
#pragma comment(lib, "libMacOSX.a")
#include <irrlicht.h>
#include "GCamera.h"
#include "GGameMain.h"
#include "GWeapon.h"
#include "resPath.h"

/*using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;*/

GWeapon::GWeapon() {
}


GWeapon::~GWeapon() {
}

void GWeapon::setupBullet() {

	GGameMain::getSceneManager();
	GCamera::getCamera();
}


void GWeapon::shootBullet( char** argv ) {
	
	// Starting Point of shot //
	vector3df startPos = GCamera::getCamera()->getPosition();
	// End Point of Shot - must be normalized when shot //
	vector3df endPos = ( GCamera::getCamera()->getTarget() - startPos );
	// Whether the Shot Collides //
	bool hitIsTrue = false;
	
	endPos.normalize();
	startPos += endPos*5.0f;
	endPos = startPos + ( endPos*GCamera::getCamera()->getFarValue() );
	
	/******************************* 
		*	Used Determining Collision *
		*******************************/
	triangle3df tri;
	line3d<f32> ray( startPos, endPos );
	ITriangleSelector* collisionSelector;
	
	if( GGameMain::getSceneManager()->getSceneCollisionManager()->getCollisionPoint( ray, collisionSelector, endPos, tri ) ) {
		hitIsTrue = true;
		vector3df temp = tri.getNormal();
		temp.setLength(0.03f);
		collisionVector = temp;
		collisionPos = endPos;
	} else {
		//Doesn't collide with wall
		endPos = ( GCamera::getCamera()->getTarget() - startPos );
		endPos.normalize();
		endPos = startPos + ( endPos*1000 );
	}
	
	
	ILightSceneNode* redLight = GGameMain::getSceneManager()->addLightSceneNode( 0, core::vector3df(0,0,0), video::SColorf(0.5f, 1.0f, 0.5f, 0.0f), 200.0f);
	ISceneNodeAnimator* Anim = GGameMain::getSceneManager()->createFlyStraightAnimator( startPos, endPos, 1800, false );
	redLight->addAnimator(Anim);
	Anim->drop();
	// attach billboard to the red light
	ISceneNode* bill = GGameMain::getSceneManager()->addBillboardSceneNode(redLight, dimension2d<f32>(60, 60));
	bill->setMaterialFlag(video::EMF_LIGHTING, false);
	bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
	bill->setMaterialTexture(0, GGameMain::getDriver()->getTexture( resPath( argv, "particlered.bmp"))); // needs to use getRes()
		
	// add gray light
	ISceneNode* grayLight = GGameMain::getSceneManager()->addLightSceneNode(0, vector3df(0,0,0), SColorf(1.0f, 0.2f, 0.2f, 0.0f), 200.0f);
	// add fly fly straight animator to the gray light
	Anim = GGameMain::getSceneManager()->createFlyStraightAnimator( startPos, endPos, 1800, false );
	grayLight->addAnimator(Anim);
	Anim->drop();
	
	// attach billboard to light
	bill = GGameMain::getSceneManager()->addBillboardSceneNode(grayLight, dimension2d<f32>(120, 120));
	bill->setMaterialFlag(video::EMF_LIGHTING, false);
	bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
	bill->setMaterialTexture(0, GGameMain::getDriver()->getTexture( resPath( argv, "particlewhite.bmp" ))); //Needs resPath()
	
	// add particle system
	IParticleSystemSceneNode* shotParticle = GGameMain::getSceneManager()->addParticleSystemSceneNode(false, grayLight);
	shotParticle->setParticleSize(dimension2d<f32>(30.0f, 40.0f));
	
	// create and set emitter
	IParticleEmitter* shotEmmiter = shotParticle->createBoxEmitter(
														aabbox3d<f32>(-3,0,-3,3,1,3), 
														vector3df(0.0f,0.03f,0.0f),
														80,100, 
														SColor(0,255,255,255), SColor(0,255,255,255),
														400,1100 );
	shotParticle->setEmitter(shotEmmiter);
	shotEmmiter->drop();
	
	// create and set affector
	IParticleAffector* shotAffector = shotParticle->createFadeOutParticleAffector();
	shotParticle->addAffector(shotAffector);
	shotAffector->drop();
	
	// adjust some material settings
	shotParticle->setMaterialFlag(video::EMF_LIGHTING, false);
	shotParticle->setMaterialTexture(0, GGameMain::getDriver()->getTexture( resPath( argv, "fireball.bmp" ))); //needs resPath()
	shotParticle->setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA);
}


vector3df GWeapon::getCollisionOfBullet() {
	
	return collisionPos;
}
Any idea why it doesn't work (I tried using the "flame" in the per pixel lighting tutorial)?

Edit - Oh, here is the code that checks whether space is pressed, and it should shoot

Code: Select all

	//Shoot if mouse is clicked //
	if ((event.EventType == EET_KEY_INPUT_EVENT &&
		 event.KeyInput.Key == KEY_SPACE &&
		 event.KeyInput.PressedDown == false) )
	{
		// setup shot 
		Player.gun.setupBullet();
		// shoot
		Player.gun.shootBullet( argv );
	}
bronxbomber92
Posts: 27
Joined: Mon Oct 30, 2006 11:55 pm

Post by bronxbomber92 »

Anyone have an idea?
Post Reply