Shooting Projectiles

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
GameDude
Posts: 500
Joined: Thu May 24, 2007 12:24 am

Shooting Projectiles

Post by GameDude »

Hello,

So I am kinda confused on how to shoot projectiles in 3D using Irrlicht. I know how to shoot projectiles in 2D, but its different with 3D. I'm using Irrlicht and Bullet Physics. I've done the tutorial on using Bullet physics with Irrlicht, but what I'd like to do, is to be able to shoot boxes when the user presses the left mouse button.

Code: Select all

 
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <iostream>
 
#include <irrlicht.h>
 
#include <btBulletDynamicsCommon.h>
#include <btBulletCollisionCommon.h>
 
using namespace std;
 
using namespace irr;
using namespace core;
using namespace video;
using namespace scene;
using namespace io;
using namespace gui;
 
static void CreateStart();
static void CreateBox(const btVector3 &TPosition, const vector3df &TScale, btScalar TMass);
static void CreateSphere(const btVector3 &TPosition, btScalar TRadius, btScalar TMass);
static void UpdatePhysics(u32 TDeltaTime);
static void UpdateRender(btRigidBody* TObject);
static void ClearObjects();
static int GetRandInt(int TMax) {return rand() % TMax;}
 
static bool Done = false;
static btDiscreteDynamicsWorld* World;
static IrrlichtDevice* Device;
static IVideoDriver* Driver;
static ISceneManager* Smgr;
static IGUIEnvironment* Env;
static ITimer* Timer;
static list <btRigidBody*> Objects;
 
class MainEvent : public IEventReceiver 
{
public:
 
    virtual bool OnEvent(const SEvent &event)
    {
        if(event.EventType == EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown)
        {
            switch(event.KeyInput.Key)
            {
            case KEY_ESCAPE:
                Done = true;
            break;
            case KEY_KEY_1:
                CreateBox(btVector3(GetRandInt(10) - 5.0f, 7.0f, GetRandInt(10) - 5.0f), vector3df(GetRandInt(3) + 0.5f, GetRandInt(3) + 0.5f, GetRandInt(3) + 0.5f), 1.0f);
            break;
            case KEY_KEY_2:
                CreateSphere(btVector3(GetRandInt(10) - 5.0f, 7.0f, GetRandInt(10) - 5.0f), GetRandInt(5) / 5.0f + 0.2f, 1.0f);
            break;
            case KEY_KEY_X:
                CreateStart();
            break;
            default:
                return false;
            break;
            }
 
            return true;
        }
 
        return false;
     }
};
 
int main(int argc, char* argv[])
{
    MainEvent receiver;
 
    Device = createDevice(EDT_DIRECT3D9, dimension2d<u32>(800,600), 32, false, false, false, &receiver);
    
    Env = Device->getGUIEnvironment();
    Timer = Device->getTimer();
    Smgr = Device->getSceneManager();
    Driver = Device->getVideoDriver();
 
    btDefaultCollisionConfiguration* collisionConfig = new btDefaultCollisionConfiguration();
    btBroadphaseInterface* broadphase = new btAxisSweep3(btVector3(-1000,-1000,-1000), btVector3(1000,1000,1000));
    btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfig);
    btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver();
    World = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfig);
 
    ICameraSceneNode* Cam = Smgr->addCameraSceneNodeFPS(0,100,10);
    Cam->setPosition(vector3df(0,5,-5));
    Cam->setTarget(vector3df(0,0,0));
 
    Smgr->addLightSceneNode(0,vector3df(2,5,-2), SColorf(4,4,4,1));
    CreateStart();
 
    u32 TimeStamp = Timer->getTime(), DeltaTime = 0;
    while(!Done)
    {
        DeltaTime = Timer->getTime() - TimeStamp;
        TimeStamp = Timer->getTime();
 
        UpdatePhysics(DeltaTime);
 
        Driver->beginScene(true,true,SColor(255,20,0,0));
        Smgr->drawAll();
        Env->drawAll();
        Driver->endScene();
 
        Device->run();
    }
 
    ClearObjects();
    delete World;
    delete solver;
    delete dispatcher;
    delete broadphase;
    delete collisionConfig;
 
    return 0;
}
 
void UpdatePhysics(u32 TDeltaTime)
{
    World->stepSimulation(TDeltaTime * 0.001f, 60);
 
    for(list<btRigidBody*>::Iterator it = Objects.begin(); it != Objects.end(); ++it)
    {
        UpdateRender(*it);
    }
}
 
void CreateStart()
{
    ClearObjects();
    CreateBox(btVector3(0.0f,0.0f,0.0f), vector3df(10.0f,0.5f,10.0f), 0.0f);
}
 
void CreateBox(const btVector3 &TPosition, const vector3df &TScale, btScalar TMass)
{
    ISceneNode* Node = Smgr->addCubeSceneNode(1.0f);
    Node->setScale(TScale);
    Node->setMaterialFlag(EMF_LIGHTING,1);
    Node->setMaterialFlag(EMF_NORMALIZE_NORMALS, true);
    
    btTransform Transform;
    Transform.setIdentity();
    Transform.setOrigin(TPosition);
 
    btDefaultMotionState *MotionState = new btDefaultMotionState(Transform);
 
    btVector3 HalfExtents(TScale.X * 0.5f, TScale.Y * 0.5f, TScale.Z * 0.5f);
    btCollisionShape* Shape = new btBoxShape(HalfExtents);
 
    btVector3 LocalInertia;
    Shape->calculateLocalInertia(TMass,LocalInertia);
 
    btRigidBody* RigidBody = new btRigidBody(TMass,MotionState,Shape,LocalInertia);
 
    RigidBody->setUserPointer((void*)(Node));
 
    World->addRigidBody(RigidBody);
    Objects.push_back(RigidBody);
}
 
void CreateSphere(const btVector3 &TPosition, btScalar TRadius, btScalar TMass)
{
    ISceneNode* Node = Smgr->addSphereSceneNode(TRadius,32);
    Node->setMaterialFlag(EMF_LIGHTING,1);
    Node->setMaterialFlag(EMF_NORMALIZE_NORMALS, true);
 
    btTransform Transform;
    Transform.setIdentity();
    Transform.setOrigin(TPosition);
 
    btDefaultMotionState* MotionState = new btDefaultMotionState(Transform);
 
    btCollisionShape* Shape = new btSphereShape(TRadius);
 
    btVector3 LocalInertia;
    Shape->calculateLocalInertia(TMass,LocalInertia);
 
    btRigidBody* RigidBody = new btRigidBody(TMass,MotionState,Shape,LocalInertia);
 
    RigidBody->setUserPointer((void*)(Node));
 
    World->addRigidBody(RigidBody);
    Objects.push_back(RigidBody);
}
 
void UpdateRender(btRigidBody* TObject)
{
    ISceneNode* Node = static_cast<ISceneNode*>(TObject->getUserPointer());
 
    btVector3 Point = TObject->getCenterOfMassPosition();
    Node->setPosition(vector3df((f32)Point[0], (f32)Point[1], (f32)Point[2]));
 
    vector3df Euler;
    const btQuaternion& TQuat = TObject->getOrientation();
    quaternion q(TQuat.getX(), TQuat.getY(), TQuat.getZ(), TQuat.getW());
    q.toEuler(Euler);
    Euler *= RADTODEG;
    Node->setRotation(Euler);
}
 
void ClearObjects()
{
    for(list<btRigidBody *>::Iterator Iterator = Objects.begin(); Iterator != Objects.end(); ++Iterator) {
        btRigidBody *Object = *Iterator;
 
        ISceneNode *Node = static_cast<ISceneNode *>(Object->getUserPointer());
        Node->remove();
 
        World->removeRigidBody(Object);
 
        delete Object->getMotionState();
        delete Object->getCollisionShape();
        delete Object;
    }
 
    Objects.clear();
}
 
As you can see, this is code from the tutorial. I did add a couple things here and there. Of course my main issue is wanting to be able to shoot the boxes as projectiles. If anyone could give me some pointers or help, I'd greatly appericate it.
CuteAlien
Admin
Posts: 9926
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Shooting Projectiles

Post by CuteAlien »

You didn't mention yet where your problem is... catching the left mouse button? Or calculating a trajectory for your boxes? Or creating them? Or memory management for them? Or using forces in Bullet?

You have to give us at least some hint where you are stuck when you ask for help ;-)

(also post doesn't exactly belong in the advanced section)
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
GameDude
Posts: 500
Joined: Thu May 24, 2007 12:24 am

Re: Shooting Projectiles

Post by GameDude »

Sorry, I didn't know where the post should go. And There's nothing wrong with the code. I'm just trying to figure out how to shoot projectiles using Bullet Physics and Irrlicht. Do I use particles, do I need to use a CameraScenenode?
Neirdan
Posts: 39
Joined: Tue Aug 14, 2012 10:29 pm

Re: Shooting Projectiles

Post by Neirdan »

I made rockets, bullets, grenades, mines and lasers using bullet + irrlicht.
It depends.
Rocket is basically a 3D mesh + a particle emitter attached that creates the trail.
Bullets are simple meshes, same for grenades and mines.

Lasers work differently since it's just an instant ray from A to B (no beam).
GameDude
Posts: 500
Joined: Thu May 24, 2007 12:24 am

Re: Shooting Projectiles

Post by GameDude »

So would I like use a ray-tracer or something like that? I know how to shoot bullets in 2D

Code: Select all

 
int bullet_x = 10,bullet_y = 10;
int bullet_speed = 0;
 
if(user_presses_key)
{
 bullet_speed = 10
  bullet_x = bullet_x + bullet_speed
}
 
The above is just a rough example of how I'd shoot a bullet in 2D. Its different for 3D of course. Which what I am trying to figure out.
arnir
Competition winner
Posts: 154
Joined: Sat Jan 20, 2007 4:36 pm
Location: Czech Republic

Re: Shooting Projectiles

Post by arnir »

Code: Select all

//as you mention the 2D way, 3D has one more coordinate
float bullet_x = 10;
float bullet_y = 10;
float bullet_z = 10;
 
//which can be packed into vector
vector3df bullet(bullet_x, bullet_y, bullet_z);
 
//because we are now in 3D, bullet can move
//every direction in 3D space. because of that
//we cannot use one number to set direction,
//we need 3 numbers - vector again.
//here's the example of vector facing "up" direction (Y)
vector3df dir(0, 1, 0);
 
//no initial movement
float bullet_speed = 0.0f;
 
//if user press key
if(user_presses_key)
{
    //setup new bullet speed
    bullet_speed = 5.0f;
}
 
//and now move bullet in given direction at given speed
bullet = bullet + dir*bullet_speed;
 
programmer is bad designer
designer is bad programmer
GameDude
Posts: 500
Joined: Thu May 24, 2007 12:24 am

Re: Shooting Projectiles

Post by GameDude »

Thank you, I will try something along those lines.
Post Reply