Page 1 of 1

Shooting Query

Posted: Wed Nov 01, 2006 10:26 pm
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.

Posted: Wed Nov 01, 2006 10:35 pm
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

Posted: Wed Nov 01, 2006 10:46 pm
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!

Posted: Thu Nov 02, 2006 2:06 am
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.

Posted: Thu Nov 02, 2006 4:37 am
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.

Posted: Thu Nov 02, 2006 8:35 pm
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...

Posted: Tue Nov 21, 2006 2:51 am
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 );
	}

Posted: Tue Nov 21, 2006 10:02 pm
by bronxbomber92
Anyone have an idea?