Translating Child Object3D

Started by paulscode, December 28, 2008, 10:29:45 PM

Previous topic - Next topic

paulscode

I have noticed that translating a child Object3D does not take the parent's rotations into account.  Is this a bug, or do I just need to account for parent rotations "manually"?

EgonOlsen

I think it's a feature, but i'm not 100% sure if i really understand what you mean exactly. Maybe a little drawing would help!? 

paulscode

Oh, sorry, here is a simple test case:

http://www.paulscode.com/source/TranslateChild/

The direction of the translation vector in this case is from the base parent cube to toward the small target cube.  As you can see, the child cube moves in the wrong direction if the parent cube has been rotated with the mouse (i.e. in object space instead of world space).

Source code for the applet:
http://www.paulscode.com/source/TranslateChild/TranslateChild.java

How would I go about compensating for the parent rotations?  It seems that the computations could get complicated if the object in question is a "great great grandchild" for example.

EgonOlsen

#3
Ok, you managed to confuse me for a while, but the behavior is actually correct...albeit confusing. The "problem" is: The translation of the child gets rotated. It has to, because otherwise it would be impossible to keep the three objects in place when rotating the parent. Would it be different, this


target.translate( 0, -1.2f, 0 );
child.translate( 0, -3, 0 );


wouldn't work when the parent rotates, because the translations would have to change constantly to keep the objects in place. In your case, this either means that you have to use a static translation (0,1,0) and (0,-1,0) and it will work, or, if that's not an option because the actual case is more complicated, revert the rotation like so (works only in this simple way, if the world transformation matrix contains no translations...if it does, you have to set them to 0 before using Matrix.set(...)) :


direction.matMul(parent.getWorldTransformation().invert3x3());

paulscode

#4
Thanks, that works nicely!

Here is the method I came up with, if anyone is interested:

    private void translateChild( Object3D childObject, SimpleVector translation )
    {
        Object3D[] parentObjects = childObject.getParents();
        if( parentObjects == null || parentObjects.length == 0 )
        {
            childObject.translate( translation );
            return;
        }

        Object3D parentObject = parentObjects[0];
       
        Matrix m = new Matrix( parentObject.getWorldTransformation() );
        float[] dm = m.getDump();
        for( int i = 12; i < 15; i++ )
        {
            dm[i] = 0;
        }
        dm[15] = 1;
        m.setDump( dm );
       
        SimpleVector worldTranslation = new SimpleVector( translation );
        worldTranslation.matMul( m.invert3x3() );
        childObject.translate( worldTranslation );
    }