development of multiplatform, vr applications pablo figueroa 1, pierre boulanger 1, h. j. hoover 1,...

13
Development of Development of Multiplatform, VR Multiplatform, VR Applications Applications Pablo Figueroa Pablo Figueroa 1 1 , Pierre , Pierre Boulanger Boulanger 1 , H. J. Hoover , H. J. Hoover 1 , , Mark Green Mark Green 2 2 , Robyn Taylor , Robyn Taylor 1 1. University of Alberta 2. City University of Hong Kong

Upload: douglas-warren

Post on 03-Jan-2016

214 views

Category:

Documents


0 download

TRANSCRIPT

Development of Development of Multiplatform, VRMultiplatform, VR

ApplicationsApplications

Pablo FigueroaPablo Figueroa11, Pierre , Pierre BoulangerBoulanger11, H. J. Hoover, H. J. Hoover11, ,

Mark GreenMark Green22, Robyn Taylor, Robyn Taylor11

1. University of Alberta2. City University of Hong Kong

ContentsContents

MotivationMotivation GoalsGoals Our ApproachOur Approach Example: A Matching TestExample: A Matching Test ConclusionsConclusions

MotivationMotivation

Motivation (2)Motivation (2)

Motivation (2)Motivation (2)

VR applications running in…VR applications running in… Different hardware platformsDifferent hardware platforms

– PCsPCs– SMART BoardSMART Board– Head Mounted Display + JoystickHead Mounted Display + Joystick– 2 Screens + Tracker2 Screens + Tracker– Passive StereoPassive Stereo– VizRoomVizRoom

Different interaction techniquesDifferent interaction techniques An affordable wayAn affordable way

GoalsGoals

Our goals are:Our goals are: To provide a development environment To provide a development environment

suitable for multiple platformssuitable for multiple platforms

To minimize difficulties due to hardware To minimize difficulties due to hardware differences when implementing an differences when implementing an application across multiple platformsapplication across multiple platforms

To facilitate communication between To facilitate communication between application designers and programmersapplication designers and programmers

Our ApproachOur Approach

InTml: Interaction Techniques InTml: Interaction Techniques Markup LanguageMarkup Language

Descriptive language between Descriptive language between designers and programmersdesigners and programmers

Core implementation in different Core implementation in different platformsplatforms

More information at More information at http://www.cs.ualberta.ca/~pfiguero/Ihttp://www.cs.ualberta.ca/~pfiguero/InTmlnTml

Example: A Matching TestExample: A Matching Test

We are currently working on a small We are currently working on a small example of a VR application developed example of a VR application developed using the InTml framework.using the InTml framework.

In this application, the user must match In this application, the user must match pairs of objects in a 3D environment. The pairs of objects in a 3D environment. The interaction techniques used must be interaction techniques used must be appropriate to the environment the user is appropriate to the environment the user is working within.working within.

Standard PC with Mouse & KeyboardStandard PC with Mouse & Keyboard

Orientation and position moving the mouse while pressing different combinations of keyboard and mouse buttons.

SMART BoardSMART Board

Orientation and position of the objects by drawingon the screen withdifferent pens.

InTml CodeInTml Code

<?xml version="1.0" encoding="UTF-8"?><?xml version="1.0" encoding="UTF-8"?><!DOCTYPE App PUBLIC "-//pfiguero//3D Interaction Techniques ML//EN"<!DOCTYPE App PUBLIC "-//pfiguero//3D Interaction Techniques ML//EN" "http://www.cs.ualberta.ca/~pfiguero/InTmlTemp/spec/intml.dtd">"http://www.cs.ualberta.ca/~pfiguero/InTmlTemp/spec/intml.dtd"><!-- Copyright info<!-- Copyright info matchingAppPC: The matching application, standard PC versionmatchingAppPC: The matching application, standard PC version

Copyright (C) 2001, Pablo FigueroaCopyright (C) 2001, Pablo Figueroa

This library is free software; you can redistribute it and/orThis library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Publicmodify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; eitherLicense as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty ofbut WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNUMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General PublicYou should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free SoftwareLicense along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USAFoundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -->--><!-- Assumptions <!-- Assumptions - The initial viewpoint is looking to -z from (0,0,0)- The initial viewpoint is looking to -z from (0,0,0) - The valid x, y positions are between (-20, 20)- The valid x, y positions are between (-20, 20) -->--><App id="matchingTest.matchingAppPC"><App id="matchingTest.matchingAppPC"> <ShortDesc>Matching application in the PC platform</ShortDesc><ShortDesc>Matching application in the PC platform</ShortDesc> <Import id="matchingTest"/><Import id="matchingTest"/> <Overrides classId="matchingTest.genericPCApp"/><Overrides classId="matchingTest.genericPCApp"/>

<!-- Load objects --><!-- Load objects --> <Object id="obj1" filename="media/car.3ds" type="VRObject"/><Object id="obj1" filename="media/car.3ds" type="VRObject"/> <Object id="obj2" filename="media/Dodge32.3ds" type="VRObject"/><Object id="obj2" filename="media/Dodge32.3ds" type="VRObject"/> <Object id="obj3" filename="media/beethoven.obj" type="VRObject"/><Object id="obj3" filename="media/beethoven.obj" type="VRObject"/> <Object id="selectableObjs" type="Scene"/><Object id="selectableObjs" type="Scene"/> <Binding iE="_self" iP="obj1" oE="selectableObjs" oP="addObject"/><Binding iE="_self" iP="obj1" oE="selectableObjs" oP="addObject"/> <Binding iE="_self" iP="obj2" oE="selectableObjs" oP="addObject"/><Binding iE="_self" iP="obj2" oE="selectableObjs" oP="addObject"/> <Binding iE="_self" iP="obj3" oE="selectableObjs" oP="addObject"/><Binding iE="_self" iP="obj3" oE="selectableObjs" oP="addObject"/>

<!-- Create viewpoint --><!-- Create viewpoint --> <Constant id="pV" type="Pos3D" value="0 0 0"/><Constant id="pV" type="Pos3D" value="0 0 0"/> <Constant id="qV" type="Quaternion" value="0 0 -1 0"/><Constant id="qV" type="Quaternion" value="0 0 -1 0"/> <Constant id="notVisible" type="boolean" value="false"/><Constant id="notVisible" type="boolean" value="false"/> <Object id="viewpoint" filename="" type="Viewpoint"/><Object id="viewpoint" filename="" type="Viewpoint"/> <Binding iE="_self" iP="pV" oE="viewpoint" oP="setPos"/><Binding iE="_self" iP="pV" oE="viewpoint" oP="setPos"/> <Binding iE="_self" iP="qV" oE="viewpoint" oP="setQ"/><Binding iE="_self" iP="qV" oE="viewpoint" oP="setQ"/> <Binding iE="_self" iP="notVisible" oE="viewpoint" oP="setVisible"/><Binding iE="_self" iP="notVisible" oE="viewpoint" oP="setVisible"/> <!-- Link it to the viewpoint in the system --><!-- Link it to the viewpoint in the system --> <Binding iE="_self" iP="viewpoint" oE="theCurrentViewpoint" oP="object"/><Binding iE="_self" iP="viewpoint" oE="theCurrentViewpoint" oP="object"/>

<!-- Localize objects at random --><!-- Localize objects at random --> <Constant id="dimGrid" type="int" value="10"/><Constant id="dimGrid" type="int" value="10"/> <Filter id="randomPQ" type="RandomPQ"/><Filter id="randomPQ" type="RandomPQ"/> <Binding iE="_self" iP="dimGrid" oE="randomPQ" oP="gridDimension"/><Binding iE="_self" iP="dimGrid" oE="randomPQ" oP="gridDimension"/> <Binding iE="_self" iP="obj1" oE="randomPQ" oP="objs"/><Binding iE="_self" iP="obj1" oE="randomPQ" oP="objs"/> <Binding iE="_self" iP="obj2" oE="randomPQ" oP="objs"/><Binding iE="_self" iP="obj2" oE="randomPQ" oP="objs"/> <Binding iE="_self" iP="obj3" oE="randomPQ" oP="objs"/><Binding iE="_self" iP="obj3" oE="randomPQ" oP="objs"/> <!-- Bind the current output display to randomPQ.outputDevice --><!-- Bind the current output display to randomPQ.outputDevice --> <Binding iE="_self" iP="screen" oE="randomPQ" oP="outputDevice"/><Binding iE="_self" iP="screen" oE="randomPQ" oP="outputDevice"/>

<!-- Create transparent copies of objects and localize them at random --><!-- Create transparent copies of objects and localize them at random --> <Filter id="tCopy1" type="TransparentCopy"/><Filter id="tCopy1" type="TransparentCopy"/> <Filter id="tCopy2" type="TransparentCopy"/><Filter id="tCopy2" type="TransparentCopy"/> <Filter id="tCopy3" type="TransparentCopy"/><Filter id="tCopy3" type="TransparentCopy"/> <Object id="transparentObjs" type="Scene"/><Object id="transparentObjs" type="Scene"/> <Binding iE="_self" iP="obj1" oE="tCopy1" oP="obj"/><Binding iE="_self" iP="obj1" oE="tCopy1" oP="obj"/> <Binding iE="_self" iP="obj2" oE="tCopy2" oP="obj"/><Binding iE="_self" iP="obj2" oE="tCopy2" oP="obj"/> <Binding iE="_self" iP="obj3" oE="tCopy3" oP="obj"/><Binding iE="_self" iP="obj3" oE="tCopy3" oP="obj"/> <Binding iE="tCopy1" iP="objCopied" oE="randomPQ" oP="objs"/><Binding iE="tCopy1" iP="objCopied" oE="randomPQ" oP="objs"/> <Binding iE="tCopy2" iP="objCopied" oE="randomPQ" oP="objs"/><Binding iE="tCopy2" iP="objCopied" oE="randomPQ" oP="objs"/> <Binding iE="tCopy3" iP="objCopied" oE="randomPQ" oP="objs"/><Binding iE="tCopy3" iP="objCopied" oE="randomPQ" oP="objs"/> <Binding iE="tCopy1" iP="objCopied" oE="transparentObjs" oP="addObject"/><Binding iE="tCopy1" iP="objCopied" oE="transparentObjs" oP="addObject"/> <Binding iE="tCopy2" iP="objCopied" oE="transparentObjs" oP="addObject"/><Binding iE="tCopy2" iP="objCopied" oE="transparentObjs" oP="addObject"/> <Binding iE="tCopy3" iP="objCopied" oE="transparentObjs" oP="addObject"/><Binding iE="tCopy3" iP="objCopied" oE="transparentObjs" oP="addObject"/>

<!-- Make selectableObjs selectable --><!-- Make selectableObjs selectable --> <!-- Create selection technique and bind it as necessary --><!-- Create selection technique and bind it as necessary --> <Filter id="selection" type="SelectByRay"/><Filter id="selection" type="SelectByRay"/> <Binding iE="_self" iP="selectableObjs" oE="selection" oP="scene"/><Binding iE="_self" iP="selectableObjs" oE="selection" oP="scene"/> <Binding iE="mouse" iP="mousePos" oE="selection" oP="pos"/><Binding iE="mouse" iP="mousePos" oE="selection" oP="pos"/>

<!-- Give feedback of selection --><!-- Give feedback of selection --> <Filter id="highlight" type="HighlightedFeedback"/><Filter id="highlight" type="HighlightedFeedback"/> <Binding iE="selection" iP="object" oE="highlight" oP="obj"/><Binding iE="selection" iP="object" oE="highlight" oP="obj"/> <Binding iE="selection" iP="deselected" oE="highlight" oP="deselected"/><Binding iE="selection" iP="deselected" oE="highlight" oP="deselected"/>

<!-- Grab an object (See translate or rotate) --><!-- Grab an object (See translate or rotate) -->

<!-- Rotate an object --><!-- Rotate an object --> <Filter id="rotateObj" type="RotationBehavior"/><Filter id="rotateObj" type="RotationBehavior"/> <Binding iE="mouse" iP="lButtonPressed" oE="rotateObj" oP="buttonPressed"/><Binding iE="mouse" iP="lButtonPressed" oE="rotateObj" oP="buttonPressed"/> <Binding iE="mouse" iP="lButtonReleased" oE="rotateObj" oP="buttonReleased"/><Binding iE="mouse" iP="lButtonReleased" oE="rotateObj" oP="buttonReleased"/> <Binding iE="mouse" iP="mousePos" oE="rotateObj" oP="pointerPos"/><Binding iE="mouse" iP="mousePos" oE="rotateObj" oP="pointerPos"/> <Binding iE="selection" iP="object" oE="rotateObj" oP="obj"/><Binding iE="selection" iP="object" oE="rotateObj" oP="obj"/> <Binding iE="selection" iP="deselected" oE="rotateObj" oP="deselected"/><Binding iE="selection" iP="deselected" oE="rotateObj" oP="deselected"/>

<!-- Translate an object --> <!-- Translate an object --> <Filter id="translateObj" type="TranslationBehavior"/><Filter id="translateObj" type="TranslationBehavior"/> <Binding iE="mouse" iP="rButtonPressed" oE="translateObj" oP="buttonPressed"/><Binding iE="mouse" iP="rButtonPressed" oE="translateObj" oP="buttonPressed"/> <Binding iE="mouse" iP="rButtonReleased" oE="translateObj" oP="buttonReleased"/><Binding iE="mouse" iP="rButtonReleased" oE="translateObj" oP="buttonReleased"/> <Binding iE="mouse" iP="mousePos" oE="translateObj" oP="pointerPos"/><Binding iE="mouse" iP="mousePos" oE="translateObj" oP="pointerPos"/> <Binding iE="keyboard" iP="z" oE="translateObj" oP="movXY"/><Binding iE="keyboard" iP="z" oE="translateObj" oP="movXY"/> <Binding iE="keyboard" iP="x" oE="translateObj" oP="movXZ"/><Binding iE="keyboard" iP="x" oE="translateObj" oP="movXZ"/> <Binding iE="keyboard" iP="c" oE="translateObj" oP="movYZ"/><Binding iE="keyboard" iP="c" oE="translateObj" oP="movYZ"/> <Binding iE="selection" iP="object" oE="translateObj" oP="obj"/><Binding iE="selection" iP="object" oE="translateObj" oP="obj"/> <Binding iE="selection" iP="deselected" oE="translateObj" oP="deselected"/><Binding iE="selection" iP="deselected" oE="translateObj" oP="deselected"/>

<!-- Release an object --> <!-- Release an object --> <!-- (Done by rotate and translate) --> <!-- (Done by rotate and translate) -->

<!-- Compute matching function --> <!-- Compute matching function --> <Filter id="matchFunction1" type="MatchFunction"/><Filter id="matchFunction1" type="MatchFunction"/> <Filter id="matchFunction2" type="MatchFunction"/><Filter id="matchFunction2" type="MatchFunction"/> <Filter id="matchFunction3" type="MatchFunction"/><Filter id="matchFunction3" type="MatchFunction"/> <Binding iE="_self" iP="obj1" oE="matchFunction1" oP="obj"/><Binding iE="_self" iP="obj1" oE="matchFunction1" oP="obj"/> <Binding iE="tCopy1" iP="objCopied" oE="matchFunction1" oP="copyObj"/><Binding iE="tCopy1" iP="objCopied" oE="matchFunction1" oP="copyObj"/> <Binding iE="_self" iP="obj2" oE="matchFunction2" oP="obj"/><Binding iE="_self" iP="obj2" oE="matchFunction2" oP="obj"/> <Binding iE="tCopy2" iP="objCopied" oE="matchFunction2" oP="copyObj"/><Binding iE="tCopy2" iP="objCopied" oE="matchFunction2" oP="copyObj"/> <Binding iE="_self" iP="obj3" oE="matchFunction3" oP="obj"/><Binding iE="_self" iP="obj3" oE="matchFunction3" oP="obj"/> <Binding iE="tCopy3" iP="objCopied" oE="matchFunction3" oP="copyObj"/><Binding iE="tCopy3" iP="objCopied" oE="matchFunction3" oP="copyObj"/> <Binding iE="obj1" iP="posChanged" oE="matchFunction1" oP="compute"/><Binding iE="obj1" iP="posChanged" oE="matchFunction1" oP="compute"/> <Binding iE="obj1" iP="qChanged" oE="matchFunction1" oP="compute"/><Binding iE="obj1" iP="qChanged" oE="matchFunction1" oP="compute"/> <Binding iE="obj2" iP="posChanged" oE="matchFunction2" oP="compute"/><Binding iE="obj2" iP="posChanged" oE="matchFunction2" oP="compute"/> <Binding iE="obj2" iP="qChanged" oE="matchFunction2" oP="compute"/><Binding iE="obj2" iP="qChanged" oE="matchFunction2" oP="compute"/> <Binding iE="obj3" iP="posChanged" oE="matchFunction3" oP="compute"/><Binding iE="obj3" iP="posChanged" oE="matchFunction3" oP="compute"/> <Binding iE="obj3" iP="qChanged" oE="matchFunction3" oP="compute"/><Binding iE="obj3" iP="qChanged" oE="matchFunction3" oP="compute"/> <!-- Control all InTs --> <!-- Control all InTs --> <Filter id="control" type="ControlMatching"/><Filter id="control" type="ControlMatching"/> <Binding iE="_self" iP="selection" oE="control" oP="selection"/><Binding iE="_self" iP="selection" oE="control" oP="selection"/> <!-- Link platform-specific InTs --><!-- Link platform-specific InTs --> <Binding iE="_self" iP="rotateObj" oE="control" oP="rotation"/><Binding iE="_self" iP="rotateObj" oE="control" oP="rotation"/> <Binding iE="rotateObj" iP="inMode" oE="control" oP="inModeRotation"/><Binding iE="rotateObj" iP="inMode" oE="control" oP="inModeRotation"/> <Binding iE="_self" iP="translateObj" oE="control" oP="translation"/><Binding iE="_self" iP="translateObj" oE="control" oP="translation"/> <Binding iE="translateObj" iP="inMode" oE="control" oP="inModeTranslation"/><Binding iE="translateObj" iP="inMode" oE="control" oP="inModeTranslation"/> <Binding iE="rotateObj" iP="finishing" oE="control" oP="endRotation"/><Binding iE="rotateObj" iP="finishing" oE="control" oP="endRotation"/> <Binding iE="translateObj" iP="finishing" oE="control" oP="endTranslation"/><Binding iE="translateObj" iP="finishing" oE="control" oP="endTranslation"/> <Binding iE="_self" iP="matchFunction1" oE="control" oP="match1"/><Binding iE="_self" iP="matchFunction1" oE="control" oP="match1"/> <Binding iE="_self" iP="matchFunction2" oE="control" oP="match2"/><Binding iE="_self" iP="matchFunction2" oE="control" oP="match2"/> <Binding iE="_self" iP="matchFunction3" oE="control" oP="match3"/><Binding iE="_self" iP="matchFunction3" oE="control" oP="match3"/>

<!-- Delete objects once they match --> <!-- Delete objects once they match --> <Filter id="deleteObjs1" type="DeleteWhenSignal"/><Filter id="deleteObjs1" type="DeleteWhenSignal"/> <Filter id="deleteObjs2" type="DeleteWhenSignal"/><Filter id="deleteObjs2" type="DeleteWhenSignal"/> <Filter id="deleteObjs3" type="DeleteWhenSignal"/><Filter id="deleteObjs3" type="DeleteWhenSignal"/> <Binding iE="_self" iP="obj1" oE="deleteObjs1" oP="obj"/><Binding iE="_self" iP="obj1" oE="deleteObjs1" oP="obj"/> <Binding iE="tCopy1" iP="objCopied" oE="deleteObjs1" oP="obj"/><Binding iE="tCopy1" iP="objCopied" oE="deleteObjs1" oP="obj"/> <Binding iE="matchFunction1" iP="match" oE="deleteObjs1" oP="signal"/><Binding iE="matchFunction1" iP="match" oE="deleteObjs1" oP="signal"/> <Binding iE="_self" iP="obj2" oE="deleteObjs2" oP="obj"/><Binding iE="_self" iP="obj2" oE="deleteObjs2" oP="obj"/> <Binding iE="tCopy2" iP="objCopied" oE="deleteObjs2" oP="obj"/><Binding iE="tCopy2" iP="objCopied" oE="deleteObjs2" oP="obj"/> <Binding iE="matchFunction2" iP="match" oE="deleteObjs2" oP="signal"/><Binding iE="matchFunction2" iP="match" oE="deleteObjs2" oP="signal"/> <Binding iE="_self" iP="obj3" oE="deleteObjs3" oP="obj"/><Binding iE="_self" iP="obj3" oE="deleteObjs3" oP="obj"/> <Binding iE="tCopy3" iP="objCopied" oE="deleteObjs3" oP="obj"/><Binding iE="tCopy3" iP="objCopied" oE="deleteObjs3" oP="obj"/> <Binding iE="matchFunction3" iP="match" oE="deleteObjs3" oP="signal"/><Binding iE="matchFunction3" iP="match" oE="deleteObjs3" oP="signal"/>

<!-- End of the application --><!-- End of the application --> <Filter id="quit" type="QuitMatching"/><Filter id="quit" type="QuitMatching"/> <Binding iE="matchFunction1" iP="match" oE="quit" oP="signal"/><Binding iE="matchFunction1" iP="match" oE="quit" oP="signal"/> <Binding iE="matchFunction2" iP="match" oE="quit" oP="signal"/><Binding iE="matchFunction2" iP="match" oE="quit" oP="signal"/> <Binding iE="matchFunction3" iP="match" oE="quit" oP="signal"/><Binding iE="matchFunction3" iP="match" oE="quit" oP="signal"/> <Binding iE="keyboard" iP="q" oE="quit" oP="abortSignal"/><Binding iE="keyboard" iP="q" oE="quit" oP="abortSignal"/>

<!-- Log start/stop times --><!-- Log start/stop times --> <Filter id="log" type="Log"/><Filter id="log" type="Log"/> <IDevice id="timer" type="Timer"/><IDevice id="timer" type="Timer"/> <Binding iE="timer" iP="curTime" oE="log" oP="curTime"/><Binding iE="timer" iP="curTime" oE="log" oP="curTime"/> <Binding iE="quit" iP="endInfo" oE="log" oP="endSignal"/><Binding iE="quit" iP="endInfo" oE="log" oP="endSignal"/> <!-- Identify user and platform --><!-- Identify user and platform --> <!-- Change this constant to an id for a particular user --><!-- Change this constant to an id for a particular user --> <Constant id="userId" type="String" value="Test user PC"/><Constant id="userId" type="String" value="Test user PC"/> <Constant id="platformId" type="String" value="standardPC"/><Constant id="platformId" type="String" value="standardPC"/> <Binding iE="_self" iP="userId" oE="log" oP="userId"/><Binding iE="_self" iP="userId" oE="log" oP="userId"/> <Binding iE="_self" iP="platformId" oE="log" oP="platformId"/><Binding iE="_self" iP="platformId" oE="log" oP="platformId"/>

<!-- log the experience --><!-- log the experience --> <!-- initial transformations, selected objects, position and orientation <!-- initial transformations, selected objects, position and orientation while moving, match times -->while moving, match times --> <Binding iE="matchFunction1" iP="match" oE="log" oP="matchSignal"/><Binding iE="matchFunction1" iP="match" oE="log" oP="matchSignal"/> <Binding iE="matchFunction2" iP="match" oE="log" oP="matchSignal"/><Binding iE="matchFunction2" iP="match" oE="log" oP="matchSignal"/> <Binding iE="matchFunction3" iP="match" oE="log" oP="matchSignal"/><Binding iE="matchFunction3" iP="match" oE="log" oP="matchSignal"/> <Binding iE="mouse" iP="mousePos" oE="log" oP="pointerPos"/><Binding iE="mouse" iP="mousePos" oE="log" oP="pointerPos"/> <Binding iE="mouse" iP="lButtonPressed" oE="log" oP="rotateStart"/><Binding iE="mouse" iP="lButtonPressed" oE="log" oP="rotateStart"/> <Binding iE="mouse" iP="lButtonReleased" oE="log" oP="rotateStop"/><Binding iE="mouse" iP="lButtonReleased" oE="log" oP="rotateStop"/> <Binding iE="mouse" iP="rButtonPressed" oE="log" oP="translateStart"/><Binding iE="mouse" iP="rButtonPressed" oE="log" oP="translateStart"/> <Binding iE="mouse" iP="rButtonReleased" oE="log" oP="translateStop"/><Binding iE="mouse" iP="rButtonReleased" oE="log" oP="translateStop"/> <Binding iE="keyboard" iP="z" oE="log" oP="movXY"/><Binding iE="keyboard" iP="z" oE="log" oP="movXY"/> <Binding iE="keyboard" iP="x" oE="log" oP="movXZ"/><Binding iE="keyboard" iP="x" oE="log" oP="movXZ"/> <Binding iE="keyboard" iP="c" oE="log" oP="movYZ"/><Binding iE="keyboard" iP="c" oE="log" oP="movYZ"/> <Binding iE="keyboard" iP="q" oE="log" oP="abortSignal"/><Binding iE="keyboard" iP="q" oE="log" oP="abortSignal"/> <Binding iE="selection" iP="object" oE="log" oP="selectedObj"/><Binding iE="selection" iP="object" oE="log" oP="selectedObj"/> <Binding iE="selection" iP="deselected" oE="log" oP="deselectedObj"/><Binding iE="selection" iP="deselected" oE="log" oP="deselectedObj"/>

<Binding iE="obj1" iP="posChanged" oE="log" oP="posObj1"/><Binding iE="obj1" iP="posChanged" oE="log" oP="posObj1"/> <Binding iE="obj1" iP="qChanged" oE="log" oP="qObj1"/><Binding iE="obj1" iP="qChanged" oE="log" oP="qObj1"/> <Binding iE="obj2" iP="posChanged" oE="log" oP="posObj2"/><Binding iE="obj2" iP="posChanged" oE="log" oP="posObj2"/> <Binding iE="obj2" iP="qChanged" oE="log" oP="qObj2"/><Binding iE="obj2" iP="qChanged" oE="log" oP="qObj2"/> <Binding iE="obj3" iP="posChanged" oE="log" oP="posObj3"/><Binding iE="obj3" iP="posChanged" oE="log" oP="posObj3"/> <Binding iE="obj3" iP="qChanged" oE="log" oP="qObj3"/><Binding iE="obj3" iP="qChanged" oE="log" oP="qObj3"/>

<ObjectHolder id="copy1"/><ObjectHolder id="copy1"/> <ObjectHolder id="copy2"/><ObjectHolder id="copy2"/> <ObjectHolder id="copy3"/><ObjectHolder id="copy3"/> <Binding iE="tCopy1" iP="objCopied" oE="copy1" oP="object"/><Binding iE="tCopy1" iP="objCopied" oE="copy1" oP="object"/> <Binding iE="tCopy2" iP="objCopied" oE="copy2" oP="object"/><Binding iE="tCopy2" iP="objCopied" oE="copy2" oP="object"/> <Binding iE="tCopy3" iP="objCopied" oE="copy3" oP="object"/><Binding iE="tCopy3" iP="objCopied" oE="copy3" oP="object"/>

<Binding iE="copy1" iP="posChanged" oE="log" oP="posReplica1"/><Binding iE="copy1" iP="posChanged" oE="log" oP="posReplica1"/> <Binding iE="copy2" iP="qChanged" oE="log" oP="qReplica1"/><Binding iE="copy2" iP="qChanged" oE="log" oP="qReplica1"/> <Binding iE="copy3" iP="posChanged" oE="log" oP="posReplica2"/><Binding iE="copy3" iP="posChanged" oE="log" oP="posReplica2"/> <Binding iE="copy1" iP="qChanged" oE="log" oP="qReplica2"/><Binding iE="copy1" iP="qChanged" oE="log" oP="qReplica2"/> <Binding iE="copy2" iP="posChanged" oE="log" oP="posReplica3"/><Binding iE="copy2" iP="posChanged" oE="log" oP="posReplica3"/> <Binding iE="copy3" iP="qChanged" oE="log" oP="qReplica3"/><Binding iE="copy3" iP="qChanged" oE="log" oP="qReplica3"/>

</App></App>

version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --><!-- Assumptions - The initial viewpoint is looking to -z from (0,0,0) --><App id="matchingTest.matchingAppSMARTBoard"> <ShortDesc>Matching application in the SMART Board platform</ShortDesc> <Import id="matchingTest"/> <Overrides classId="matchingTest.genericSMARTBoardApp"/>

<!-- Load objects --> <Object id="obj1" filename="media/car.3ds" type="VRObject"/> <Object id="obj2" filename="media/Dodge32.3ds" type="VRObject"/> <Object id="obj3" filename="media/beethoven.obj" type="VRObject"/> <Object id="selectableObjs" type="Scene"/> <Binding iE="_self" iP="obj1" oE="selectableObjs" oP="addObject"/> <Binding iE="_self" iP="obj2" oE="selectableObjs" oP="addObject"/> <Binding iE="_self" iP="obj3" oE="selectableObjs" oP="addObject"/>

<!-- Create viewpoint --> <Constant id="pV" type="Pos3D" value="0 0 0"/> <Constant id="qV" type="Quaternion" value="0 0 -1 0"/> <Constant id="notVisible" type="boolean" value="false"/> <Object id="viewpoint" filename="" type="Viewpoint"/> <Binding iE="_self" iP="pV" oE="viewpoint" oP="setPos"/> <Binding iE="_self" iP="qV" oE="viewpoint" oP="setQ"/> <Binding iE="_self" iP="notVisible" oE="viewpoint" oP="setVisible"/> <!-- Link it to the viewpoint in the system --> <Binding iE="_self" iP="viewpoint" oE="theCurrentViewpoint" oP="object"/>

<!-- Localize objects at random --> <Constant id="dimGrid" type="int" value="10"/> <Filter id="randomPQ" type="RandomPQ"/> <Binding iE="_self" iP="dimGrid" oE="randomPQ" oP="gridDimension"/> <Binding iE="_self" iP="obj1" oE="randomPQ" oP="objs"/> <Binding iE="_self" iP="obj2" oE="randomPQ" oP="objs"/> <Binding iE="_self" iP="obj3" oE="randomPQ" oP="objs"/> <!-- Bind the current output display to randomPQ.outputDevice --> <Binding iE="_self" iP="smartboard" oE="randomPQ" oP="outputDevice"/>

<!-- Create transparent copies of objects and localize them at random --> <Filter id="tCopy1" type="TransparentCopy"/> <Filter id="tCopy2" type="TransparentCopy"/> <Filter id="tCopy3" type="TransparentCopy"/> <Object id="transparentObjs" type="Scene"/> <Binding iE="_self" iP="obj1" oE="tCopy1" oP="obj"/> <Binding iE="_self" iP="obj2" oE="tCopy2" oP="obj"/> <Binding iE="_self" iP="obj3" oE="tCopy3" oP="obj"/> <Binding iE="tCopy1" iP="objCopied" oE="randomPQ" oP="objs"/> <Binding iE="tCopy2" iP="objCopied" oE="randomPQ" oP="objs"/> <Binding iE="tCopy3" iP="objCopied" oE="randomPQ" oP="objs"/> <Binding iE="tCopy1" iP="objCopied" oE="transparentObjs" oP="addObject"/> <Binding iE="tCopy2" iP="objCopied" oE="transparentObjs" oP="addObject"/> <Binding iE="tCopy3" iP="objCopied" oE="transparentObjs" oP="addObject"/>

<!-- Make selectableObjs selectable --> <Filter id="selection" type="SelectByRay"/> <Binding iE="smartboard" iP="touchPos" oE="selection" oP="pos"/> <Binding iE="smartboard" iP="screenReleased" oE="selection" oP="flushState"/> <Binding iE="_self" iP="selectableObjs" oE="selection" oP="scene"/>

<!-- Give feedback of selection --> <Filter id="highlight" type="HighlightedFeedback"/> <Binding iE="selection" iP="object" oE="highlight" oP="obj"/> <Binding iE="selection" iP="deselected" oE="highlight" oP="deselected"/> <!-- Release the current state once a pen release the screen--> <Binding iE="smartboard" iP="pen1Released" oE="selection" oP="flushState"/> <Binding iE="smartboard" iP="pen2Released" oE="selection" oP="flushState"/> <Binding iE="smartboard" iP="pen3Released" oE="selection" oP="flushState"/> <Binding iE="smartboard" iP="pen4Released" oE="selection" oP="flushState"/>

<!-- Grab an object (See translate or rotate) -->

<!-- Rotate an object --> <Filter id="rotateObj" type="RotationBehavior"/> <Binding iE="smartboard" iP="pen1Selected" oE="rotateObj" oP="buttonPressed"/> <Binding iE="smartboard" iP="pen1Released" oE="rotateObj" oP="buttonReleased"/> <Binding iE="smartboard" iP="touchPos" oE="rotateObj" oP="pointerPos"/> <Binding iE="selection" iP="object" oE="rotateObj" oP="obj"/> <Binding iE="selection" iP="deselected" oE="rotateObj" oP="deselected"/>

<!-- Translate an object --> <Filter id="translateObj" type="TranslationBehavior"/> <Binding iE="smartboard" iP="pen2Selected" oE="translateObj" oP="buttonPressed"/> <Binding iE="smartboard" iP="pen2Released" oE="translateObj" oP="buttonReleased"/> <Binding iE="smartboard" iP="pen2Selected" oE="translateObj" oP="movXY"/> <Binding iE="smartboard" iP="pen3Selected" oE="translateObj" oP="movXZ"/> <Binding iE="smartboard" iP="pen3Selected" oE="translateObj" oP="buttonPressed"/> <Binding iE="smartboard" iP="pen3Released" oE="translateObj" oP="buttonReleased"/> <Binding iE="smartboard" iP="pen4Selected" oE="translateObj" oP="movYZ"/> <Binding iE="smartboard" iP="pen4Selected" oE="translateObj" oP="buttonPressed"/> <Binding iE="smartboard" iP="pen4Released" oE="translateObj" oP="buttonReleased"/> <Binding iE="smartboard" iP="touchPos" oE="translateObj" oP="pointerPos"/> <Binding iE="selection" iP="object" oE="translateObj" oP="obj"/> <Binding iE="selection" iP="deselected" oE="translateObj" oP="deselected"/>

<!-- Release an object --> <!-- (Done by rotate and translate) -->

<!-- Compute matching function --> <Filter id="matchFunction1" type="MatchFunction"/> <Filter id="matchFunction2" type="MatchFunction"/> <Filter id="matchFunction3" type="MatchFunction"/> <Binding iE="_self" iP="obj1" oE="matchFunction1" oP="obj"/> <Binding iE="tCopy1" iP="objCopied" oE="matchFunction1" oP="copyObj"/> <Binding iE="_self" iP="obj2" oE="matchFunction2" oP="obj"/> <Binding iE="tCopy2" iP="objCopied" oE="matchFunction2" oP="copyObj"/> <Binding iE="_self" iP="obj3" oE="matchFunction3" oP="obj"/> <Binding iE="tCopy3" iP="objCopied" oE="matchFunction3" oP="copyObj"/> <Binding iE="obj1" iP="posChanged" oE="matchFunction1" oP="compute"/> <Binding iE="obj1" iP="qChanged" oE="matchFunction1" oP="compute"/> <Binding iE="obj2" iP="posChanged" oE="matchFunction2" oP="compute"/> <Binding iE="obj2" iP="qChanged" oE="matchFunction2" oP="compute"/> <Binding iE="obj3" iP="posChanged" oE="matchFunction3" oP="compute"/> <Binding iE="obj3" iP="qChanged" oE="matchFunction3" oP="compute"/> <!-- Control all InTs --> <Filter id="control" type="ControlMatching"/> <Binding iE="_self" iP="selection" oE="control" oP="selection"/> <!-- Link platform-specific InTs --> <Binding iE="_self" iP="rotateObj" oE="control" oP="rotation"/> <Binding iE="rotateObj" iP="inMode" oE="control" oP="inModeRotation"/> <Binding iE="_self" iP="translateObj" oE="control" oP="translation"/> <Binding iE="translateObj" iP="inMode" oE="control" oP="inModeTranslation"/> <Binding iE="rotateObj" iP="finishing" oE="control" oP="endRotation"/> <Binding iE="translateObj" iP="finishing" oE="control" oP="endTranslation"/> <Binding iE="_self" iP="matchFunction1" oE="control" oP="match1"/> <Binding iE="_self" iP="matchFunction2" oE="control" oP="match2"/> <Binding iE="_self" iP="matchFunction3" oE="control" oP="match3"/>

<!-- Delete objects once they match --> <Filter id="deleteObjs1" type="DeleteWhenSignal"/> <Filter id="deleteObjs2" type="DeleteWhenSignal"/> <Filter id="deleteObjs3" type="DeleteWhenSignal"/> <Binding iE="_self" iP="obj1" oE="deleteObjs1" oP="obj"/> <Binding iE="tCopy1" iP="objCopied" oE="deleteObjs1" oP="obj"/> <Binding iE="matchFunction1" iP="match" oE="deleteObjs1" oP="signal"/> <Binding iE="_self" iP="obj2" oE="deleteObjs2" oP="obj"/> <Binding iE="tCopy2" iP="objCopied" oE="deleteObjs2" oP="obj"/> <Binding iE="matchFunction2" iP="match" oE="deleteObjs2" oP="signal"/> <Binding iE="_self" iP="obj3" oE="deleteObjs3" oP="obj"/> <Binding iE="tCopy3" iP="objCopied" oE="deleteObjs3" oP="obj"/> <Binding iE="matchFunction3" iP="match" oE="deleteObjs3" oP="signal"/>

<!-- End of the application --> <Filter id="quit" type="QuitMatching"/> <Binding iE="matchFunction1" iP="match" oE="quit" oP="signal"/> <Binding iE="matchFunction2" iP="match" oE="quit" oP="signal"/> <Binding iE="matchFunction3" iP="match" oE="quit" oP="signal"/>

<!-- Log start/stop times --> <Filter id="log" type="Log"/> <IDevice id="timer" type="Timer"/> <Binding iE="timer" iP="curTime" oE="log" oP="curTime"/> <Binding iE="quit" iP="endInfo" oE="log" oP="endSignal"/> <!-- Identify user and platform --> <!-- Change this constant to an id for a particular user --> <Constant id="userId" type="String" value="Test user SMART Board"/> <Constant id="platformId" type="String" value="SMART Board"/> <Binding iE="_self" iP="userId" oE="log" oP="userId"/> <Binding iE="_self" iP="platformId" oE="log" oP="platformId"/>

<!-- log the experience --> <!-- initial transformations, selected objects, position and orientation while moving, match times --> <Binding iE="matchFunction1" iP="match" oE="log" oP="matchSignal"/> <Binding iE="matchFunction2" iP="match" oE="log" oP="matchSignal"/> <Binding iE="matchFunction3" iP="match" oE="log" oP="matchSignal"/> <Binding iE="smartboard" iP="touchPos" oE="log" oP="pointerPos"/> <Binding iE="smartboard" iP="pen1Selected" oE="log" oP="rotateStart"/> <Binding iE="smartboard" iP="pen1Released" oE="log" oP="rotateStop"/> <Binding iE="smartboard" iP="pen1Selected" oE="log" oP="translateStart"/> <Binding iE="smartboard" iP="pen1Released" oE="log" oP="translateStop"/> <Binding iE="smartboard" iP="pen2Selected" oE="log" oP="translateStart"/> <Binding iE="smartboard" iP="pen2Released" oE="log" oP="translateStop"/> <Binding iE="smartboard" iP="pen3Selected" oE="log" oP="translateStart"/> <Binding iE="smartboard" iP="pen3Released" oE="log" oP="translateStop"/> <Binding iE="smartboard" iP="pen4Selected" oE="log" oP="translateStart"/> <Binding iE="smartboard" iP="pen4Released" oE="log" oP="translateStop"/> <Binding iE="smartboard" iP="pen2Selected" oE="log" oP="movXY"/> <Binding iE="smartboard" iP="pen3Selected" oE="log" oP="movXZ"/> <Binding iE="smartboard" iP="pen4Selected" oE="log" oP="movYZ"/></App>

PC: SMART Board:

InTml Development EnvironmentInTml Development Environment

Core Frameworks/APIs: X3D, Java3D, VRJuggler, …

InTml Framework (InTml-F)

InTml Language InTml Tools (InTml-T)(Checker, Browser, Compiler, VPE, …)

VR Developer

VR Designer

InTml Library

InTml LibraryImplementation

ConclusionsConclusions

Non-programmers can describe Non-programmers can describe applications that run in non-applications that run in non-conventional hardware platformsconventional hardware platforms

Programmers can collaborate with Programmers can collaborate with designers in the development of VR designers in the development of VR applicationsapplications

Applications can be tuned to a Applications can be tuned to a particular platform at description particular platform at description levellevel