Candy

From H3D.org

Jump to: navigation, search

The Candy package provides a collection of miscellaneous tools, nodes and scripts for H3D API. Some of the components can be used without any compilation, for example the calibration tool, while other require compilation. Current versions of Candy also contains the HVR package.

Contents

Summary of Components

No Compilation Required

  • Calib, a semi-automatic and interactive calibration tool for the H3D system,
  • Shell, an interactive Python shell for run-time manipulation of the H3D scene-graph,
  • CorrectViewpoint, a script can be used when you have a correct viewpoint to correct all necessary settings,
  • Rotator, a Python script that provides rotation from arrows, mouse motions and the magellan device,
  • Bubble, a Python script implementing the 'Bubble' technique for extending the reach of the haptics device,
  • ZoomToNavigate, a Python script that implements scaling as a means for navigation,
  • MultiTouch, a Python script implementing multi touch interaction using two or more haptics devices,
  • ManualTransform, a set of Python scripts that enables intuitive handling of object transforms,
  • pick RGB, a widget for interactive selection of colour in the RGB colour space,
  • pick HSV, a widget for interactive selection of colour in the HSV colour space,
  • AutoLoadSO, a Python script that automatically loads the correct shared object (dll/so/dylib) for a cross platform X3D files,
  • GettextWrapper, a Python script that uses GNU Gettext to facilitate internationalization of H3D applications,
  • FrameTime, a Python script that draws bars to visualize the frame time for the graphics loop and for all haptics devices

Compilation Required

  • CubicPositionInterpolator, an interpolator node that interpolates softly between the specified intermediate key positions
  • FiniteStateMachine, a node encapsulating the functionality of a state machine, or automata, useful for handling states in a game or larger application
  • ForceTorqueIcon, a small widget that provides real-time visual representations of the force and torque generated for the first haptic instrument
  • I18N, is a node that provides strings specified through separate language files
  • MouseHapticsDevice, a haptics device implementation that use the mouse position in 3D to determine the motions
  • PathHapticsDevice, a haptics device implementation that is controlled through a pre-defined cubic spline path
  • XSplinePositionInterpolator, a position interpolator that uses the x-spline algorithm which allows for a mixture of hard and soft corners

For more information, see the documentation of the separate parts.

Calib

Calibration tool running.
Enlarge
Calibration tool running.

This is an interactive tool for calibrating the haptic instruments used with H3D API. It provides a clean and easy way of finding both the position calibration matrix and the rotation calibration of any type of haptic device supported by H3D API. With correct display settings and calibration data generated from this tool, the VR environment will become one-to-one mapped with the real world, so that a one cm object will look one cm, and the haptic instrument will become co-located and co-registered. With a semi-transparent display you will see the virtual stylus superposed the real haptic probe taking full advantage of human eye/hand coordination.

There is a video on YouTube demonstrating the calibration procedure and its result.

Prerequisites

For the tool to successfully work you will need non-standard Python packages used for optimizing the transformation matrix. Make sure that you have installed SciPy and either NumPy or Numeric for your current version of Python. The tool has been confirmed to work on Linux with Python 2.4, SciPy 0.3.2 and Numeric 24.2, and on Windows with Python 2.4, SciPy 0.4.9 and NumPy 0.9.8

It is also assumed that you have a working copy of H3D API.

Tool keys

The following keys can be used during calibration:

  • c - Perform calibration
  • z - Undo last sample
  • Z - Undo all samples
  • p - Print calibration

Using the tool

First make sure you use the correct Viewpoint for your system. H3DLoad in H3D API v 1.4 and later provides display specific settings, however you may want to make sure that the values fit your display. The calibration wizard included in Calib can help you with that.

If you want to manually adjust the view then measure the screen height (h) and the distance (d) between the screen and the viewer's eyes (through the mirror if your system has one). The active viewpoint of the scene graph should then have the following properties:

  • position = [ 0, 0, d ]
  • fieldOfView = 2 x arctan( 0.5 x h / d )

The fieldOfView is expressed in radians (should be around 0.5). If stereo is supported, there should also be a StereoInfo node with the following properties:

  • focalDistance = d
  • interocularDistance = 0.06

The calibration tool is started from the Candy root by with the command-line 'H3DLoad x3d/Calib.x3d'. This will show an empty grey screen. To use the tool, follow these steps:

  1. Make sure the light is on in your room, so that you see the real haptic instrument through the mirror.
  2. Move the stylus (a blue sphere) to a position and orientation to which you believe that you can move the real instrument. The long and short spikes represents the length of the pen and its up orientation, respectively.
  3. Hold down the main button. This will create a red version of the stylus.
  4. Now, while holding down the button, move the real instrument, seen through the mirror, inside the red stylus and orientate the instrument to match it, and release the button. Observe that it is the pivot point of your device that should be co-centred with the sphere and not its tip.
  5. You now have a calibration sample, represented by a green and a red sphere. Repeat steps 2-4 until you have a set of samples that you believe fully represents the transform of the tool. It is important that the different positions and orientations of the samples adequately represent the workspace of the device, also distributed in depth.
  6. When you have enough samples, press the 'c' key. This will freeze the scene for a few seconds or minutes depending on the number of samples and the speed of your computer.
  7. Check if you think that the new calibration matrix is satisfactory by moving the instrument about. Otherwise, restart from step 1. It is not uncommon that the calibration procedure needs to be performed two times - one time for coarse calibration and one time for fine tuning.
  8. When finished press the 'p' key. The new instrument calibration settings are then printed to your command window. Use these in the X3D setup of your haptic device.

Internationalization

The calibration tool supports localization (from version 1.7) so that it adapts to the current language of the platform it runs on. For each supported language, except the default English, it requires a language file. At the moment language files exists for the following languages:

  • Dutch
  • Swedish

To help provide support for more languages download the language template file and add translation strings.

Python Scripts

Shell

The Candy Shell script.
Enlarge
The Candy Shell script.

Shell is a script that sets up a Tcl/Tk or wxPython outside the H3D API 3D rendering of the scene graph. Into this window can be entered Python code to modify the run-time scene graph by adding or removing nodes or updating and reading values of fields. The window is split in two halves providing one half for input, the Python scripts, and one half for output from the execution, both error messages and results from printing commands.

The shell comes in two versions, one for Tcl/Tk and one for wxPython. While the wxPython version is better looking and has a bit more functionality, the Tcl/Tk version runs with out-of-the-box Python installations. Read on for more information.

Prerequisites

There should not be any prerequisites, apart from a working copy of H3D API. Tcl/Tk, used per default for widget rendering, should be included in all distributions of Python. wxPython, however, provides native look and feel on all supported platforms. Use this if you have wxPython installed on your system.

Usage

See the example 'x3d/setup_shell.x3d'. The first reference provided for the script can be accessed through the name 'node'. All references are provided through the name 'nodes'. Observe that this is a list of all references, so 'node' and 'nodes[0]' provide the same scene graph node.

The input box in the wxPython version of the shell allows for a few short-cut commands. Pressing Ctrl+Return executes the entered code, Ctrl+Up steps back through a history of previously executed commands, and Ctrl+Down steps forward in the same history.

Running the example using H3DLoad, try executing the following code through the shell:

app = node.children.getValue()[0].appearance.getValue()
app.material.getValue().diffuseColor.setValue( RGB(0.1,0.1,0.1) )
app.material.getValue().specularColor.setValue( RGB(0.9,0.1,0.1) )
nodes[1].cycleInterval.setValue(5)


Bubble

This Python-script implements the 'Bubble' technique for extending the reach of a small workspace haptics device into a larger environment. In this approach a sphere is defined around the centre of the device's workspace. When interacting inside of this sphere the normal mode of interaction is executed. If the probe is moved outside the sphere, however, the sphere is pushed and thereby translated to a new position in space.

A demonstration of this technique is available in a YouTube video


ZoomToNavigate

This Python-script provides an intuitive navigation scheme where the a selected transform is scaled down for navigation and then scaled back up for interaction.

The following must be provided through the "references" field:

  • the MatrixTransform node on which to operate.

The following must be routed:

  1. To the "zoom" field, the button to activate zooming out
  2. To the "position" field, the position to use as zoom centre

You may also control the following variables, either by routing to their respective fields or by providing a MetadataFloat with the name of the variable:

  • inScale - the transform scale when zoomed in, default 1.0
  • outScale - the transform scale when zoomed out, default 0.1
  • zoomTime - the duration of zooming in or out, default 1.0 sec

MultiTouch

This Python script provides an intuitive navigation scheme where at least two haptic instruments are used to translate, rotate and scale a selected transform. All haptic instruments available in the currently active DeviceInfo node are applied. The main button of the devices is used to grasp the specified transform.

A demonstration of this technique is available in a YouTube video

CorrectViewpoint

This script can be used when you have a correct viewpoint to correct all settings that modifies tracking and viewpoint according to navigation. It sets the type in the navigation info to NONE and sets all devices to not follow the viewpoint.


Rotator

This Python-script accumulates rotation information extracted from the sensors provided through the references field. This can be KeySensor, MouseSensor or any Sensor with an instantRotation field, such as SpaceWareSensor. The script can then be used to control 3D scene orientation. Load the "python/Rotator.py" with a PythonScript node and route the "rotation" field to the "rotation" field of the selected transform. The orientation provided by this script can be reset to zero by setting the reset field to true.

This script uses KeySensor, MouseSensor and SpaceWareSensor if no sensor is explicitly provided through the references field.

You may also modify several settings using metadata nodes with appropriate values:

"keyRotationScale" 1 in MetadataFloat Sets the rotation scaling when a key is used to rotate the object(s).
"mouseRotationScale" 1 in MetadataFloat Sets the rotation scaling when the mouse is used to rotate the object(s).
"generalRotationScale" 1 in MetadataFloat Sets a common rotation scaling for all means of rotation, keys, mouse, space mouse, etc.
"defaultKeyTime" 1 in MetadataFloat Time is used to scale rotation to reduce the impact of frame rate. This parameter sets the time used to scale a single key event (i.e. where there is no time)
"eulerAxis" 3 in MetadataFloat (x,y,z) Sets an axis for Euler angle rotation and deactivates free rotation.
"eulerLimits" 2 in MetadataFloat (min,max) Sets upper and lower Euler angle limits for the last specified Euler axis.

For example, use the following script to rotate the transform "TR" using a classical inspectation navigation:

<PythonScript
    DEF="ROTATOR"
    url="urn:candy:python/Rotator.py">
  <MetadataFloat name="eulerAxis" value="1 0 0"
                 containerField="references"/>
  <MetadataFloat name="eulerLimits" value="-1 1"
                 containerField="references"/>
  <MetadataFloat name="eulerAxis" value="0 1 0"
                 containerField="references"/>
</PythonScript>
<ROUTE fromNode="ROTATOR" fromField="rotation"
       toNode="TR" toField="rotation"/>

ManualTransform

Three Python-scripts, ManualTranslation, ManualRotation and ManualZoom, provides an intuitive navigation scheme where the haptic instrument is used to translate, rotate and zoom (respectively) on objects in a selected transform. They can be used individually or combined. Since both zoom and rotation are performed using the rotation of a haptics device it is not recommended to use them both simultaneously.

Here is an example setup which is also shown in a YouTube video:

 
  <MatrixTransform
      DEF="TR">
 
    <Shape>
      <Appearance>
        <Material
            diffuseColor=".6 .8 .2"
            specularColor=".6 .6 .0"/>
      </Appearance>
      <Box size=".04 .04 .04"/>
    </Shape>
 
  </MatrixTransform>
 
  <IMPORT inlineDEF="H3D_EXPORTS" exportedDEF="HDEV" AS="HDEV"/>
 
  <PythonScript
      DEF="MT"
      url="urn:candy:python/ManualTranslation.py">
    <Transform USE="TR" containerField="references"/>
  </PythonScript>
 
  <PythonScript
      DEF="MZ"
      url="urn:candy:python/ManualZoom.py">
    <Transform USE="TR" containerField="references"/>
  </PythonScript>
 
  <PythonScript
      DEF="MR"
      url="urn:candy:python/ManualRotation.py">
    <Transform USE="TR" containerField="references"/>
  </PythonScript>
 
  <ROUTE fromNode="HDEV" fromField="mainButton"
         toNode="MT" toField="button"/>
  <ROUTE fromNode="HDEV" fromField="trackerPosition"
         toNode="MT" toField="position"/>
 
  <ROUTE fromNode="HDEV" fromField="mainButton"
         toNode="MZ" toField="button"/>
  <ROUTE fromNode="HDEV" fromField="trackerPosition"
         toNode="MZ" toField="position"/>
  <ROUTE fromNode="HDEV" fromField="trackerOrientation"
         toNode="MZ" toField="orientation"/>
 
  <ROUTE fromNode="HDEV" fromField="mainButton"
         toNode="MR" toField="button"/>
  <ROUTE fromNode="HDEV" fromField="trackerPosition"
         toNode="MR" toField="position"/>
  <ROUTE fromNode="HDEV" fromField="trackerOrientation"
         toNode="MR" toField="orientation"/>

AutoLoadSO

This script automatically loads the correct shared object library file for the current platform. For the Linux and MacOS platform the library loaded is 'lib*.so' or 'lib*.dylib', respectively. For Windows platforms the script searches for the first occurance of a dll with the correct prefix. The script will attempt to automatically select debug or no-debug library but the result can be manually overridden by an argument in the X3D file.

Include this to load the Candy library:

<PythonScript url="urn:candy:python/AutoLoadSO.py"/>

Include this to load library for XYZ:

<PythonScript url="urn:candy:python/AutoLoadSO.py">
  <MetadataString name="library" value="XYZ"
                  containerField="references"/>
</PythonScript>

Include this to force loading the debug version of XYZ:

<PythonScript url="urn:candy:python/AutoLoadSO.py">
  <MetadataString name="library" value="XYZ"
                  containerField="references"/>
  <MetadataInteger name="debug" value="1"
                   containerField="references"/>
</PythonScript>

It is also possible to force verbose information, by settings the "verbose" argument to 1 (one):

<MetadataInteger name="verbose" value="1" containerField="references"/>


You may also specify an alternative root for the path to the library. This functionality supports both environment variable substitution and URNs:

<MetadataString name="root" value="/usr/local/lib"
                containerField="references"/>
<MetadataString name="root" value="$(VHTK_ROOT)/lib"
                containerField="references"/>
<MetadataString name="root" value="urn:vhtk:"
                containerField="references"/>

GettextWrapper

This module provides functionality for loading X3D or VRML files with GNU gettext translations for internationalization. All X3D and VRML loading functions from H3D are overloaded. Any instance of _(...) is replaced with the translation of the argument or the argument itself if there is no translation available. You may use _(...) around the string to be translated, or inside the string if you want strict XML.

Example:

import gettext
gettext.bindtextdomain("MyCoolApp","./resources/")
import GettextWrapper as GW
node, def = GW.createX3DFromURL("file.x3d")

You can also use this script to load a full scene with translation directly from X3D code. It will look for the references field and use metadata string nodes to specify domain and localedir and also to specify the url to get the file to load the scene from.

The domain and localedir must be specified first and any following url will be loaded with those settings. You may also change domain or localedir before loading further urls. It is also recommended that you specify a group in which to put the loaded nodes, or else the root of the current scene will be replaced.

Example:

<PythonScript url="urn:candy:python/GettextWrapper.py">
  <MetadataString name="domain" value="MyCoolApp"
                  containerField="references"/>
  <MetadataString name="localedir" value="./resources/"
                  containerField="references"/>
  <Group USE="THE_GROUP" containerField="references"/>
  <MetadataString name="url" value="file.x3d"
                  containerField="references"/>
</PythonScript>

FrameTime

This script draws cylindrical bars showing the frame time for the graphics loop and every haptics device used in the scene. The maximum and mean frame time for graphics and haptics loops are displayed in milliseconds.

Example:

<Transform translation="-.1 -.1 0" DEF="FRAMETIME"/>
  <PythonScript url="urn:candy:python/candy/FrameTime.py">
    <Transform USE="FRAMETIME" containerField="references"/>
  </PythonScript>
 

SFtoMF*

There are three script that convert an SField to an MField: SFtoMFBool, SFtoMFFloat and SFtoMFInt32. Each script provides a field "value" that takes any number of SField of its type as input to provide an MField value.

MFtoSF*

There are three script that convert an MField to an SField: MFtoSFBool, MFtoSFFloat and MFtoSFInt32. Each script provides a field "value" that takes an MField of its type as input and extracts the first value, if available, to provide an SField value.

OrBool

This script provides a field "value" that takes an number of SFBool or MFBool as input to provide an SFBool value. This will use the OR operator to determine the final value.

Colour Picker Models

The colour pickers in the Candy package.
Enlarge
The colour pickers in the Candy package.

pick_RGB

The pick_RGB widget can be included by doing an Inline on the file "x3d/pick_RGB.x3d". The X3D file renders the widget, provides interactive colour selection and exports the node "PICK_RGB" which contains the following fields:

  • color, providing the picked colour. Route from this field to read off the selected colour and route to the field to see a colour's position in the colour space of the widget
  • position, describing the position of the colour in the local space
  • trigger, a boolean field that becomes true when the stylus is moved inside the widget. Use this to deactivate other functions in your program when colour picking is being performed
  • active, a boolean field that becomes true when the the widget is triggered and the main button is pressed, indicating that the colour is being interactively updated

An example of how this component can be used is given in the file "x3d/example_colourPickers.x3d". Both colour pickers are present and interconnected so that their respective colour space's positions can be interactively visualized and explored.

pick_HSV

The pick_HSV widget can be included by doing an Inline on the file "x3d/pick_HSV.x3d". The X3D file renders the widget, provides interactive colour selection and exports the node "PICK_HSV" which contains the following fields:

  • color, providing the picked colour. Route from this field to read off the selected colour and route to the field to see a colour's position in the colour space of the widget
  • position, describing the position of the colour in the local space
  • trigger, a boolean field that becomes true when the stylus is moved inside the widget. Use this to deactivate other functions in your program when colour picking is being performed
  • active, a boolean field that becomes true when the the widget is triggered and the main button is pressed, indicating that the colour is being interactively updated

An example of how this component can be used is given in the file "x3d/example_colourPickers.x3d". Both colour pickers are present and interconnected so that their respective colour space's positions can be interactively visualized and explored.

Fake Haptics Devices

MouseHapticsDevice

This haptics device transforms the mouse position into its corresponding 3D position and uses that position for the haptics device. The device position is interpolated in the haptics thread for smooth simulation of haptic algorithms even without a real haptic device.

The right mouse button is used as the main button of the haptics device. While holding down the middle button, up and down movements of the mouse will move the haptics device away and closer in the Z direction. The left mouse button remains left mouse button, since this is often used for other interface interaction.


PathHapticsDevice

This haptics device is controlled through a pre-defined cubic spline path which the device follows at a specified time. It is designed primarily for testing haptic algorithms and parameters in a comparable manner. Because of the required precision in such tests, this device estimates the probe position and velocity in the haptics loop, in contrast to the fake haptics device(s) available in H3D API. There are two example device setup files available in this package:

  • x3d/device_CircularPath.x3d - use this device setup file to make the haptic device go slowly around and around
  • x3d/device_LeftToRightPath.x3d - this device setup file makes the device go from left to right starting after ten seconds to allow for any time consuming initialization to finish


Other Nodes

ForceTorqueIcon

Example of ForceTorqueIcon appearance.
Enlarge
Example of ForceTorqueIcon appearance.

This node provides a visual representation of the force and torque generated through the first haptic instrument. There are two X3D files provided for including this information in a general setup file:

  • x3d/model_FeedbackIcon.x3d - include this file to show the visual feedback at a position specified by the current transform
  • x3d/model_FeedbackTip.x3d - include this file to show the visual feedback at the tip of the first haptic instrument


CubicPositionInterpolator

This node provides a position interpolation functionality with cubic interpolation, to produce a smooth path. It is useful for producing paths for flying objects, for example in transitions between using and not using a graphical user interface or presenting a splash screen.


FiniteStateMachine

The FiniteStateMachine node provides state machine functionality through programmable states and transitions.

A state machine takes care of states in anything from compiler programs, file readers and client/server systems to games and applications. A state can be, for example, 'showing menu', 'running game' or 'game over'. By using a central state machine each functionality of the game or application can be individually programmed in separate scripts or systems and by simply reading of the state value, or even receive events from the state machine, each script can know what to do, if is should be inactive or start doing something.

This node reads a specified XML file with state and transition specifications. Events can be associated with transitions, or with entering or exiting states, providing events and values through routing.

Details on the XML syntax are given in the HTML documentation.


I18N

The string to be used in a game or application can be specified in a language file. This file is read by the I18N node from which each string is routed from a field to the label, button or other widget that requires a string.

The GettextWrapper script is much more convenient to use.


XSplinePositionInterpolator

This is a position interpolator that is using the x-spline to define the path. X-Spline is an alternative to traditional splines and was introduced by Carole Blanc and Christophe Schlick in 1995. It is capable of defining a mixture of corners that are of various softness so that both a smooth bend and hard corners can be defined in the same path.

Personal tools
go to