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 {
}
}
}
运行效果如下