[fixed]getCollisionPoint() has gaps at large distances
[fixed]getCollisionPoint() has gaps at large distances
Hello all!
First of all: great engine, great forum! I use Irrlicht for some time now and found always help here when I needed some.
Until now; I saw some strange behaviour of getCollisionPoint() with the following setup:
- load mesh from .3ds file, scale it * 200
- place it far away, about 39000 Irrlicht units from zero point (position(0,0,0))
- create IMeshNode from mesh
- create octree triangle selector from node
- add a camera
Now, in the main loop, I cast a ray from the camera's position straight down through the mesh node (from above bbox to below bbox) and check for a collision point.
When I move the camera with the cursor keys and the mouse, sometimes I do not get a collision with the mesh! There are no holes in the mesh, and when I place it at short distance to zero point, I always get my collision point. The farther away I place my node, the more gaps I get during camera movement.
Is that,like, expected behaviour due to some engine limitations, ore like a floating point issue, or just my dirty code?
Thanks in advance and Best Regards,
dixx
First of all: great engine, great forum! I use Irrlicht for some time now and found always help here when I needed some.
Until now; I saw some strange behaviour of getCollisionPoint() with the following setup:
- load mesh from .3ds file, scale it * 200
- place it far away, about 39000 Irrlicht units from zero point (position(0,0,0))
- create IMeshNode from mesh
- create octree triangle selector from node
- add a camera
Now, in the main loop, I cast a ray from the camera's position straight down through the mesh node (from above bbox to below bbox) and check for a collision point.
When I move the camera with the cursor keys and the mouse, sometimes I do not get a collision with the mesh! There are no holes in the mesh, and when I place it at short distance to zero point, I always get my collision point. The farther away I place my node, the more gaps I get during camera movement.
Is that,like, expected behaviour due to some engine limitations, ore like a floating point issue, or just my dirty code?
Thanks in advance and Best Regards,
dixx
Re: getCollisionPoint() has gaps at large distances
Here is the code of a sample app to reproduce the behaviour:
The mesh can be found at https://github.com/dixx/getCollisionPoi ... sMesh_Test
Code: Select all
/**
* @file getCollisionPointWithScalesMesh_Test.cpp
* @date 04.06.2012
* @author dixx
* @brief Test to locate gaps (points where getCollisionPoint() returns no
* point) within a scaled mesh
*
* Additional information:
* Irrlicht Engine version 1.7.2
* Microsoft Windows XP Professional Service Pack 2 (Build 2600)
* Using renderer: OpenGL 3.3.0
* GeForce GTS 250/PCI/SSE2/3DNOW!: NVIDIA Corporation
* OpenGL driver version is 1.2 or better.
* GLSL version: 3.3
*/
#include <irrlicht.h>
using namespace irr;
f32 getHeight( const f32 x, const f32 z,
scene::ISceneCollisionManager* colliman,
scene::IMeshSceneNode* testNode )
{
core::vector3df collisionPoint = core::vector3df();
core::triangle3df collisionTriangle = core::triangle3df();
const scene::ISceneNode* collisionNode;
// cast a ray from above the bbox of our testNode straight down
// and return the height of the mesh at the given xz coordinates
// or 1000.0f if no collision point was found.
if ( colliman->getCollisionPoint(
core::line3df(
x, testNode->getTransformedBoundingBox().MaxEdge.Y+1.0f, z,
x, testNode->getTransformedBoundingBox().MinEdge.Y-1.0f, z
),
testNode->getTriangleSelector(),
collisionPoint, collisionTriangle, collisionNode ) )
{
return collisionPoint.Y;
}
else
{
return 1000.0f;
}
}
// from the 04.Movement example
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_KEY_INPUT_EVENT)
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
// This is used to check whether a key is being held down
virtual bool IsKeyDown(EKEY_CODE keyCode) const
{
return KeyIsDown[keyCode];
}
MyEventReceiver()
{
for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
KeyIsDown[i] = false;
}
private:
// We use this array to store the current state of each key
bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
int main()
{
scene::IMesh* testMesh;
scene::IMeshSceneNode* testNode;
scene::ITriangleSelector* selector;
core::matrix4 matrix = core::matrix4();
scene::ICameraSceneNode* camera;
core::vector3df cameraOffset = core::vector3df( 0.0f, 2.0f, 0.0f );
MyEventReceiver receiver;
IrrlichtDevice* device = createDevice( video::EDT_OPENGL,
core::dimension2du( 800, 600 ), 32, false, true, false,
&receiver );
if ( device == 0 ) exit( 1 );
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
scene::IMeshManipulator* meshManipulator = smgr->getMeshManipulator();
scene::ISceneCollisionManager* colliman = smgr->getSceneCollisionManager();
// load, scale and place mesh
driver->setTransform( video::ETS_WORLD, core::matrix4() );
testMesh = meshManipulator->createMeshCopy(
smgr->getMesh( "just_a_mesh.3ds" ) );
matrix.setScale( core::vector3df(
200.0f + 0.001f, 200.0f, 200.0f + 0.001f ) );
matrix.setTranslation(
core::vector3df(
99 * 400.0f + 200.0f,
0.0f,
99 * 400.0f + 200.0f
)
);
meshManipulator->transform( testMesh, matrix );
meshManipulator->recalculateNormals( testMesh, true );
// setHardwareMappingHint
for ( register u32 i = 0; i < testMesh->getMeshBufferCount(); ++i )
{
scene::IMeshBuffer* buffer = testMesh->getMeshBuffer( i );
buffer->setHardwareMappingHint( scene::EHM_STATIC );
buffer->setDirty();
buffer->recalculateBoundingBox();
}
// create node from mesh
testNode = smgr->addMeshSceneNode( testMesh );
testMesh->drop();
// set material
testNode->setMaterialTexture(
0, driver->getTexture( "just_a_texture.jpg" ) );
testNode->setMaterialType( video::EMT_SOLID );
testNode->setMaterialFlag( video::EMF_LIGHTING, false );
testNode->setVisible( true );
// add node to collision detection
selector = smgr->createOctreeTriangleSelector(
testNode->getMesh(), testNode, 900 );
testNode->setTriangleSelector( selector );
selector->drop();
// add a camera
camera = smgr->addCameraSceneNodeFPS( 0, 360.0f, 0.01f );
camera->setPosition( core::vector3df(39936.0f, 0.0f, 39755.0f) );
camera->setTarget( camera->getPosition() + core::vector3df( 1.0f, 0.0f, 1.0f ) );
camera->updateAbsolutePosition();
camera->setFarValue( 300.0f );
camera->setNearValue( 0.1f );
camera->setFOV( 1.25f );
camera->setAspectRatio( 4.0f / 3.0f );
camera->setInputReceiverEnabled( true );
smgr->setActiveCamera( camera );
device->getCursorControl()->setVisible( false );
while( device->run() )
{
if ( !device->isWindowActive() ) device->yield();
if ( receiver.IsKeyDown( irr::KEY_ESCAPE ) ) device->closeDevice();
core::vector3df pos = camera->getPosition() - cameraOffset;
pos.Y = getHeight( pos.X, pos.Z, colliman, testNode );
if ( pos.Y > 999.0f ) printf( "gap at x=%f, z=%f!\n", pos.X, pos.Z );
camera->setPosition( pos + cameraOffset );
driver->beginScene( true, true );
smgr->drawAll();
driver->endScene();
}
device->drop();
return 0;
}
Re: getCollisionPoint() has gaps at large distances
Hm, thanks for the test. Unfortunately I need a model now which works with that test... I tried room.3ds from the media-folder but that just gives me a black screen with this code.
I have one bug still left to fix before Irrlicht release about collision, but that was for a very extreme corner-case (and caused by floating point troubles). No idea right now if your problem is related. Certainly not expected to miss collisions.
edit: OK, sorry - didn't see the mesh-link at first. Will try again.
I have one bug still left to fix before Irrlicht release about collision, but that was for a very extreme corner-case (and caused by floating point troubles). No idea right now if your problem is related. Certainly not expected to miss collisions.
edit: OK, sorry - didn't see the mesh-link at first. Will try again.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Re: getCollisionPoint() has gaps at large distances
Draw the bounding box of the node and the ray for testing collision. Then use a second camera to see if something is wrong.
Regards,
smso
Regards,
smso
Re: getCollisionPoint() has gaps at large distances
I can reproduce it with your test, but debugging that will take a while and I can't do that now. But it looks a lot like the triangle bug which I'm already hunting (the currently outcommented part in testTriangle3d in the triangle3d.cpp test). I had a solution for that already, but it broke some other stuff, so working on a new solution. It's a combination of several floating-point troubles actually and one of the handful problems left before we can release 1.8. I'll check your test-case again once I found a better solution for this problem.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Re: getCollisionPoint() has gaps at large distances
CuteAlien, thanks alot for your answer (and the time already invested)!
Would you think it may help to downscale my whole world (collision problem is related to a little game project) or would that result in the same floating point issues? And if I can help with anything (except for debugging) please give me a shout.
smso, thank you too, but bboxes and ray seem to be correct all the time (I did the draw-and-look-from-behind test already).
Would you think it may help to downscale my whole world (collision problem is related to a little game project) or would that result in the same floating point issues? And if I can help with anything (except for debugging) please give me a shout.
smso, thank you too, but bboxes and ray seem to be correct all the time (I did the draw-and-look-from-behind test already).
Re: getCollisionPoint() has gaps at large distances
Sorry don't know about scaling. My old fix was here: http://irrlicht.sourceforge.net/forum/v ... 2&p=263477
(the lines marked as fix). I think the trouble was that this won't work when used with integer types. If you want you can try if that would already solve your problem. But I think I'll probably get to it in a few days anyway.
(the lines marked as fix). I think the trouble was that this won't work when used with integer types. If you want you can try if that would already solve your problem. But I think I'll probably get to it in a few days anyway.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Re: getCollisionPoint() has gaps at large distances
Please try again with newest svn trunk. I checked-in several fixes in revision 4183 and it seems to work with your test so far.
Unless we find another problem it will stay like this and be in Irrlicht 1.8 soon.
Unless we find another problem it will stay like this and be in Irrlicht 1.8 soon.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Re: getCollisionPoint() has gaps at large distances
no bug, try with :
where ray:
Code: Select all
node->setTriangleSelector(selector);
selector->drop();
scene::ISceneCollisionManager* collMan = smgr->getSceneCollisionManager();
core::line3d<f32> ray;
ray.start = camera->getPosition();
ray.end = ray.start + (camera->getTarget() - ray.start).normalize() * 30000.0f;//see here the distance
core::vector3df intersection;
core::triangle3df hitTriangle;
scene::ISceneNode * outNode =
collMan->getSceneNodeAndCollisionPointFromRay(
ray,
intersection, // This will be the position of the collision
hitTriangle, // This will be the triangle hit in the collision
1<<0, // This ensures that only nodes that we have
// set up to be pickable are considered
0); // Check the entire scene (this is actually the implicit default)
where ray:
Code: Select all
core::line3d<f32> ray;
ray.start = camera->getPosition();
ray.end = ray.start + (camera->getTarget() - ray.start).normalize() * 30000.0f; // larger is better
Re: getCollisionPoint() has gaps at large distances
@nespa: I don't know how to interpret your message. With "no bug", do you mean "no, there is a bug"? If so - your code is without any context - I just don't see how it fits into the example above. If it has to do with the example above please explain. If not - then please post a complete example where I can reproduce any problem (I have have no idea what kind of node you have there for example).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Re: getCollisionPoint() has gaps at large distances
I think it is about the setting the size of the ray; if the ray is too short, it doesn't collide his mesh.
Re: getCollisionPoint() has gaps at large distances
I have the feeling we're not talking about the same right now nespa. I did fix a problem in triangle3d which caused the trouble in the code from dixx (and some troubles in other test-cases). That fix is now in latest svn trunk and I'm just wondering if I did catch all cases.
I guess you meant there was no bug in the original code, but that's not correct, there was indeed a problem in Irrlicht caused by some floating point inaccuracies that caused it to miss collisions sometimes when they hit polygons exactly on the border.
I guess you meant there was no bug in the original code, but that's not correct, there was indeed a problem in Irrlicht caused by some floating point inaccuracies that caused it to miss collisions sometimes when they hit polygons exactly on the border.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Re: getCollisionPoint() has gaps at large distances
CuteAlien, nespa, thanks for your help and ideas. I would like to try with newest svn trunk, but am not sure where to go and what to do for this, could you please give me a hint?
Re: getCollisionPoint() has gaps at large distances
@nespa: I start my ray above the highest point of mesh's bbox and end it below the lowest point of bbox. Should be long enough
Re: getCollisionPoint() has gaps at large distances
You first have to get an svn-client. If you are on Windows I would recommend installing TortoiseSVN while on Linux systems I usually use the commandline tools (package name depends on distribution, but usually something like "subversion").
Then on the commandline you can use: svn co https://irrlicht.svn.sourceforge.net/sv ... icht/trunk irrlicht
That will write the trunk (which contains always the version in development) into the folder irrlicht.
With Tortoise on Windows you will have a the svn-client directly in the file-browser and can checkout with right-click (and again need servername like above and some target-folder where you want to put it).
Once you have checked out once you can always update with "svn update" or with TortoiseSVN by right-clicking the folder and selecting update.
You can also browse svn-folders online here: http://sourceforge.net/projects/irrlicht/develop
(note that they give another path to use for check-out which does not contain /trunk, but that will download all versions ever released of Irrlicht which you usually do not want).
Then on the commandline you can use: svn co https://irrlicht.svn.sourceforge.net/sv ... icht/trunk irrlicht
That will write the trunk (which contains always the version in development) into the folder irrlicht.
With Tortoise on Windows you will have a the svn-client directly in the file-browser and can checkout with right-click (and again need servername like above and some target-folder where you want to put it).
Once you have checked out once you can always update with "svn update" or with TortoiseSVN by right-clicking the folder and selecting update.
You can also browse svn-folders online here: http://sourceforge.net/projects/irrlicht/develop
(note that they give another path to use for check-out which does not contain /trunk, but that will download all versions ever released of Irrlicht which you usually do not want).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm