2012-05-15 6 views
5

क्षमा करें अगर यह दोहराना है, लेकिन मैं ओपन इनवेंटर में SoRayPickAction के कार्यान्वयन को समझने की कोशिश कर रहा हूं। मैं इसे लागू करने की कोशिश कर रहा हूं ताकि जब माउस पर क्लिक किया जाए, तो एक विशेष नोड का चयन करें ताकि मैं अनुवाद कर सकूं, घुमाएं, आदि। मेरे पास तीन नोड्स हैं: डेस्क, दीपक, और फ्रेम (चित्र फ्रेम)। हालांकि, मुझे नहीं लगता कि मेरा कोड बिल्कुल सही है। मेरे पास माउसबटन कॉलबैक जैसे कई विधियां भी हैं (जो जांचेंगी कि माउस क्लिक किया गया है और फिर नेविगेटर का उपयोग करें) और MouseMoveCallback (एक ही विचार)। तो यहां मेरे पास कोड है, लेकिन क्या आपके पास कोई सुझाव है? अभी, ठीक है, यह कुछ भी नहीं करता है।ओपन इनवेंटर में SoRayPickAction?

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; 
    } 

आप भी आदि OpenInventor में एक कार्रवाई है कि "जगह" दृश्य में एक नोड है, अर्थात डेस्क के शीर्ष पर, फ्रेम पर दीपक जगह कर सकते हैं दीवार पर, यह पथ के साथ है के बारे में पता कर सकते? दुर्भाग्यवश, मैं यह भी नहीं जानता कि मैं क्या देख रहा हूं। आपकी मदद के लिए बहुत धन्यवाद!!

संपादित करें: यह कैसे दिखता है? सोसेपरेटर * डेस्क 2; सोसेपरेटर * लैंप 2; सोसेपरेटर * pic_frame2; सोसेपरेटर * उठाया;

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); 

उत्तर

2

आपके पास चुना गया बिंदु है। आप अनुमान लगाते समय SoPath प्राप्त करते हैं। फिर देखें कि पथ में एक नोड है जिसमें आप कुछ करना चाहते हैं।

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)) 
      { 
      } 
     } 
    } 

अंततः आप इस तरह एक तरह से माउस की स्थिति में ले रे कनेक्ट करना चाहेंगे:

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

यह आपको .apply() से पहले निश्चित रूप से ले कार्रवाई की जाती है।

मुझे लगता है कि मेरा कोड आपके और मेरा मिश्रण है, लेकिन मुझे लगता है कि यह आपको एक शुरुआत देनी चाहिए।

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); 

अब जब मैं इसे देखता हूं तो मैंने रिवर्स ऑर्डर में भाग लिखा था ;-)। माफ़ कीजिये।

अच्छी किस्मत

+1

ग्रेट, वाह, बहुत बहुत धन्यवाद, ईएमएसआर !! आपका कोड अब समझ का एक टन बनाता है। क्षमा करें, "radomeSeparator" क्या है? और क्या यह कोड बदलता है अगर मुझे एहसास हुआ कि दुर्भाग्यवश, डेस्क, दीपक और फ्रेम नोड्स के बजाय विभाजक हैं? एक बार फिर सहायताके लिए शुक्रिया! – m00nbeam360

+0

क्षमा करें, radomeSeparator मेरे कोड से है ;-) मैं विमान के साथ काम करता हूं। मैं इसे अपने कोड की तरह दिखने के लिए बदलना भूल गया। जाहिर है, आप अपने स्वयं के विभाजक उपयोग करना चाहेंगे। इसके अलावा, एक सोसेपरेटर एक सोनोड है - यानी सोसेपरेटर सोनोड से प्राप्त होता है (SoGroup के माध्यम से और शायद कुछ और)। SoNode इनवेंटर में * बहुत * चीजों का अभिभावक है ताकि आप एक SoMaterial, SoTransform या जो कुछ भी चुन सकें। – emsr

+0

मुझे खेद है, इसलिए मैं थोड़ा सा खो गया हूं। मैं स्थानीय चर से गंभीरता से नफरत करता हूं! मेरे पास पहले से MouseMoveCallback और MouseButtonCallback विधियां हैं। हालांकि, आप कैसे सोचते हैं कि मैं इन सभी तीनों को RayPickAction से संभवतः जोड़ सकता हूं? आपकी मदद के लिए बहुत बहुत धन्यवाद! – m00nbeam360

संबंधित मुद्दे