[fixed]Unexpected clipping with setPosition and setClipPlane

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.
Post Reply
heda
Posts: 10
Joined: Mon Jul 16, 2012 3:28 pm
Location: The Netherlands

[fixed]Unexpected clipping with setPosition and setClipPlane

Post by heda »

Hi there,

When I position a node, which has it's origin at (0.0, 0.0, 0.0) at distance of -10 in the x direction:

Code: Select all

 
IAnimatedMesh* mesh = smgr->getMesh("tree.3ds");
ISceneNode* tree = smgr->addMeshSceneNode(mesh->getMesh(0));
tree->setPosition(core::vector3df(-10.0, 0.0, 0.0));
 
and when I use a clipping plane through the origin, with it's normal in the positive x direction:

Code: Select all

 
plane3df clipPlane = plane3df( 0.0, 0.0, 0.0,    1.0, 0.0, 0.0);
driver->setClipPlane(0, clipPlane, true);
 
then the node is clipped in half, as if it was first clipped, and only then translated to (-10.0, 0.0, 0.0), so I see a half-clipped node at (-10.0, 0.0, 0.0). What am I doing wrong? I've tried calling updateAbsolutePosition() but that didn't help. Any help is appreciated!

Heda
Last edited by heda on Tue Jul 17, 2012 2:30 pm, edited 1 time in total.
heda
Posts: 10
Joined: Mon Jul 16, 2012 3:28 pm
Location: The Netherlands

Re: Unexpected clipping when using setPosition and setClipPl

Post by heda »

It appears that this is a known issue with the OpenGL implementation, see this post:
http://irrlicht.sourceforge.net/forum/v ... hp?t=30776
But so far I didn't find a proposed solution.

A workaround is to adjust the positions of the vertices in the meshbuffer manually like this:

Code: Select all

 
for (u32 cntr = 0; cntr < nov; cntr++)
{
   vector3df pos = meshbuf->getPosition(cntr);
   pos.X = pos.X + 5.0;
   meshbuf->getPosition(cntr) = pos;
}
 
But this means I would need to clone the meshbuffer for each additional tree node, which sounds rather inelegant to me. Any suggestions?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Unexpected clipping when using setPosition and setClipPl

Post by hybrid »

Well, you could use the mesh transformer to offset the vertices by some amount more easily. But it's still not the proper solution. I still have the bug report about clip plane open here, so maybe we can get a correct solution soon.
heda
Posts: 10
Joined: Mon Jul 16, 2012 3:28 pm
Location: The Netherlands

Re: Unexpected clipping when using setPosition and setClipPl

Post by heda »

Thanks for the answer, I looked into the clipping problem a bit better and I noticed in COpenGLDriver.cpp that the clipping plane is updated after the GL_MODELVIEW matrix is set in setTransform():

Code: Select all

 
void COpenGLDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat)
{
    Matrices[state] = mat;
    Transformation3DChanged = true;
 
    switch (state)
    {
    case ETS_VIEW:
    case ETS_WORLD:
        {
            // OpenGL only has a model matrix, view and world is not existent. so lets fake these two.
            glMatrixMode(GL_MODELVIEW);
            glLoadMatrixf((Matrices[ETS_VIEW] * Matrices[ETS_WORLD]).pointer());
            // we have to update the clip planes to the latest view matrix
            for (u32 i=0; i<MaxUserClipPlanes; ++i)
                if (UserClipPlanes[i].Enabled)
                    uploadClipPlane(i);
        }
        break;
 
The GL_MODELVIEW matrix is set to the combined ETS_VIEW and ETS_WORLD matrices, so the uploadClipPlane() applies the clipplane in the local node coordinates. This explains why all nodes are suddenly clipped in half.

I guess a discussion on what would be expected clipping behavior is in order. If I enable a clip plane using driver->setClipPlane(0, clipPlane, true) I expected it to be in world coordinates, especially since it is applied to all nodes in the scene manager. The current implementation makes it very hard to add 100 tree nodes with a different position using setPosition(), and then have one clip plane clipping the forrest. Right now I would have to assign each tree node to a different scene manager, so I can apply a different clip plane to each scene manager.

I think a solution to the problem would be to apply the clip plane only after the GL_MODELVIEW matrix has been set to the ETS_VIEW matrix. This ensures that all clip planes are applied in world coordinates. The proposed code below does this:

Code: Select all

 
void COpenGLDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat)
{
    Matrices[state] = mat;
    Transformation3DChanged = true;
 
    switch (state)
    {
    case ETS_VIEW:
    case ETS_WORLD:
        {
            // OpenGL only has a model matrix, view and world is not existent. so lets fake these two.
            glMatrixMode(GL_MODELVIEW);
 
            // first load the viewing transformations
            glLoadMatrixf((Matrices[ETS_VIEW]).pointer());
 
            // we have to update the clip planes to the latest view matrix
            for (u32 i=0; i<MaxUserClipPlanes; ++i)
               if (UserClipPlanes[i].Enabled)
                  uploadClipPlane(i);
 
            // now load the combined view and world matrices
            glLoadMatrixf((Matrices[ETS_VIEW] * Matrices[ETS_WORLD]).pointer());
        }
        break;
 
And if someone still would like to apply a clip plane in local node coordinates this can be done by setting the plane3df object to the node position.

Is there any chance that the proposed patch can be applied to the next Irrlicht release?

cheers,
heda
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Unexpected clipping when using setPosition and setClipPl

Post by hybrid »

I will check what my test code says. But it sounds like something reasonable. Actually, there's still another problem with the correct time the clipplane upload is called. Because code under OpenGL and DX behaves even different when the model is in the origin. But this might be a start to get a correct behavior for both drivers.
(PS: Moving to bug thread).
heda
Posts: 10
Joined: Mon Jul 16, 2012 3:28 pm
Location: The Netherlands

Re: Unexpected clipping when using setPosition and setClipPl

Post by heda »

I've tested with four simultaneous viewports and moving cameras, and everything behaves beautifully :D If there's anything I can do to help or test, let me know.

Cheers,
heda
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Unexpected clipping when using setPosition and setClipPl

Post by hybrid »

Ok, thanks for the fix. I've commited this and the other fixes for D3D now to SVN/trunk.
BTW: I was unsure if the user clip plane upload is necessary at the projection matrix change as well. Since my test case didn't require it, I've removed this. If someone knows a reason why it might be required, please post here.
Post Reply