Strange problem with collision

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
WromthraX
Posts: 16
Joined: Fri Feb 13, 2004 2:53 pm

Strange problem with collision

Post by WromthraX »

I have a room made in 3ds max and a ball that acts like a player. All interior in the room and the room itself is a single object.

I've added an octreetriangleselector to the room and set it on my room scene node and I added a collisionresponseanimator to the ball just like with camera in the tutorial with collision detection. Also I have an animator that moves the ball around the room to the place where u click with the mouse but there is a problem..

The ball is moving but it's not colliding with walls or interior of the room, and if i set gravity other than 0 it just falls thru the floor..

I determine the elipsoide radius for collision by substracting MaxEdge and MinEdge of the ball's boundingbox and I divide it by 2. Gravity is -100, speed 100, center of elipsoide is at the center of the ball.

Here is the code i use for that part of program:

Code: Select all

    IAnimatedMeshSceneNode* ball = smgr->addAnimatedMeshSceneNode(smgr->getMesh("data/ball.3ds")); 
        ball->setPosition(vector3df(35,0,185));
        ball->setMaterialFlag(EMF_LIGHTING, false);
    player = ball;

    IAnimatedMesh* floormesh = smgr->getMesh("data/floor.3ds");
    ISceneNode* floor = 0;
    ITriangleSelector* world = 0;
        if (floormesh)
            floor = smgr->addOctTreeSceneNode(floormesh);
        if (floor) {
            floor->setPosition(vector3df(0,0,0));
            floor->setMaterialFlag(EMF_LIGHTING, false);
    world = smgr->createOctTreeTriangleSelector(floormesh->getMesh(0), floor, 128);
    floor->setTriangleSelector(world);
    world->drop();
                    }

    camera = smgr->addCameraSceneNode(0, vector3df(0,150,-100), vector3df(0,0,0));

    vector3df radius = ball->getBoundingBox().MaxEdge - ball->getBoundingBox().MinEdge;
    radius = radius / 2.0f;

    ISceneNodeAnimator* anim =  smgr->createCollisionResponseAnimator(
        world, ball, radius,
        vector3df(0,-100,0), 
        100.0f, 
        vector3df(0,0,0));

        ball->addAnimator(anim);
        anim->drop();
This part of the code goes before while (device->run()) loop. In the loop i determine the position where to move the ball, and in mu onevent when mouse click i have an animator for moving the node to that position.

Where have I made a mistake?
keless
Posts: 805
Joined: Mon Dec 15, 2003 10:37 pm
Location: Los Angeles, California, USA

Post by keless »

you dont 'add the octree selector TO the ROOM'

basically, each object has a collision animator, which has a tri selector. The Tri Selector for each individual Collision Animator is what that animator uses to determine collision.

So to get your ball to collide with the room you:
1) create a collision animator for the ball
2) create an octtree TriSelector from the room
3) attach the TriSel that represents the room to the Ball's Animator

since nothing is colliding with the ball, you do not need to generate a TriSelector that represents the ball
a screen cap is worth 0x100000 DWORDS
WromthraX
Posts: 16
Joined: Fri Feb 13, 2004 2:53 pm

Post by WromthraX »

OK i don't get it at all, from your post i see the error is in this part of code

Code: Select all

IAnimatedMesh* floormesh = smgr->getMesh("data/floor.3ds"); 
    ISceneNode* floor = 0; 
    ITriangleSelector* world = 0; 
        if (floormesh) 
            floor = smgr->addOctTreeSceneNode(floormesh); 
        if (floor) { 
            floor->setPosition(vector3df(0,0,0)); 
            floor->setMaterialFlag(EMF_LIGHTING, false); 
    world = smgr->createOctTreeTriangleSelector(floormesh->getMesh(0), floor, 128); 
    floor->setTriangleSelector(world); 
    world->drop(); 
                    } 
But I did everything you said, I created octreeselector FROM the ROOM (i misstyped this one) :), i can't see the error?.
since nothing is colliding with the ball, you do not need to generate a TriSelector that represents the ball
I haven't done this?!
"Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music."
Kristian Wilson, Nintendo, Inc, 1989.
keless
Posts: 805
Joined: Mon Dec 15, 2003 10:37 pm
Location: Los Angeles, California, USA

Post by keless »

okay, what you're doing wrong:

you are taking the TS that you create FROM the room, and attaching it TO the room. However setting a scene node to 'have' a TriSelector does not actually make anything collide with it-- its just basically storing a pointer to that TS. You now need to actually tell a collision animator to use it.

Specifically, you need to tell your Ball's Collision Animator to use the room's TriSel by calling Ball->collision animator->setworld( room's TS);

Note that this will only allow it to collide with the world. If you wanted to have several balls and have them collide with each other, you'd need to create an IMetaTriangle selector for each moving object and add the world and all moving objects (except for itself) to that IMetaTS, and then call setworld() using that imetats. (create a diff IMTS for EACH object, and a CA for EACH object-- fill in the different IMTSs and send them to the appropriate CAs)

You can see example code doing this in IrrLichtRPG in the AddCreature function of LevelManager ( http://www.skyesurfer.net/keless/IrrLicht/ )
a screen cap is worth 0x100000 DWORDS
WromthraX
Posts: 16
Joined: Fri Feb 13, 2004 2:53 pm

Post by WromthraX »

Sorry if I'm boring but in the createCollisionResponseAnimator function, the first parameter u pass to the function is the TriSelector created from the node with wich u want to collide, am i right?

Code: Select all

virtual ISceneNodeAnimatorCollisionResponse* irr::scene::ISceneManager::createCollisionResponseAnimator  (  ITriangleSelector *    world,
  ISceneNode *    sceneNode,  
  const core::vector3df &    ellipsoidRadius = core::vector3df(30, 60, 30),  
  const core::vector3df &    gravityPerSecond = core::vector3df(0,-100.0f, 0),  
  f32    accelerationPerSecond = 100.0f,  
  const core::vector3df &    ellipsoidTranslation = core::vector3df(0, 0, 0),  
  f32    slidingValue = 0.0005f 
 )  [pure virtual] 
I've done that and it still keeps falling thru the floor...
"Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music."
Kristian Wilson, Nintendo, Inc, 1989.
WromthraX
Posts: 16
Joined: Fri Feb 13, 2004 2:53 pm

Post by WromthraX »

Sorry I haven't seen the message, I was typing the reply ;)

Thanks for help!
"Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music."
Kristian Wilson, Nintendo, Inc, 1989.
WromthraX
Posts: 16
Joined: Fri Feb 13, 2004 2:53 pm

Post by WromthraX »

Hm, i get an error while trying to do ball->anim->setWorld(world)
it says:

`class irr::scene::IAnimatedMeshSceneNode' has no member named `

then i try just

anim->setWorld(world) and then it says:

no matching function for call to `irr::scene::ISceneNodeAnimator

Btw. my collision animator code behaves differently when i put it inside while(device->run()) loop, i guess it should be there..

And another thing, like a said in the post above, i think that the setWorld functions does the same thing like if i would define it in the collisionanimator function.
"Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music."
Kristian Wilson, Nintendo, Inc, 1989.
WromthraX
Posts: 16
Joined: Fri Feb 13, 2004 2:53 pm

Post by WromthraX »

And another thing, the code performes perfectly when I replace the ball scene node in the coollisionresponse animator with my FPS camera. So the camera collides with walls and everything but ball scene node doesn't.

So there must be an error with the ball somewhere...
"Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music."
Kristian Wilson, Nintendo, Inc, 1989.
keless
Posts: 805
Joined: Mon Dec 15, 2003 10:37 pm
Location: Los Angeles, California, USA

Post by keless »

effectively, this is my code (cut and pasted things from different classes so its more straight forward)

Code: Select all

 
mesh = device->getSceneManager()->getMesh(meshName);
m_Node = smgr->addAnimatedMeshSceneNode(m_pMesh);

//create collision selector
irr::scene::IMetaTriangleSelector* metaselector = 
              device->getSceneManager()->createMetaTriangleSelector() ;
//include room-collision
metaselector->addTriangleSelector( lvlTriSel );

//add the tri selectors from other objects to the meta selector
 //**cut**
	
irr::core::aabbox3d<irr::f32> box = m_Node->getBoundingBox();
irr::core::vector3df radius = box.MaxEdge - box.getCenter();
m_CollisionAnim = m_pSmgr->createCollisionResponseAnimator(
    		                    metaselector, m_Node, radius,
                                irr::core::vector3df(0,-100,0), 100.0f
                                );
m_Node->addAnimator(m_CollisionAnim);
m_CollisionAnim->drop();
metaselector->drop();

a screen cap is worth 0x100000 DWORDS
WromthraX
Posts: 16
Joined: Fri Feb 13, 2004 2:53 pm

Post by WromthraX »

I've tried with that code too and I get the same result, ball just drops thru the floor.. thanks for help anyway.

I don't know what to do anymore, so I paste the entire code and if anyone is willing to look over it and tell me if there is any mistake in collision or any other parts of the code that may influence the collision behavior... please tell me... I really can't find it, it is as same as in tutorials :(

Code: Select all

#include <irrlicht.h>

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

#pragma comment(lib, "Irrlicht.lib")

IrrlichtDevice* device = 0;
ICameraSceneNode* camera = 0;
ITriangleSelector* mapa = 0; //TriSel for my level (map)
ISceneNode* player = 0; //SceneNode for the player(ball actually)
vector3df position;

class MyEventReceiver : public IEventReceiver
{
    public:
	virtual bool OnEvent(SEvent event)
	{
        if (event.EventType == EET_MOUSE_INPUT_EVENT && 
            event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) 
            {

//Here i handle the left mouse click
                ISceneManager* smgr = device->getSceneManager();

//Get the curent position of the ball and set as start
                vector3df start = player->getAbsolutePosition();

//Set end position of node after moving
                vector3df end = position;

//Determine time for movement of the ball
                f32 length = (f32)(end - start).getLength();
	              const f32 speed = 0.1f;
                u32 time = (u32)(length / speed);

                ISceneNodeAnimator* anim2 = 0;

//Animate the node(ball)
                anim2 = smgr->createFlyStraightAnimator(start, end, time);
                player->addAnimator(anim2);	
                anim2->drop();
            }
		return false;
    }
};

int main()
{
    MyEventReceiver receiver;

    device = createDevice(EDT_OPENGL, dimension2d<s32>(800, 600), 32, false, false, &receiver);

    IVideoDriver* driver = device->getVideoDriver();
    ISceneManager* smgr = device->getSceneManager();
    IGUIEnvironment* guienv = device->getGUIEnvironment();

//Adding the ball mesh and scene node (i named the ball "lopta")    
    IAnimatedMeshSceneNode* lopta = smgr->addAnimatedMeshSceneNode(smgr->getMesh("data/ball.3ds")); 
        lopta->setPosition(vector3df(35,50,185));
        lopta->setMaterialFlag(EMF_LIGHTING, false);

    player = lopta; //I could set lopta to be global pointer but i'm to lazy :) I need this for movement

//Adding the level mesh
    IAnimatedMesh* floormesh = smgr->getMesh("data/mapa.3ds");
    ISceneNode* floor = 0;
        if (floormesh)
            floor = smgr->addOctTreeSceneNode(floormesh);
        if (floor) {
            floor->setPosition(vector3df(0,0,0));
            floor->setMaterialFlag(EMF_LIGHTING, false);

//Creating TriSel from the level
    mapa = smgr->createOctTreeTriangleSelector(floormesh->getMesh(0), floor, 128);
    floor->setTriangleSelector(mapa);
    mapa->drop();
                    }

    camera = smgr->addCameraSceneNodeFPS(0, 50.0f, 50.0f);

//This is the code kelees gave me...
    IMetaTriangleSelector* metaselector = device->getSceneManager()->createMetaTriangleSelector() ; 

    metaselector->addTriangleSelector( mapa ); 

    aabbox3d<f32> box = lopta->getBoundingBox(); 
    vector3df radius = box.MaxEdge - box.getCenter(); 
    ISceneNodeAnimator* m_CollisionAnim = smgr->createCollisionResponseAnimator(
        metaselector, lopta, radius, 
        vector3df(0,-100,0), 100.0f 
        ); 
    lopta->addAnimator(m_CollisionAnim); 
    m_CollisionAnim->drop(); 
    metaselector->drop(); 

    while(device->run() && driver)
    {
        driver->beginScene(true, true, SColor(255,0,0,0));

//This part determins the position of mouse click
        triangle3df triangle;
        line3d<f32> line;

//Screen coordiates of mouse click
        position2d<s32> cpos = device->getCursorControl()->getPosition();

//Making ray from those coordinates
        line = smgr->getSceneCollisionManager()->getRayFromScreenCoordinates(cpos);

//Geting position of intersection and saving to "position" variable
        smgr->getSceneCollisionManager()->getCollisionPoint(line, mapa, position, triangle);
 
//Some tweeking for placement
        position.X = position.X + 35;
        position.Z = position.Z + 185;

        smgr->drawAll();
        guienv->drawAll();
        driver->endScene();
    }
	device->drop();
	return 0;
}
...and that's it.
"Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music."
Kristian Wilson, Nintendo, Inc, 1989.
disanti
Posts: 367
Joined: Sat Jan 17, 2004 1:36 am
Location: California, US
Contact:

Post by disanti »

Last night I tried to do a fly straight animator after I had a collision responce animator to make my character jump, but instead, when I pressed the jump key, that animator made the character go up and then just completely deleted the collision responce. The character wouldn't fall or anything, just look around because of the FPS camera scene node.

Is this a bug in Irrlicht?
________
Mflb
Last edited by disanti on Tue Feb 22, 2011 7:59 am, edited 1 time in total.
Phunk
Posts: 78
Joined: Sun Dec 14, 2003 8:18 pm
Location: The Netherlands

Post by Phunk »

floor = smgr->addOctTreeSceneNode(floormesh); should be floor = smgr->addOctTreeSceneNode(floormesh->getMesh(0)); maybe that helps
WromthraX
Posts: 16
Joined: Fri Feb 13, 2004 2:53 pm

Post by WromthraX »

Nah, it's the same, but thanks anyway. In 0.4.2 you can just give the name of the mesh.

I don't think that the problem is there because this code works fine when I put FPS camera instead of ball.

Something is wrong with the ball I guess...
"Computer games don't affect kids; I mean if Pac-Man affected us as kids, we'd all be running around in darkened rooms, munching magic pills and listening to repetitive electronic music."
Kristian Wilson, Nintendo, Inc, 1989.
Post Reply