[fixed] Issue with collision

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.
crosel
Posts: 11
Joined: Fri May 29, 2009 6:53 am

[fixed] Issue with collision

Post by crosel »

Hi,

Im not sure if its just me or not but when i use the function:

getCollisionPoint()

I have inconsisten results. What is strange is, the fact that the results do not occur in 1.5 but only in 1.6

Pretty much, what i do is create a "ray" between a camera and its look at position. It then calls this function based on that ray.

Yet sometimes, something strange happens, in which it wont get the correct object or "end" position. The ray seems to pass through the object im after.

Yet if i move myself (the camera) to a different position, it will work. So it seems depending upon the position of the object, it sometimes work's.

Hope this make sense.

The code is based off the Demo example for shooting, with only small alterations to it to suit my needs.

Does this happen to anyone else?

Cheers.
MarvLeonidasX
Posts: 15
Joined: Fri Oct 09, 2009 2:54 pm

Post by MarvLeonidasX »

Yes I have almost the same problem, but mine is distance based not positional: The node the ray intersects with is only "detected" if the camera is really close to said node. But in 1.51 the collision detection behaves as it should. Now some may say, "Well, if it works in 1.51 but not 1.6 then just use 1.51!" But 1.51 had other issues that 1.6 fixed.

Maybe 1.61+ will fix this collision problem without breaking something else...
"Mission failed: Your team was wiped out."
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

We would need a simply setup which can reproduce the problem. Maybe you can also collect some values which could give a hint about what might fail here. I'll move this thread to the bug forum for confirmation.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

I haven't tested this against 1.5.1, but it does exhibit some interesting behavior.

Code: Select all

#include <irrlicht.h> 
using namespace irr;

#include <stdio.h>

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

int main() 
{ 
  // create device and exit if creation failed 
  IrrlichtDevice *device = createDevice(video::EDT_OPENGL, core::dimension2d<u32>(800, 600), 32, false, false, true); 
  if (device == 0) 
    return 1; // could not create selected driver. 

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

  // add camera 
  scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS();
  camera->setPosition(core::vector3df(30, 30, 30));
  camera->setTarget(core::vector3df(-8.f, 8.f, -8.f));
  camera->setID(0);

  // add a dynamic light (this causes weirdness)
  smgr->addLightSceneNode(0, core::vector3df(4, 4, 4), video::SColorf(.2f, .3f, .2f)); 

  // add a cube to pick
  scene::ISceneNode* cube = smgr->addCubeSceneNode(15);

  while(device->run()) 
  { 
    // window is active, so render scene 
    if (device->isWindowActive()) 
    { 
      if (driver->beginScene(true, true, video::SColor(100, 50, 50, 100))) 
      { 
        smgr->drawAll();

        driver->endScene(); 
      }

      gui::ICursorControl* cursor = device->getCursorControl();
      const core::position2di pos(cursor->getPosition().X, cursor->getPosition().Y);

      // get the line used for picking
      core::line3df ray =
        smgr->getSceneCollisionManager()->getRayFromScreenCoordinates(pos, camera);

      // find a selected node
      scene::ISceneNode* pick = 
        smgr->getSceneCollisionManager()->getSceneNodeFromRayBB(ray, 1);

      core::matrix4 invMat = cube->getAbsoluteTransformation();
      invMat.makeInverse();

      invMat.transformVect(ray.start);
      invMat.transformVect(ray.end);

      const int a_hit = (pick == cube);
      const int b_hit = cube->getBoundingBox().intersectsWithLine(ray);

      wchar_t buf [32];
      _snwprintf (buf, sizeof buf / sizeof *buf, L"%d:%d", a_hit, b_hit);

      device->setWindowCaption(buf);
    } 
  } 

  device->drop(); 

  return 0; 
} 
The testcase does a ray intersection test against a cube in two different ways. It uses the collision manager and a quick box/ray collision check. Ideally, the colon seperated string in the title bar should always be 0:0 because there is no collision, or 1:1 indicating there is a collision. If the two values aren't the same then one of the collision detection techniques isn't working correctly. I frequently see 0:1 which indicates the collision manager isn't detecting the collision.

Travis
mmxx1
Posts: 8
Joined: Thu Nov 05, 2009 7:17 am
Location: Poland

Post by mmxx1 »

Hi,

I've noticed that in my application after upgrade irrlicht engine from 1.5.1 to 1.6, function getSceneNodeFromScreenCoordinatesBB works not completely right.
In my app (shows houses with adding furnitures function) I have orbit camera with zoom function, I've noticed that when i decrease distance (radius) from camera to furniture (added earlier to the scene) function getSceneNodeFromScreenCoordinatesBB recognizes it and works fine, but when I increase distance from camera to the added sceneNode, function getSceneNodeFromScreenCoordinatesBB doesn't see my node under mouse position.
I must fly with my camera relatively close to the node to pick it by mouse.

I use this code :

Code: Select all


irr::scene::ISceneNode* sn = smgr->getSceneCollisionManager()->getSceneNodeFromScreenCoordinatesBB(
						irr::core::position2d<irr::s32>(
device->getCursorControl()->getPosition().X,
device->getCursorControl()->getPosition().Y
),
1<<30,
false,
0
);
if(sn) 
{
...
}
....
[/code]
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Yes, this method calls getSceneNodeFromRayBB internally, so would show similar problems. The method which seems to have made the change is getPickedNodeBB, which is used by all the other methods.
Edit: Found the problem. It's the early out block in line 104, which does an object space test with isPointInside. When disabling this test the example runs without problems. I hope vitek can explain what's wrong with this part :wink:
mmxx1
Posts: 8
Joined: Thu Nov 05, 2009 7:17 am
Location: Poland

Post by mmxx1 »

Great that this part of irrlicht functionality has been fixed :)
Hope official fix release 1.6.1 will be available soon, because my app is a commercial product.
Greetings
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

I'll probably just disable that part in 1.6, as fixing the code might introduce even more problems. Depends on the necessary code changes. Anyway, 1.6.1 will have this fixed some way.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

hybrid wrote:I hope vitek can explain what's wrong with this part :wink:
I'll have to take some time to look at it. The logic seems reasonable, but the start of the ray most definitely should not be inside the bounding box in my testcase.

Travis
Mequa
Posts: 13
Joined: Fri Jul 07, 2006 7:39 pm

Post by Mequa »

hybrid wrote:Yes, this method calls getSceneNodeFromRayBB internally, so would show similar problems. The method which seems to have made the change is getPickedNodeBB, which is used by all the other methods.
Edit: Found the problem. It's the early out block in line 104, which does an object space test with isPointInside. When disabling this test the example runs without problems. I hope vitek can explain what's wrong with this part :wink:
I can confirm that this fixes the problem. The file in question here is (from the extracted archive) irrlicht-1.6\source\Irrlicht\CSceneCollisionManager.cpp , from line 104:

if(objectBox.isPointInside(objectRay.start))
{
// If the line starts inside the box, then consider the distance as being
// to the centre of the box.
const f32 toIntersectionSq = objectRay.start.getDistanceFromSQ(objectBox.getCenter());
if(toIntersectionSq < outbestdistance)
{
outbestdistance = toIntersectionSq;
outbestnode = current;

// And we can truncate the ray to stop us hitting further nodes.
ray.end = ray.start + (rayVector * sqrtf(toIntersectionSq));
}
}
else if (objectBox.intersectsWithLine(objectRay))
{
.............

To fix this, simply comment out the relevant section of code so it looks like this:

/*if(objectBox.isPointInside(objectRay.start))
{
// If the line starts inside the box, then consider the distance as being
// to the centre of the box.
const f32 toIntersectionSq = objectRay.start.getDistanceFromSQ(objectBox.getCenter());
if(toIntersectionSq < outbestdistance)
{
outbestdistance = toIntersectionSq;
outbestnode = current;

// And we can truncate the ray to stop us hitting further nodes.
ray.end = ray.start + (rayVector * sqrtf(toIntersectionSq));
}
}
else */ if (objectBox.intersectsWithLine(objectRay))
{
.............

Save the file, then open Irrlicht.dev (for Dev-CPP) or Irrlicht9.0.vcproj (for Visual Studio 2008), Release (not Debug) mode, and select Rebuild All.
(You may also need to install the latest DirectX SDK for Direct3D9 support, plus an older version if you want to build support for Direct3D8, and add the relevant Include and Library directories).

Assuming the process completed successfully, the fixed Irrlicht.dll will be found in the appropriate folder under irrlicht-1.6\bin\ (either Win32-gcc or Win32-VisualStudio).
Copy this over to your game/application's working folder (or alternatively static link), and voila! Working bounding box collisions even between the camera's line of view and billboard nodes (as my app required), which I can confirm was broken in the 1.6 build I downloaded and fixed by this method...
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Ah yes, almost forgot about this problem. I've disabled the test for now, just as shown above. We'll have to check this later on.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Please note that I had to revert this change, as it caused another regression. Thus I'm not sure if this issue can be fixed in 1.6, or will have to wait for 1.7.
mmxx1
Posts: 8
Joined: Thu Nov 05, 2009 7:17 am
Location: Poland

Post by mmxx1 »

What consequences (damages) in other parts of Irrlicht will bring this change in CSceneCollisionManager.cpp ?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Which change, the first one proposed or my revert? The revert undid all changes made between 1.6 release and now, so the situation will be the same as for the official SDK. I don't know which things are broken since then exactly, I've seen just one so far (as documented above).
mmxx1
Posts: 8
Joined: Thu Nov 05, 2009 7:17 am
Location: Poland

Post by mmxx1 »

So what is your suggestion to fix this - come back to 1.5.1 or comment (if(objectBox.isPointInside(objectRay.start)) .... ) CSceneCollisionManager.cpp or wait for 1.7 (how long) ?
Post Reply