Hi,

I am using the Drag handlers with an autotransform on them (see code below). I 
have it set to AutoscaleToScreen. This works great as long as I only have 1 
view of the scene. When I have multiple views though, I get a problem where 
zooming in on one will cause the autotransform to change the scale of the 
dragger. I can click on the dragger just fine in that window, but when I go 
back to the other window and try and click on the dragger it is no longer 
scaled correctly. As an example, if I zoom in to view A then the translate drag 
handler become larger. I can click anywhere on them and they work correctly. 
When I go to View B that is zoomed out then I can click not only on the visual 
representation of the drag handler, but on a projection of it that extends past 
the visual end of the axis. If I do this the opposite way (Zoom out A and look 
at zoomed in B), then the opposite happens. I can only click on the drag 
handler on a smaller portion of the visible axis. 

I looked around and found this post 
(http://forum.openscenegraph.org/viewtopic.php?t=4637&highlight=). 


> 
> The issue you are hitting up against is a limitation of
> osg::AutoTransform in that it only has a single set of state so when
> you have two or more views that require different stats you'll get
> issues with both views attempting to sets it's value. The only way to
> solve this would be to refactor osg::AutoTransform to have multiple
> states in some way. 
> 


It looks like this may be related to this problem, but I am not sure. Does 
anyone have any experience with this issue? Is this issue caused by the state 
problem of autotransform? Has anyone else found a way around this problem? Does 
anyone have any suggestions for an easy way to get around this problem without 
redoing the autotransform node?

Here is my drag handler code.

Code:

VsDragger::VsDragger(VsMovableItem *lpParent, BOOL bAllowTranslateX, BOOL 
bAllowTranslateY, BOOL bAllowTranslateZ, 
                                         BOOL bAllowRotateX, BOOL 
bAllowRotateY, BOOL bAllowRotateZ)
{
        if(!lpParent)
                THROW_ERROR(Al_Err_lParentNotDefined, 
Al_Err_strParentNotDefined);

        m_lpVsParent = lpParent;

        //Create the gripperMT and default it to loc=0, rot=0
        m_osgGripperMT = new osg::MatrixTransform();
        osg::Matrix osgMT; osgMT.makeIdentity();
        m_osgGripperMT->setMatrix(osgMT);
        m_osgGripperMT->addChild(this);
        
        _autoTransform = new osg::AutoTransform;
        _autoTransform->setAutoScaleToScreen(true);
        addChild(_autoTransform.get());

        _sizeTransform = new osg::MatrixTransform;
        // Screen coordinates because of AutoTransform parent
        _sizeTransform->setMatrix(osg::Matrix::scale(100, 100, 100));
        _autoTransform->addChild(_sizeTransform.get());

        _tbDragger = new VsTrackballDragger(bAllowRotateX, bAllowRotateY, 
bAllowRotateZ); 
        _tbDragger->setName("TrackballDragger");
        //addChild(_tbDragger.get());
        _sizeTransform->addChild(_tbDragger.get());

        _transDragger = new VsTranslateAxisDragger(bAllowTranslateX, 
bAllowTranslateY, bAllowTranslateZ);
        _transDragger->setName("TranslateAxisDragger");
        //addChild(_transDragger.get());
        _sizeTransform->addChild(_transDragger.get());

        this->addDragger(_tbDragger.get());
        this->addDragger(_transDragger.get());
        this->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL, 
osg::StateAttribute::ON);
        this->setParentDragger(getParentDragger()); 
}

VsDragger::~VsDragger(void)
{
}


void VsDragger::setupDefaultGeometry()
{
        _tbDragger->setupDefaultGeometry();
        _transDragger->setupDefaultGeometry(); 

        SetupMatrix();
}

void VsDragger::AddToScene()
{
        SetupMatrix();
        if(m_lpVsParent && m_lpVsParent->RootGroup() && m_osgGripperMT.valid())
                
if(!m_lpVsParent->RootGroup()->containsNode(m_osgGripperMT.get()))
                        
m_lpVsParent->RootGroup()->addChild(m_osgGripperMT.get());
}

void VsDragger::RemoveFromScene()
{
        if(m_lpVsParent && m_lpVsParent->RootGroup() && m_osgGripperMT.valid())
                
if(m_lpVsParent->RootGroup()->containsNode(m_osgGripperMT.get()))
                        
m_lpVsParent->RootGroup()->removeChild(m_osgGripperMT.get());
}

void VsDragger::SetupMatrix()
{
        if(m_lpVsParent && m_lpVsParent->RootGroup() && m_osgGripperMT.valid())
        {
                //This gives the radius of the boundign sphere for the selected 
part.
                //We will multiply that by 2 and then scale the entire dragger 
by that amount.
                //We will also use that setting for the minimum scale of the 
autotransform.
                float fltMaxDim = m_lpVsParent->Physics_GetBoundingRadius();

                Simulator *lpSim = GetSimulator();
                if(fltMaxDim > (lpSim->InverseDistanceUnits()/2.0f))
                        fltMaxDim = (lpSim->InverseDistanceUnits()/2.0f);

                //Use an equation to calculate the radius here. This seemed to 
work best. 
                //I tried several size values and found a good radius scale 
that fit it. Then
                //I did a regression to find this equation of the line for the 
radius.
                float fltRadius = fltMaxDim*0.501794454f + 0.639290375f;

                //We are dividing the number by 100 because we are using a 
_sizeTransform that scales it up by 100.
                _autoTransform->setMinimumScale( (fltRadius*0.01f) );

                //We use the final matrix here instead of local matrix because 
the joint can have an additional offset that
                //must be taken into account when setting up the dragger.
                m_osgGripperMT->setMatrix(m_lpVsParent->FinalMatrix());
                
                //Set the matrix for the dragger back to default.
                osg::Matrix mtNull = osg::Matrix::identity();
                mtNull *= osg::Matrix::scale(fltRadius,fltRadius,fltRadius);
                this->setMatrix(mtNull);

                //Lets setup the grip to zero out the rotation of the body so 
that it points 
                //to the default axis of the parent it is connected to. 
                osg::Matrix tempMT = m_lpVsParent->LocalMatrix(), invMT;
                tempMT.setTrans(osg::Vec3f(0, 0, 0));
                invMT.invert(tempMT);

                //We want to scale the translate axis to be 1.5 times as big as 
the rotate axis dragger.
                // Scale the translate dragger up a bit, otherwise the axes
                // will be in the trackball dragger's sphere and we won't be
                // able to pick them.
                float axesScale = 1.5;
                invMT = invMT * 
osg::Matrix::scale(axesScale,axesScale,axesScale);

                _transDragger->setMatrix(invMT);
        }
}




Thank you!

Cheers,
David

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=41431#41431





_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to