Download presentation
Presentation is loading. Please wait.
1
User Interaction Chapters 10, 12, 13, 15
2
Events Events are actions applied to the graph Each node implements its own behavior When node is found to handle the event, the graph traversing stops.
3
Keyboard Events Create an event node. Create a callback function Add the node to the graph (typically to root) Callback nodes are written to file, but without the event they process Example …
4
Keyboard Events #include // Callback function void keyEvent(void* userData, SoEventCallback* eventCallBack){ const SoEvent *curEvent = eventCallBack->getEvent(); if(SO_KEY_PRESS_EVENT(curEvent, Q)) { exit(1); } // Main file SoEventCallback* switchEventCallBack = new SoEventCallback; root->addChild(switchEventCallBack); switchEventCallBack->addEventCallback(SoKeyboardEvent::getClassTypeId(), keyEvent, root); switchEventCallBack->removeEventCallback(SoKeyboardEvent::getClassTypeId(), keyEvent, root);
5
Mouse events Defined similarly to keyboard events –SoMouseButtonEvent and SoLocation2Event However SoWinExaminerViewer blocks the mouse events. To unblock them – check “arrow” button Example …
6
Selection of nodes SoSelection –Defined in SoSelection.h –Derived from SoGroup –Has a built-in method to handle mouse events –Responses to mouse click on object –Inserted near root (above, below or instead) –Used for manipulators
7
SoSelection SoSelection * root = new SoSelection; root->addSelectionCallback(selectionCallback, NULL); root->addDeselectionCallback(deselectionCallback, NULL); // ----------------------------------------------------------------- // void selectionCallback(void *, SoPath *selectionPath) { SoTranslation *tr = (SoTranslation *)selectionPath->getNodeFromTail( 1); SbVec3f a = tr->translation.getValue(); std::cout<< a.getValue(); }
8
Sensors Special class of nodes Data sensors –Monitor a part of database and inform the application when that part changes Time sensors –Response to time events (inner events of Inventor)
9
Data sensors SoFieldSensor (attached to a field) SoNodeSensor (attached to a node) SoPathSensor (attached to a path)
10
Data sensors - example // Callback that reports whenever the viewer's position changes. static void cameraChangedCB(void *data, SoSensor *) { SoCamera *viewerCamera = (SoCamera *)data; SbVec3f cameraPosition = viewerCamera->position.getValue(); printf("Camera position: (%g,%g,%g)\n", cameraPosition[0], cameraPosition[1], cameraPosition[2]); } // main function SoCamera *camera = myViewer->getCamera(); SoFieldSensor *mySensor = // define callback and its input new SoFieldSensor(cameraChangedCB, camera); // Attach callback to camera position mySensor->attach(&camera->position);
11
Sequence for Data Sensors // Construct the sensor SoSensor *sensor = new SoSensor( func, data); // Function must be static void func( void *, SoSensor *) // since it obtains pointer to the sensor // Set the priority of the sensor // 0 highest // 100 is default priority (lowest) sensor->setPriority(priority number); // Attach the sensor to a field, node or path sensor->attach(pointer to object);
12
Using the trigger node and field You can use –getTriggerField(); –getTriggerNode(); –getTriggerPath(); For 0 priority sensors Use setTriggerPathFlag() –Sets trigger path flag to true –Saving path is expensive
13
Using the trigger node and field // This function prints a message whenever changes are made to the scene graph. // The sensor should be attached to root // Sensor callback function: static void rootChangedCB(void *, SoSensor *s) { // We know the sensor is really a data sensor: SoDataSensor *mySensor = (SoDataSensor *)s; SoNode *changedNode = mySensor->getTriggerNode(); SoField *changedField = mySensor->getTriggerField(); // Print the data printf("The node named '%s' changed\n",changedNode->getName().getString()); if (changedField != NULL) { SbName fieldName; changedNode->getFieldName(changedField, fieldName); printf(" (field %s)\n", fieldName.getString()); } else printf(" (no fields changed)\n"); }
14
Time sensors SoAlarmSensor –Goes off at a specific time SoTimerSensor –Goes off at intervals
15
Example // Rotate flag every minute static void raiseFlagCallback(void *data, SoSensor *) { // We know data is really a SoTransform node: SoTransform *flagAngleXform = (SoTransform *)data; // Rotate flag by 90 degrees about the z axis: flagAngleXform->rotation.setValue(SbVec3f(0,0,1), M_PI/2); } // Main function SoTransform *flagXform = new SoTransform; // Create an alarm that will call the flag-raising callback: SoAlarmSensor *myAlarm = new SoAlarmSensor(raiseFlagCallback, flagXform); myAlarm->setTimeFromNow(60.0); myAlarm->schedule();
16
Time sensors sequence Construct Set the callback Set the timing before scheduling Schedule using schedule() Delete when finished
17
Setting the timing For alarm: sensor->setTime(time); sensor->setTimerFromNow(time); For timer: Interval: sensor->setInterval(interval); First time (default is now): sensor->setBaseTime(time);
18
Example Rotate the flag with different frequencies Two frequencies are available –1Hz –10Hz Exchange the frequencies every 5 sec
19
Example SoRotation *myRotation = new SoRotation; root->addChild(myRotation); root->addChild(myFlag); SoTimerSensor *exchangeSensor = new SoTimerSensor(exchangeFrequencies, rotatingSensor); SoTimerSensor *rotatingSensor = new SoTimerSensor(rotateCallback, myRotation); exchangeSensor ->setInterval(5.0); // once per 5 seconds exchangeSensor ->schedule(); rotatingSensor->setInterval(1.0); //scheduled once per second rotatingSensor->schedule();
20
Example // This function is called once every 5 seconds, and // reschedules the other sensor. static void exchangeFrequencies(void *data, SoSensor *){ SoTimerSensor *rotatingSensor = (SoTimerSensor *)data; rotatingSensor->unschedule(); if (rotatingSensor->getInterval() == 1.0) rotatingSensor->setInterval(1.0/10.0); else rotatingSensor->setInterval(1.0); rotatingSensor->schedule(); } // This function is called either 10 times/second or once every // second; the scheduling changes every 5 seconds (see below): static void rotateCallback(void *data, SoSensor *){ // Rotate an object... SoRotation *myRotation = (SoRotation *)data; SbRotation currentRotation = myRotation->rotation.getValue(); currentRotation = SbRotation(SbVec3f(0,0,1), M_PI/90.0) *currentRotation; myRotation->rotation.setValue(currentRotation); }
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.