Open Inventor练习-SoRayPickAction和SoMouseButtonEvent点选操作

SoRayPickAction是三维物体射线选择操作,SoPickedPoin用来存放选择的坐标,SoMouseButtonEvent用来鼠标操作信息处理。例子中获得鼠标点击物体的类型和坐标位置信息,在Console控制台窗口中输出。代码如下。

#define COIN_DLL #define SOWIN_DLL // 加载COIN库文件 #ifdef _DEBUG #pragma comment(lib, "SoWin1d.lib") #pragma comment(lib, "Coin3d.lib") #else #pragma comment(lib, "SoWin1.lib") #pragma comment(lib, "Coin3.lib") #endif // 添加COIN头文件-Window操作显示库和节点库 #include <Inventor/Win/viewers/SoWinExaminerViewer.h> #include <Inventor/Win/SoWin.h> #include <Inventor/nodes/SoSeparator.h> #include <Inventor/nodes/SoSphere.h> #include <Inventor/nodes/SoMaterial.h> #include <Inventor/nodes/SoEventCallback.h> #include <Inventor/actions/SoRayPickAction.h> #include <Inventor/events/SoMouseButtonEvent.h> #include <Inventor/SoPickedPoint.h> SoWinExaminerViewer *viewer = NULL; SoSeparator *root = NULL; void button_event_cb(void *userdata, SoEventCallback *node) { const SoMouseButtonEvent *event = (SoMouseButtonEvent *)node->getEvent(); SbVec2s pos = event->getPosition(viewer->getViewportRegion()); if (event->getButton()==SoMouseButtonEvent::BUTTON1 && event->getState()==SoButtonEvent::DOWN) { SoRayPickAction pick(viewer->getViewportRegion()); pick.setPoint(pos); pick.apply(viewer->getSceneManager()->getSceneGraph()); SoPickedPoint *pp = pick.getPickedPoint(); if (pp) { const SoPath *path = pp->getPath(); SbVec3f p = pp->getPoint(); SoNode *node = path->getTail(); printf("Picked shape: %s (%s), point: (%f %f %f)\n", node->getName().getString(), node->getTypeId().getName().getString(), p[0], p[1], p[2]); } } } int main (int argc, char ** argv) { if (argc != 2) { fprintf(stderr, "Usage: %s <file.iv>\n", argv[0]); exit(1); } // Initialize Coin & SoWin HWND win = SoWin::init(argv[0]); if (win == NULL) exit(1); // Read scene graph from file SoInput in; if (!in.openFile(argv[1])) { fprintf(stderr, "Unable to open file \"%s\"\n",argv[1]); exit(1); } SoSeparator *fileroot = SoDB::readAll(&in); in.closeFile(); root = new SoSeparator; root->ref(); SoEventCallback *cb = new SoEventCallback; cb->addEventCallback(SoMouseButtonEvent::getClassTypeId(), button_event_cb, NULL); root->addChild(cb); root->addChild(fileroot); // Create the viewer viewer = new SoWinExaminerViewer(win); viewer->setSceneGraph(root); viewer->setTitle("picking example"); viewer->setViewing(FALSE); viewer->setDecoration(FALSE); // Show the window viewer->show(); SoWin::show(win); // Enter the application event loop SoWin::mainLoop(); // Free scene graph memory root->unref(); return 0; }

iv文件如下:

#Inventor V2.1 ascii # open this file using the "raypick" demo program Separator { DEF A Separator { DEF D Translation { translation -5 -5 0 } DEF E Material { diffuseColor 0 1 1 } DEF E2 MaterialBinding { value PER_PART } DEF F Cube { } } DEF B SoSphere { } DEF C Separator { DEF G Translation { translation 5 0 0 } DEF H Cylinder { } } }

运行效果如下

Open Inventor练习-SoRayPickAction和SoMouseButtonEvent点选操作

Open Inventor练习-SoRayPickAction和SoMouseButtonEvent点选操作