SoRayPickAction in Open Inventor?

Sorry if this is a repeat, but I'm trying to figure out the implementation of SoRayPickAction in Open Inventor. I'm trying to implement it so that when I click on the mouse, select a specific node, after which I can translate, rotate, etc. I have three nodes: a table, a lamp and a frame (frame with pictures). However, I do not think my code is ok. I also have various methods such as MouseButtonCallback (which will check if the mouse is clicked and then use the navigator) and MouseMoveCallback (the same idea). So here is the code that I have, but do you have any suggestions? Right now, well, he's not doing anything.

SbViewportRegion viewport(400,300); 
    SoRayPickAction m(viewport); 
    m.setRay(SbVec3f(0.0,0.0,0.0), SbVec3f(0.0,0.0,-1.0));
    m.apply(callback_node);
    const SoPickedPoint *mpp = m.getPickedPoint(); 
    if(mpp != NULL) {
        std::cout << "test" << std::endl;
    }

Can you also learn about an action in OpenInventor that can "put" a node in a scene, i.e. place the lamp on top of the table, frame on the wall, etc. Is it with the ways? Unfortunately, I donโ€™t even know what Iโ€™m looking for. Many thanks for your help!

Edit: what does it look like? SoSeparator * desk2; SoSeparator * lamp2; SoSeparator * pic_frame2; SoSeparator * selected;

void MouseButtonCallback(void* data, SoEventCallback* node)
{
   SoHandleEventAction* action = node->getAction();
   const SoMouseButtonEvent* event = static_cast<const SoMouseButtonEvent*>(action-          >getEvent());
   Navigator* nav = static_cast<Navigator*>(data);

   if (SoMouseButtonEvent::isButtonPressEvent(event, event->getButton())) 
       nav->OnMouseDown(event, action);
   else
         nav->OnMouseUp(event, action);

   const SbViewportRegion & viewportRegion = action->getViewportRegion();
   SoRayPickAction pickAction(viewportRegion); 

   SbVec2s mousePos = event->getPosition(viewportRegion); 
   pickAction.setPoint(mousePos); 
   pickAction.setPickAll(TRUE); 
   pickAction.setRadius(2.0F); 
   pickAction.setRay(SbVec3f(0.0,0.0,0.0), SbVec3f(0.0,0.0,-1.0));
   pickAction.apply(node);
   const SoPickedPoint *mpp = pickAction.getPickedPoint(); 
   if(mpp != NULL) {
  SoPath *path = mpp->getPath(); 

 if(desk2 != NULL && path->containsNode(desk2))
  {             //but this doesn't respond with cout when I try to test it :(
      if (SoMouseButtonEvent::isButtonPressEvent(event, event->getButton()))
      *picked = *desk2; 
  }
  else if(lamp2 != NULL && path->containsNode(lamp2))
  {
      if (SoMouseButtonEvent::isButtonPressEvent(event, event->getButton()))
      *picked = *lamp2;
  }
  else if(pic_frame2 != NULL && path->containsNode(pic_frame2))
  {
      if (SoMouseButtonEvent::isButtonPressEvent(event, event->getButton())) 
      *picked = *pic_frame2;
  }

           action->setHandled();
   }
 void MouseMoveCallback(void* data, SoEventCallback* node)
{
    SoHandleEventAction* action = node->getAction();
    const SoLocation2Event* event = static_cast<const SoLocation2Event*>(action->getEvent());
    Navigator* nav = static_cast<Navigator*>(data);

    nav->OnMouseMove(event, action);

     const SbViewportRegion & viewportRegion = action->getViewportRegion();
    SoRayPickAction pickAction(viewportRegion); 

    SbVec2s mousePos = event->getPosition(viewportRegion); 
    pickAction.setPoint(mousePos); 
    pickAction.setPickAll(TRUE); 
    pickAction.setRadius(2.0F); 
    pickAction.setRay(SbVec3f(0.0,0.0,0.0), SbVec3f(0.0,0.0,-1.0));
    pickAction.apply(node);
    const SoPickedPoint *mpp = pickAction.getPickedPoint(); 
    if(mpp != NULL) {
  SoPath *path = mpp->getPath(); 
  if(desk2 != NULL && path->containsNode(desk2))
  {
      *picked = *desk2; //can't remember how to set pointers, will figure that out
  }
  else if(lamp2 != NULL && path->containsNode(lamp2))
  {
      *picked = *lamp2;
  }
  else if(pic_frame2 != NULL && path->containsNode(pic_frame2))
  {
       *picked = *pic_frame2;
  }
   }  
        action->setHandled();
    }

  (part of main method) 

 //desk 
SoTransform *desk_transform = new SoTransform; 
desk_transform->translation.setValue(SbVec3f(380,340,330)); 
SoSeparator* desk2 = new SoSeparator(); 
desk2->addChild(desk_transform);
desk2->addChild(desk); 
root->addChild(desk2);

  SoTransformerManip* picked_transform = new SoTransformerManip(); 
   picked_transform->translation.setValue(SbVec3f(200,340,330));
  SoSeparator* pick2 = new SoSeparator(); 
  pick2->addChild(picked_transform); 
  pick2->addChild(picked); 
  root->addChild(pick2); 

 std::auto_ptr<btCollisionShape> picked_shape(new btBoxShape(btVector3(10.0f, 10.0f,  10.0f)));
  CollisionEngine* picked_collision = new CollisionEngine(collision_world.get(),      picked_shape.get());
  picked_collision->translation_in.connectFrom(&picked_transform->translation);
  picked_collision->rotation_in.connectFrom(&picked_transform->rotation);
  picked_transform->translation.connectFrom(&picked_collision->translation_out);
+5
source share
1 answer

You have a selected point. Then you get SoPath, you guessed it. Then see if the path contains the node you want to do something with.

SbViewportRegion viewport(400,300); 
    SoRayPickAction m(viewport); 
    m.setRay(SbVec3f(0.0,0.0,0.0), SbVec3f(0.0,0.0,-1.0));
    m.apply(callback_node);
    const SoPickedPoint *mpp = m.getPickedPoint(); 
    if(mpp != NULL) {
        std::cout << "test" << std::endl;
        SoPath * path = pickedPoint->getPath();

        if (deskSeparator != NULL && path->containsNode(deskSeparator)
        {
        }
        else if (lampSeparator != NULL && path->containsNode(lampSeparator)
        {
        }
        else if (radomeSeparator != NULL && path->containsNode(radomeSeparator)
        {
            if (    SoMouseButtonEvent::isButtonPressEvent( event, SoMouseButtonEvent::BUTTON2 )
                 || ( SoMouseButtonEvent::isButtonPressEvent( event, SoMouseButtonEvent::BUTTON1 ) && event->wasShiftDown() ) )
            {
                modelPointMoving = true;
                const SoDetail * detail = modelPickedPoint->getDetail( 0 );
                int face = -1;
                if ( detail && detail->isOfType( SoFaceDetail::getClassTypeId() ) )
                {
                    const SoFaceDetail * faceDetail = static_cast<const SoFaceDetail *>( detail );
                    face = faceDetail->getFaceIndex();
                }
                updateStatusBar( face, point.getValue(), normal.getValue() );
                graphicModel.postNote( pickedPoint );
                break;
            }
            else if ( SoMouseButtonEvent::isButtonPressEvent( event, SoMouseButtonEvent::BUTTON1 ) )
            {
            }
            else if ( SoMouseButtonEvent::isButtonReleaseEvent( event, SoMouseButtonEvent::BUTTON1 ) )
            {
            }
        }
    }

In the end, you will want to combine the highlight beam with the mouse position as follows:

//  Set an 2-pixel wide region around the pixel.
SbVec2s mousePosition = event->getPosition( viewportRegion );
pickAction.setPoint( mousePosition );
pickAction.setPickAll( TRUE );
pickAction.setRadius( 2.0F );

This is done before you .apply()choose an action, of course.

, - , , . , :

void
RenderWindow::mouseEvent( void *, SoEventCallback * eventCallback )
{
    const SoEvent *event = eventCallback->getEvent();

    if ( ! event )
    {
        qDebug() << "  **  Error in mousePressCallback: Event not found.";
        return;
    }

    //SoType eventType = event->getTypeId();   
    //SbName eventTypeName = eventType.getName();
    //const char * eventTypeString = eventTypeName.getString();
    SoHandleEventAction * action = eventCallback->getAction();
    const SbViewportRegion & viewportRegion = action->getViewportRegion();
    SoRayPickAction pickAction( viewportRegion );

( ( ):

//  Add a mouse event callback to catch mouse button presses.
SoEventCallback * mouseEventCallback = new SoEventCallback();
mouseEventCallback->setName( "MOUSE_EVENT_CALLBACK" );
mouseEventCallback->addEventCallback( SoMouseButtonEvent::getClassTypeId(), &::mouseEvent, static_cast<void *>( this ) );
//  Add a mouse event callback to catch mouse motion.
mouseEventCallback->addEventCallback( SoLocation2Event::getClassTypeId(), &::mouseEvent, static_cast<void *>( this ) );
rootSeparator->addChild( mouseEventCallback );

, , ;-). .

+2

All Articles