There is an H3D-specific MouseSensor node that provides and interface to mouse functions. This example demonstrates the use of four of the MouseSensor node fields:
- leftButton whose value is True on left mouse button click, False otherwise
- rightButton whose value is True on left mouse button click, False otherwise
- scrollUp which sends an event on a mouse-scroll upwards
- scrollDown which sends an event on a mouse-scroll downwards
The complete list of fields are found at the H3D::MouseSensor class reference page.
- Using the MouseSensor node
In this tutorial we will create a red sphere and change its colour with mouse clicks and adjust its transparency with mouse scrolls.
<!!-- the X3D file --> <Group> <Group DEF="G" /> <PythonScript url="mouse.py"> <Group USE="G" containerField="references" /> </PythonScript> </Group>
In this example we will draw the scene objects in Python. The X3D file is thus minimal. There is a Group node and PytonScript which takes a reference to the Group. We will use this reference later in the script to all nodes to the scene graph. All the action lies in the script file.
# mouse.py from H3DInterface import * root, d = createX3DNodeFromString("\ <Group> \ <NavigationInfo type=\"NONE\" /> \ <Shape> \ <Appearance> \ <Material DEF=\"M\" diffuseColor=\"1 0 0\"/> \ </Appearance> \ <Sphere radius=\"0.1\"/> \ </Shape> \ <MouseSensor DEF=\"S\" /> \ </Group>"); references.getValue().addChildren.setValue( [root] ) trans = d['M'].transparency color = d['M'].diffuseColor mouse = d['S']
In mouse.py we use the createX3DNodeFromString function to create the scene that we want. We have a Navigationinfo node of which type we set to false to disable navigation, a Shape with a Sphere geometry and a MouseSensor. The createX3DNodeFromString function returns the reference to the top Group node, which we store in the variable root and a dictionary of all the DEF-ed nodes in string, that we store in the variable d. The dictionary returned uses the DEF value as its key. Thus d['M'] and Template:D give us the Material node and MouseSensor node respectively.
We then add root to the scene graph by appending it to the Group node that we have passed into the script as reference. We also get the transparency and diffuseColor fields and store them in trans and color, and define mouse to refer to the MouseSensor.
# mouse.py class ChangeTrans( AutoUpdate( TypedField(SFBool, (SFBool, SFBool)) ) ): def update( self, event ): up, down = self.getRoutesIn() t = trans.getValue() if event == up and t < 1: trans.setValue( t+0.03 ) if event == down and t > 0: trans.setValue( t-0.03 ) return True class ChangeColor( TypedField(SFColor, (SFBool, SFBool)) ): def update( self, event ): ri = self.getRoutesIn() if ri.getValue(): return RGB(0, 0.8, 0.1) if ri.getValue(): return RGB(0, 0.5, 0.8) return RGB(1, 0, 0)
We define two fields in the script. The first, defined in the ChangeTrans class adjusts the transparency of the sphere. It takes two input fields of SFBool. This field will be routed to later by scrollUp and scrollDown. We get the input routes using the getRoutesIn method, referring them as up and down. We store the current transparency of the sphere in t. When there is a mouse scroll, an event will be sent. We determine whether the event received is up. If it is and the current transparency is less than 1 we will increase the transparency value using the setValue method. Likewise, when the event is sent by down and the transparency is more than zero we will decrease the value.
The ChangeColor field class changes the color of the sphere on mouse click events. It is routed to by leftButton and rightButton. In the update method we return the colours corresponding to the respective event value.
# mouse.py ct = ChangeTrans() mouse.scrollUp.routeNoEvent( ct ) mouse.scrollDown.route( ct ) cc = ChangeColor() mouse.leftButton.route( cc ) mouse.rightButton.route( cc ) cc.route( color )
To create the interaction we set up the proper routes. We define ct as the ChangeTrans field that we route to with scrollUp and scrollDown. The reason we use routeNoEvent for the first route is because otherwise the update function of the ChangeTrans will be run when there is only one route setup and the first line in the update function will generate an error.
We then route leftButton and rightButton to the cc field that changes color on mouse clicks. cc then routes to color.