[fixed in trunk] getCollisonNode() fail in IMetaTriangleSel

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
omegasteffy
Posts: 7
Joined: Sun May 05, 2013 12:06 pm

[fixed in trunk] getCollisonNode() fail in IMetaTriangleSel

Post by omegasteffy »

Hi there.
short:
The getCollisonNode() seem only seem able to parse the first TriangleSelector added to the IMetaTriangleSelector
What to do, am i doing stuff wrong?

Elaborated:
I would like to have a some static nodes to respresent my level/world and some movable nodes.
To get collision detection i create TriangleSelector for all nodes of the level. The smartest way is of course to gather these in a IMetaTriangleSelector

Code: Select all

IMetaTriangleSelector* assembledTriangles = smgr->createMetaTriangleSelector();
ITriangleSelector* staticTriSelector= smgr->createTriangleSelector(myStaticNode->getMesh(),myStaticNode);
ITriangleSelector* staticTriSelector2= smgr->createTriangleSelector(myStaticNode2->getMesh(),myStaticNode2);
assembledTriangles->addTriangleSelector(staticTriSelector2);
assembledTriangles->addTriangleSelector(staticTriSelector);
Afterward a CollisionResponse animator is added to my Moveable node

Code: Select all

ISceneNodeAnimatorCollisionResponse* Anim_collition = smgr->createCollisionResponseAnimator     (assembledTriangles,Node2Move, core::vector3df(5,5,5),gravity, core::vector3df(0,0,0));
    Node2Move->addAnimator(Anim_collition); 
The basic animation works. The moveable nodes are stopped by the static nodes of the level.
However in some case i would like to use a callback mechanism. (e.g. some damage might occur if a truck hit a heavy rock)
For these cases i would like to use getCollisionNode

Code: Select all

class MyColCallback:public ICollisionCallback {
    virtual bool onCollision(   const ISceneNodeAnimatorCollisionResponse &     animator    ) override
    {
        ISceneNode* Node = animator.getCollisionNode();
        std::cout<< "Callback msg. Collision with" << Node->getName() <<std::endl;
        return false;
    }
};
MyColCallback aCallBackClass;
Anim_collition->setCollisionCallback(&aCallBackClass)
However IMetaTriangleSelector parse the first node, no mater swich node i collide with

So far my best option would be to create a seperate animation for each of the staic level nodes.
Last edited by omegasteffy on Mon May 06, 2013 6:54 am, edited 1 time in total.
zprg
Competition winner
Posts: 30
Joined: Tue Jul 31, 2012 12:29 pm
Location: Germany

Re: Collision bug? getCollisonNode() fail with IMetaTriangle

Post by zprg »

in one program i had problems with triangleselector, too and changed to createTriangleSelectorFromBoundingBox and with it everything was working fine, maybe you can try?
omegasteffy
Posts: 7
Joined: Sun May 05, 2013 12:06 pm

Re: Collision bug? getCollisonNode() fail with IMetaTriangle

Post by omegasteffy »

I wil give it a try. But it would not make sense. The problem is the way the IMetaTriangleSelector parse the sub-nodes. NOT indiviual triangleselectors
omegasteffy
Posts: 7
Joined: Sun May 05, 2013 12:06 pm

Re: Collision bug? getCollisonNode() fail with IMetaTriangle

Post by omegasteffy »

damit it works! :-$
After i changed to use the bounding box version the correct node is picked.
To me it still be like a bug in irrlicht
zprg
Competition winner
Posts: 30
Joined: Tue Jul 31, 2012 12:29 pm
Location: Germany

Re: Collision bug? getCollisonNode() fail with IMetaTriangle

Post by zprg »

yes i also think its a bug
Abraxas)
Posts: 227
Joined: Sun Oct 18, 2009 7:24 am

Re: Collision bug? getCollisonNode() fail with IMetaTriangle

Post by Abraxas) »

IMetaTriangleSelector assembledTriangles = smgr->createMetaTriangleSelector();

But do you actually have

IMetaTriangleSelector* assembledTriangles = smgr->createMetaTriangleSelector(); ??
omegasteffy
Posts: 7
Joined: Sun May 05, 2013 12:06 pm

Re: Collision bug? getCollisonNode() fail with IMetaTriangle

Post by omegasteffy »

->Abraxas
I typo happened, as i tried to make reduces no. lines during copy-paste
Fixed now. However i would not even be able to compile:

Code: Select all

IMetaTriangleSelector assembledTriangles = smgr->createMetaTriangleSelector()
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Collision bug? getCollisonNode() fail with IMetaTriangle

Post by hybrid »

Can you create a simple example (full code which compiles properly) and a description how to fix the code? Otherwise it's hard to reproduce and debug this issue.
omegasteffy
Posts: 7
Joined: Sun May 05, 2013 12:06 pm

Re: Collision bug? getCollisonNode() fail with IMetaTriangle

Post by omegasteffy »

It is a simple example (mock-up)
https://subversion.assembla.com/svn/ver ... multiNodes
The code here works, but i have out-commented the "non-Bounding box" version
Switch back to the normal-triangle selector and it would fail.

Code: Select all

// It is not possible to get sub-nodes from the IMetaTriangleSelector if the createTriangleSelector is used
//ITriangleSelector* staticTriSelector=  smgr->createTriangleSelector(myStaticNode->getMesh(),myStaticNode);
//ITriangleSelector* staticTriSelector2= smgr->createTriangleSelector(myStaticNode2->getMesh(),myStaticNode2);
 
ITriangleSelector* staticTriSelector= smgr->createTriangleSelectorFromBoundingBox(myStaticNode);
ITriangleSelector* staticTriSelector2 = smgr->createTriangleSelectorFromBoundingBox(myStaticNode2);
omegasteffy
Posts: 7
Joined: Sun May 05, 2013 12:06 pm

Re: Collision bug? getCollisonNode() fail with IMetaTriangle

Post by omegasteffy »

-> hybrid
Could you find anything wrong in this code?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Collision bug? getCollisonNode() fail with IMetaTriangle

Post by hybrid »

No, sorry, no time yet. Well, actually I completely missed your last post somehow. But will try to test it over the holidays end of this week. Moving to bugs forum to keep this topic recognized.
Strong99
Admin
Posts: 687
Joined: Fri Mar 31, 2006 7:06 pm
Location: Netherlands
Contact:

Re: Collision bug? getCollisonNode() fail with IMetaTriangle

Post by Strong99 »

I can replicate this problem with almost all the collision manager methods.

My default setup:
* Metatriangle selector - total of 1500 triangles
- Triangle selector 1 - 500 triangles
- Triangle selector 2 - 1000 triangles

The issue arises when the nodes in the triangle selector are completely or are partially hidden.

Currently I see two main issues, both are related with the collision manager and the meta triangle selector classes:

Bug #1
The collision manager detects collision against the triangles within its range (line or bounding box). After collision has been detected requests the scenenode for the triangle using its index. (The index comes from the list of triangles within range/line/bbox) and tries to find the triangle id in the list with all triangles resulting that it finds a different triangle on that id.

I described two different lists of triangles the collision manager checks:
1. one which is filtered and contains the same or less triangles than list 2(<= 1500 triangles)
2. one which contains all the triangles (=1500 triangles)

If one of the scenenodes are partially or completely out of sight list 1 contains fewer triangles and thus the index won't be the same as the one in list 2.

Example for the onCollision method:
CSceneCollisionManager.h line 367, get a filtered list of triangles in range

Code: Select all

s32 cnt = 0;
selector->getTriangles(Triangles.pointer(), totalcnt, cnt, ray);
CSceneCollisionManager.h line 409, get triangle from list with all triangles where i is the index of the triangle from filtered list (list 1)

Code: Select all

selector->getSceneNodeForTriangle(i);
A logic change for me would be to include the same filters for the getSceneNodeForTriangle method, giving a ray or boundingbox with it as filter.

Code: Select all

selector->getSceneNodeForTriangle(i, ray);
Bug #2
There is also an error with the getSceneNodeForTriangle method in the CMetaTriangleSelector.h file:

Code: Select all

for (u32 i=0; i<TriangleSelectors.size(); ++i)
{
    u32 totalTriangles += TriangleSelectors[i]->getTriangleCount();
 
    if(totalTriangles > triangleIndex)
        return TriangleSelectors[i]->getSceneNodeForTriangle(0);
}
The error here is that it doesn't pass the index of the triangle to the triangleselector but 0, if the child selector is a meta triangle selector too it will always return the first node it finds rather than the one matching.

One solution could be to give the correct triangle index:

Code: Select all

for (u32 i=0; i<TriangleSelectors.size(); ++i)
{
    u32 triangles = TriangleSelectors[i]->getTriangleCount();
 
    if(totalTriangles + triangles > triangleIndex)
        return TriangleSelectors[i]->getSceneNodeForTriangle(triangleIndex - totalTriangles);
 
    totalTriangles += triangles;
}
My current solution for the collisionmanager:
I created a second method getSceneNodefromTriangleIndex taking a line3df in account:

Code: Select all

//! Return the scene node associated with a given triangle in a filtered list with as filter the line3df
ISceneNode* CMetaTriangleSelector::getSceneNodeForTriangle(u32 triangleIndex, const core::line3d<f32>& line) const
{
    u32 totalTriangles = 0;
 
    for (u32 i=0; i<TriangleSelectors.size(); ++i)
    {
        //Get the list of triangles within reach of the line
        s32 arraySize = TriangleSelectors[i]->getTriangleCount();
 
        core::array<core::triangle3df> triangles;
        triangles.set_used(arraySize);
 
        s32 trianglesCnt;
        TriangleSelectors[i]->getTriangles(triangles.pointer(), arraySize, trianglesCnt, line);
 
        //Default picking based on triangle count, note: also reducing the index for the local selector, otherwise the next selector can's search a subset
        if(totalTriangles + trianglesCnt > triangleIndex)
            return TriangleSelectors[i]->getSceneNodeForTriangle(triangleIndex - totalTriangles, line);
 
        totalTriangles += trianglesCnt;
    }
 
    // For lack of anything more sensible, the index is not here
    return 0;
}
[edit] Added a solution from my custom irrlicht 1.8 build
zprg
Competition winner
Posts: 30
Joined: Tue Jul 31, 2012 12:29 pm
Location: Germany

Re: Collision bug? getCollisonNode() fail with IMetaTriangle

Post by zprg »

good job strong99 sounds you found the ugly bugs in the collision! when will it be in the next irrlichtversion?
polylux
Posts: 267
Joined: Thu Aug 27, 2009 12:39 pm
Location: EU

Re: Collision bug? getCollisonNode() fail with IMetaTriangle

Post by polylux »

Had some similar issue about three years ago. Bit in a hurry atm so I can't confirm it's the same issue. Maybe related?
beer->setMotivationCallback(this);
Strong99
Admin
Posts: 687
Joined: Fri Mar 31, 2006 7:06 pm
Location: Netherlands
Contact:

Re: Collision bug? getCollisonNode() fail with IMetaTriangle

Post by Strong99 »

@polylux they seem closely related as well as the link you provided with an other bugfix by LexManos on #bug1. I can't explain your bug though, as it sounds like you always received the terrain even though it is the last selector added.

@zprg I haven't created a patch for it yet but I'll post one as soon as possible.
Post Reply