[fixed] Issue with collision
[fixed] Issue with collision
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.
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.
-
- Posts: 15
- Joined: Fri Oct 09, 2009 2:54 pm
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...
Maybe 1.61+ will fix this collision problem without breaking something else...
"Mission failed: Your team was wiped out."
I haven't tested this against 1.5.1, but it does exhibit some interesting behavior.
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
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;
}
Travis
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]
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)
{
...
}
....
-
- Admin
- Posts: 14143
- Joined: Wed Apr 19, 2006 9:20 pm
- Location: Oldenburg(Oldb), Germany
- Contact:
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
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
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: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
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...