simple ball trajectory calculation

Post your questions, suggestions and experiences regarding game design, integration of external libraries here. For irrEdit, irrXML and irrKlang, see the
ambiera forums
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Re: thanks a lot for replies, great community :)

Post by rogerborg »

robertgarand wrote:Then I would just have to "throw" the shell and wait for impact with the collision manager
And I'd like Alyson Hannigan oiled up and duct-taped to my bed, but life is cruel.

You can use a collision response animator, but it might not do everything that you want. Remember that Irrlicht is a 3d engine, not a game engine.

Code: Select all

#include <irrlicht.h>
#include <iostream>

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

#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#endif

class MyEventReceiver : public IEventReceiver
{
public:
    // This is the one method that we have to implement
    virtual bool OnEvent(const SEvent& event)
    {
        // Remember whether each key is down or up
        if (event.EventType == irr::EET_MOUSE_INPUT_EVENT)
        {
            if(EMIE_LMOUSE_PRESSED_DOWN == event.MouseInput.Event)
                LeftButtonIsDown = true;
            else if(EMIE_LMOUSE_LEFT_UP == event.MouseInput.Event)
                LeftButtonIsDown = false;
        }

        return false;
    }

    // This is used to check whether a key is being held down
    virtual bool IsLeftButtonDown() const
    {
        return LeftButtonIsDown;
    }

    MyEventReceiver()
    {
        LeftButtonIsDown = false;
    }

private:
    bool LeftButtonIsDown;
};

int main()
{
    MyEventReceiver receiver;
    IrrlichtDevice *device = createDevice(EDT_OPENGL, core::dimension2d<s32>(800, 600));
    device->setEventReceiver(&receiver);

    video::IVideoDriver* driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();

    device->getFileSystem()->addZipFileArchive("../../media/map-20kdm2.pk3");

    scene::IAnimatedMesh* mesh = smgr->getMesh("20kdm2.bsp");
    scene::ISceneNode* world = smgr->addOctTreeSceneNode(mesh->getMesh(0), 0, -1, 128);
    world->setPosition(core::vector3df(-1300,-144,-1249));

    ICameraSceneNode * camera = smgr->addCameraSceneNodeFPS();
    camera->setPosition(core::vector3df(20,10,20));
    device->getCursorControl()->setVisible(false);

    IBillboardSceneNode * projectile = smgr->addBillboardSceneNode();
    projectile->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR );
    projectile->setMaterialTexture(0, driver->getTexture("../../media/particle.bmp"));
    projectile->setMaterialFlag(video::EMF_LIGHTING, false);
    projectile->setSize(core::dimension2d<f32>(20.0f, 20.0f));

    ITriangleSelector * selector = smgr->createOctTreeTriangleSelector(mesh->getMesh(0), world);

    ISceneNodeAnimatorCollisionResponse * cameraAnimator 
        = smgr->createCollisionResponseAnimator(selector, camera, vector3df(30, 60, 30),
                                                vector3df(0, -0.1f, 0));
    camera->addAnimator(cameraAnimator);
    cameraAnimator->drop();

    ISceneNodeAnimatorCollisionResponse * projectileAnimator
        = smgr->createCollisionResponseAnimator(selector, projectile, vector3df(5, 5, 5),
                                                vector3df(0, -0.1f, 0));
    selector->drop();
    projectile->addAnimator(projectileAnimator);
    projectileAnimator->drop();

    projectile->setVisible(false);
    f32 const PROJECTILE_SPEED = 200.f;
    u32 then = device->getTimer()->getTime();
    vector3df flightVector(0,0,0);

    while(device->run())
    {
        u32 now = device->getTimer()->getTime();
        f32 delta = (now - then) / 1000.f;
        then = now;

        if(!projectile->isVisible() && receiver.IsLeftButtonDown())
        {
            flightVector = PROJECTILE_SPEED * (camera->getTarget() - camera->getAbsolutePosition()).normalize();
            projectile->setPosition(camera->getAbsolutePosition());
            projectile->updateAbsolutePosition();
            projectile->setVisible(true);
        }

        driver->beginScene(true, true, video::SColor(0,200,200,200));
        smgr->drawAll();
        driver->endScene();

        if(projectile->isVisible())
        {
            // If the projectile isn't falling, it's hit the ground
            if(!projectileAnimator->isFalling())
            {
                projectile->setVisible(false);
            }
            else
            {
                projectile->setPosition(projectile->getAbsolutePosition() + flightVector * delta);
                projectile->updateAbsolutePosition();
            }
        }
    
    }
    
    device->drop();
    return 0;
}

Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
robertgarand
Posts: 69
Joined: Fri Feb 22, 2008 6:47 pm
Location: montreal
Contact:

here is how I made it simple !

Post by robertgarand »

Thanks again to all,
I mixed all answer together and came with this.
this code also include bullet collision detection ! It works great.
direction is a vector3df used as a 3d displacement,
we had gravity multiply by the elapse time, et voilà !
If any question...
regards,
robert

Code: Select all

	core::vector3df end;
	core::vector3df start;
	core::triangle3df triangle;
	core::line3d<f32> line;	
	core::vector3df movement;
	core::vector3df out;
	SParticleImpact imp;
	imp.when = 0;
	now = Device->getTimer()->getTime();
	if (last_time ==0)
		last_time = now - 50;
	f32 lapse = (now - last_time ) * shell_speed;
	if ((now-last_time) < .001)
	{return;
	}
	last_time = now;
	//update les shell
	if (nshell > -1)
	{	
		for ( int i =0; i < max_shell; i++)
			{if (shell[i].isVisible)
[b]
EDIT =>to be replaced
				{
				shell[i].direction = gravity + shell[i].direction;
				movement = shell[i].direction * lapse;
				shell[i].position = movement + shell[i].position;
				shell[i].pshell->setPosition(shell[i].position);
				}
EDIT=>end to be replaced
EDIT=>this routine corrects the framerate side effects from previous
{f32 lapse = now - shell[i].last_time;
				if (lapse < 10) continue;
				shell[i].direction += data_level[current_level].gravityc*lapse;
				movement = shell[i].direction*data_level[current_level].shell_speedc*lapse;
				shell[i].position += movement;
				shell[i].pshell->setPosition(shell[i].position);
				shell[i].last_time = now;
//had misplaced and omit some lapse in calculation
EDIT=> end
[/b]
}

			}
	}
//checking collision with ground
//if so, changing attributes of shell to stop updating
	for ( int i =0; i < max_shell; i++)
	{if (nshell == -1) break;
	start = shell[i].position;
	end = (shell[i].position +  shell[i].direction* 10.0);
	end.normalize();
	start += end*6.0f;
	end = start + (end * 500.0f);
	line.setLine(start,end);
// get intersection point with map
		if ((smgr->getSceneCollisionManager()->getCollisionPoint(
			line, selector, end, triangle))||(shell[i].position.Y < -10))
		{out = triangle.getNormal();
		out.setLength(0.06f);
//getting data for pos, time of impact
		imp.when = 1;
		imp.outVector = out;
		imp.pos = shell[i].position + shell[i].direction;
//one shell less
		shell[i].isVisible = false;
          shell[i].position = deadzone;
          nshell--;
          shell[i].pshell->setVisible(false);
		}
		if (imp.when)
		{
		// create impact note
		imp.when = Device->getTimer()->getTime()+ 100;
		Impacts.push_back(imp);
		}
	}	
	return;
If it can't be writen, it can't exist
Post Reply