SoWinRenderArea setEventCallback

/*------------------------------------------------------------- * This demonstrates using SoWinRenderArea::setEventCallback(). * which causes events to be sent directly to the application * without being sent into the scene graph. * * Clicking the left mouse button and dragging will draw * points in the xy plane beneath the mouse cursor. * Clicking middle mouse and holding causes the point set * to rotate about the Y axis. * Clicking right mouse clears all points drawn so far out * of the point set. *-----------------------------------------------------------*/ #ifndef WIN32 # include <X11/Intrinsic.h> #endif #include <Inventor/Sb.h> #include <Inventor/Win/SoWinRenderArea.h> #include <Inventor/Win/SoWin.h> #include <Inventor/nodes/SoCamera.h> #include <Inventor/nodes/SoCoordinate3.h> #include <Inventor/nodes/SoGroup.h> #include <Inventor/nodes/SoLightModel.h> #include <Inventor/nodes/SoPerspectiveCamera.h> #include <Inventor/nodes/SoPointSet.h> #include <Inventor/nodes/SoSeparator.h> #include <Inventor/sensors/SoTimerSensor.h> #ifdef WIN32 # include "print.h" #endif // Timer sensor // Rotate 90 degrees every second, update 30 times a second SoTimerSensor *myTicker; #define UPDATE_RATE 1.0f/30.0f #define ROTATION_ANGLE M_PI/60.0f void myProjectPoint(SoWinRenderArea *myRenderArea, int mousex, int mousey, SbVec3f &intersection) { // Take the x,y position of mouse, and normalize to [0,1]. // X windows have 0,0 at the upper left, // Inventor expects 0,0 to be the lower left. SbVec2s size = myRenderArea->getSize(); float x = float(mousex) / size[0]; float y = float(size[1] - mousey) / size[1]; // Get the camera and view volume SoGroup *root = (SoGroup *) myRenderArea->getSceneGraph(); SoCamera *myCamera = (SoCamera *) root->getChild(0); SbViewVolume myViewVolume; myViewVolume = myCamera->getViewVolume(); // Project the mouse point to a line SbVec3f p0, p1; myViewVolume.projectPointToLine(SbVec2f(x,y), p0, p1); // Midpoint of the line intersects a plane thru the origin intersection = (p0 + p1) / 2.0f; } void myAddPoint(SoWinRenderArea *myRenderArea, const SbVec3f point) { SoGroup *root = (SoGroup *) myRenderArea->getSceneGraph(); SoCoordinate3 *coord = (SoCoordinate3 *) root->getChild(2); SoPointSet *myPointSet = (SoPointSet *) root->getChild(3); coord->point.set1Value(coord->point.getNum(), point); myPointSet->numPoints.setValue(coord->point.getNum()); } void myClearPoints(SoWinRenderArea *myRenderArea) { SoGroup *root = (SoGroup *) myRenderArea->getSceneGraph(); SoCoordinate3 *coord = (SoCoordinate3 *) root->getChild(2); SoPointSet *myPointSet = (SoPointSet *) root->getChild(3); // Delete all values starting from 0 coord->point.deleteValues(0); myPointSet->numPoints.setValue(0); } void tickerCallback(void *userData, SoSensor *) { SoCamera *myCamera = (SoCamera *) userData; SbRotation rot; SbMatrix mtx; SbVec3f pos; // Adjust the position pos = myCamera->position.getValue(); rot = SbRotation(SbVec3f(0.0f, 1.0f, 0.0f), (float)(ROTATION_ANGLE)); mtx.setRotate(rot); mtx.multVecMatrix(pos, pos); myCamera->position.setValue(pos); // Adjust the orientation myCamera->orientation.setValue( myCamera->orientation.getValue() * rot); } /// // CODE FOR The Inventor Mentor STARTS HERE (part 1) #ifdef WIN32 SbBool myAppEventHandler(void *userData, MSG *anyevent) #else SbBool myAppEventHandler(void *userData, XAnyEvent *anyevent) #endif { #ifdef WIN32 SoWinRenderArea *myRenderArea = (SoWinRenderArea *) userData; POINT *myButtonEvent; POINT *myMotionEvent; ULONG buttonState; SbVec3f vec; SbBool handled = TRUE; // Hack to remember if left-mouse or shift-left-mouse (which is // logically middle-mouse) was pressed static SbBool leftIsMiddle = FALSE; switch (anyevent->message) { case WM_LBUTTONDOWN: // let shift-left-mouse be a synonym for middle-mouse on Win32 if (anyevent->wParam & MK_SHIFT) { leftIsMiddle = TRUE; myTicker->schedule(); } else { leftIsMiddle = FALSE; myButtonEvent = &anyevent->pt; myProjectPoint(myRenderArea, myButtonEvent->x, myButtonEvent->y, vec); myAddPoint(myRenderArea, vec); } break; case WM_MBUTTONDOWN: myTicker->schedule(); // start spinning the camera break; case WM_RBUTTONDOWN: myClearPoints(myRenderArea); // clear the point set break; case WM_LBUTTONUP: // let shift-left-mouse be a synonym for middle-mouse on Win32 if (leftIsMiddle) myTicker->unschedule(); break; case WM_MBUTTONUP: myTicker->unschedule(); // stop spinning the camera break; case WM_MOUSEMOVE: buttonState = anyevent->wParam ; myMotionEvent = &anyevent->pt; // let shift-left-mouse be a synonym for middle-mouse on Win32 if ((buttonState & MK_LBUTTON) && !leftIsMiddle) { myProjectPoint(myRenderArea, myMotionEvent->x, myMotionEvent->y, vec); myAddPoint(myRenderArea, vec); } break; default: handled = FALSE; break; } #else SoWinRenderArea *myRenderArea = (SoWinRenderArea *) userData; XButtonEvent *myButtonEvent; XMotionEvent *myMotionEvent; SbVec3f vec; SbBool handled = TRUE; switch (anyevent->type) { case ButtonPress: myButtonEvent = (XButtonEvent *) anyevent; if (myButtonEvent->button == Button1) { myProjectPoint(myRenderArea, myButtonEvent->x, myButtonEvent->y, vec); myAddPoint(myRenderArea, vec); } else if (myButtonEvent->button == Button2) { myTicker->schedule(); // start spinning the camera } else if (myButtonEvent->button == Button3) { myClearPoints(myRenderArea); // clear the point set } break; case ButtonRelease: myButtonEvent = (XButtonEvent *) anyevent; if (myButtonEvent->button == Button2) { myTicker->unschedule(); // stop spinning the camera } break; case MotionNotify: myMotionEvent = (XMotionEvent *) anyevent; if (myMotionEvent->state & Button1Mask) { myProjectPoint(myRenderArea, myMotionEvent->x, myMotionEvent->y, vec); myAddPoint(myRenderArea, vec); } break; default: handled = FALSE; break; } #endif return handled; } // CODE FOR The Inventor Mentor ENDS HERE int main(int, char **argv) { // Print out usage instructions printf("Mouse buttons:/n"); printf("/tLeft (with mouse motion): adds points/n"); printf("/tMiddle: rotates points about the Y axis/n"); printf("/tRight: deletes all the points/n"); // Initialize Inventor and Win HWND appWindow = SoWin::init(argv[0]); if (appWindow == NULL) exit(1); // Create and set up the root node SoSeparator *root = new SoSeparator; root->ref(); // Add a camera SoPerspectiveCamera *myCamera = new SoPerspectiveCamera; root->addChild(myCamera); // child 0 // Use the base color light model so we don't need to // specify normals SoLightModel *myLightModel = new SoLightModel; myLightModel->model = SoLightModel::BASE_COLOR; root->addChild(myLightModel); // child 1 // Set up the camera view volume myCamera->position.setValue(0.0f, 0.0f, 4.0f); myCamera->nearDistance.setValue(1.0f); myCamera->farDistance.setValue(7.0f); myCamera->heightAngle.setValue((float)(M_PI/3.0f)); // Add a coordinate and point set SoCoordinate3 *myCoord = new SoCoordinate3; SoPointSet *myPointSet = new SoPointSet; root->addChild(myCoord); // child 2 root->addChild(myPointSet); // child 3 // Timer sensor to tick off time while middle mouse is down myTicker = new SoTimerSensor(tickerCallback, myCamera); myTicker->setInterval(UPDATE_RATE); // Create a render area for viewing the scene SoWinRenderArea *myRenderArea = new SoWinRenderArea(appWindow); myRenderArea->setSceneGraph(root); myRenderArea->setTitle("My Event Handler"); // // CODE FOR The Inventor Mentor STARTS HERE (part 2) // Have render area send events to us instead of the scene // graph. We pass the render area as user data. myRenderArea->setEventCallback( myAppEventHandler, myRenderArea); // CODE FOR The Inventor Mentor ENDS HERE // // Show our application window, and loop forever... myRenderArea->show(); SoWin::show(appWindow); SoWin::mainLoop(); return 0; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值