(C++) Editor style object placement

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
bob
Posts: 57
Joined: Fri Jun 08, 2007 4:17 am
Location: Jacksonville, Fl (USA)
Contact:

(C++) Editor style object placement

Post by bob »

This function allows moving an object along any one, two or three axis using it's current position as a reference.

I assume there is probably something like this built into Irrlicht somewhere. Which is why I had such a hard time putting it together from the board. Or it could just be that this is insanely easy for most here, but I'm sure somewhere there's a poor sap like me struggling to learn. :)

Code: Select all

irr::core::vector3df getMouseIntersect2( const irr::core::vector3df &ptCurPos, const irr::core::vector3df &ptAxis, const irr::core::position2di ptMouse )
{
    // Is mouse in the window?
    if ( 0 > ptMouse.X || 0 > ptMouse.Y )
        return ptCurPos;

    // Get mouse line
    irr::core::line3df ml = 
        m_pSm->getSceneCollisionManager()->
                    getRayFromScreenCoordinates( ptMouse, GetCamera() );

    irr::core::vector3df normal, ptNew;

    // Pick an axis we don't need as the normal for the plane
    if ( !ptAxis.X ) normal.X = 1;
    else if ( !ptAxis.Y ) normal.Y = 1;
    else if ( !ptAxis.Z ) normal.Z = 1;

    // Plane faces camera for all axis
    else normal = ml.getVector().normalize();

    // Get mouse line / plane intersection
    if ( !irr::core::plane3df( ptCurPos, normal ).
                    getIntersectionWithLine( ml.getMiddle(), ml.getVector(), ptNew ) )
        return ptCurPos;

    // Revert the axis we don't want to change
    if ( !ptAxis.X ) ptNew.X = ptCurPos.X;
    if ( !ptAxis.Y ) ptNew.Y = ptCurPos.Y;
    if ( !ptAxis.Z ) ptNew.Z = ptCurPos.Z;

    return ptNew;
}
To move the object along the X axis, use

Code: Select all

new_pos = getMouseIntersect( current_position, vector3df( 1, 0, 0 ), mouse_pos );
Or to move the object around on the Z/Y axis

Code: Select all

new_pos = getMouseIntersect( current_position, vector3df( 0, 1, 1 ), mouse_pos );
While I'm at it, here's function to correctly set the object position even if it's a child node.

Code: Select all

        void setAbsolutePosition( irr::scene::ISceneNode *pNode, irr::core::vector3df pos )
        {   if ( !pNode ) return;

            irr::scene::ISceneNode *pParent =  pNode->getParent();
            if ( !pParent ) pNode->setPosition( pos );
            else
            {   irr::core::vector3df v( pos - pParent->getAbsolutePosition() );
                pParent->getAbsoluteTransformation().inverseRotateVect( v );
                pNode->setPosition( v ); 
            } // end else
            pNode->updateAbsolutePosition();
        }
Now you can do something like this, and it will correctly move the object with or without a parent.

Code: Select all

setAbsolutePosition( pNode, 
   getMouseIntersect( pNode->getAbsolutePosition(), vector3df( 1, 0, 0 ), mouse_pos ) );
Midnight
Posts: 1772
Joined: Fri Jul 02, 2004 2:37 pm
Location: Wonderland

Post by Midnight »

nah theres just a shortage of people releasing open source.

I myself am desperately trying to handle my commercial projects and my community projects and the mass of work alone is intimidating.
bob
Posts: 57
Joined: Fri Jun 08, 2007 4:17 am
Location: Jacksonville, Fl (USA)
Contact:

Post by bob »

Well, many thanks for your self-less contributions of digitized wisdom!

May the code goddesses smile upon you in sensual alluring ways.
bob
Posts: 57
Joined: Fri Jun 08, 2007 4:17 am
Location: Jacksonville, Fl (USA)
Contact:

Post by bob »

I was PM'ed on how I was using this code. Not sure it helps a whole lot since It's in Squirrel, but this is my script for creating (and moving) a little XYZ cursor thingy, similar to what you see in 3d editors.

It looks like this...
Image

And it works like this...

Code: Select all

class CCursorXYZ
{
    m_p = 0;

    m_x = 0;
    m_y = 0;
    m_z = 0;

    m_a = 0;
    m_pos = CSiVector( 0., 0., 0. );
    m_dir = 0;

    // Create a direction arrow
    function AddArrow( p, size, r, g, b, rot, pos, dir )
    {
        local arrow = ::_irr.AddArrow( 50., size, size, 16 );    
        ::_irr.SetVertexColors( arrow, 255., r, g, b );
        arrow.setRotation( rot );
        arrow.setPosition( pos );
        arrow.setParent( p );
        arrow.setCallbackFunction2( "onclick", OnClickObj.bindenv( this ), arrow, dir );
        ::_irr.AcceptInput( arrow, 1 );
        return arrow;
    }

    function Create( size )
    {
        ::_irr.SetCallbackFunction( "onbuttonup", OnButtonUp.bindenv( this ) );
        ::_irr.SetCallbackFunction( "onmousemove", OnMouseMove.bindenv( this ) );

        // Add center point
        m_p = ::_irr.AddCylinder( size / 3, size / 3, 16 );
        ::_irr.SetVertexColors( m_p, 255., 255., 255., 0. );
        m_p.setCallbackFunction2( "onclick", OnClickObj.bindenv( this ), m_p, CSiVector( 1., 1., 1. ) );
        ::_irr.AcceptInput( m_p, 1 );

        m_x = AddArrow( m_p, size, 200., 50., 50., 
                        CSiVector( 0., 0., 90. ), CSiVector( -( size + size / 2 ), 0., 0. ),
                        CSiVector( 1., 0., 0. ) );

        m_y = AddArrow( m_p, size, 50., 200., 50., 
                        CSiVector( 0., 0., 0. ), CSiVector( 0., size + size / 2, 0. ),
                        CSiVector( 0., 1., 0. ) );

        m_z = AddArrow( m_p, size, 50., 50., 200., 
                        CSiVector( 90., 0., 0. ), CSiVector( 0., 0., size + size / 2 ),
                        CSiVector( 0., 0., 1. ) );
    }

    function OnButtonUp()
    {
        m_a = 0;
    }

    function OnMouseMove()
    {
        if ( !m_a ) return;

        local intersect = CSiVector( 0., 0., 0. );
        ::_irr.getMouseIntersect( m_pos, m_dir, intersect );
        m_p.setAbsolutePosition( intersect );
     
    }

    function OnClickObj( obj, dir )
    {
        m_a = obj;
        m_a.getAbsolutePosition( m_pos );
        m_dir = dir;
    }

};
Katsankat
Posts: 178
Joined: Sun Mar 12, 2006 4:15 am
Contact:

Post by Katsankat »

Hi,
What is the type of the first variable in the class?
What means m_pos = CSiVector( 0., 0., 0. );
Where could be found the _irr.SetCallbackFunction() function?
I also don't understand the type "function" returned by all functions :shock:
Thanks in advance.
*edit* Ah I get it: it is not C++ but code from your object-oriented scripting language.
bob
Posts: 57
Joined: Fri Jun 08, 2007 4:17 am
Location: Jacksonville, Fl (USA)
Contact:

Post by bob »

You can find the code for the Squirrel classes over here...
Squirrel Bindings

:!: Just my first pass at binding Squirrel and Irrlicht, not a library or SDK.
Post Reply