As promised, the class code for followAvatarTask:
Code:
import viz
import vizshape
import vizact
import vizmat
import sys
import os
sys.path.append(os.getcwd() + '/functions')#Standard imports above here!
from sensor import Sensor
from messages import Messages
import routeList
class FollowAvatar:
#
# Training phase constructor. Takes in the current main screen as a parameter which is
# needed to set up a messages object, in order to display messages to the screen from
# here. No other set up parameters are taken here because this is called once at the
# start of the program. setUpExperiment() should be used to initialise a new experiment.
# Constructor takes care of the default settings which will never change throughtout the
# various training phases to be completed in the experiment.
#
def __init__(self, screenToUse = False):
self.message = Messages(screenToUse)
self.avatar = viz.addAvatar('vcc_male.cfg', pos = [0,0,0])
self.avatar.state(1)
self.avatar.disable(viz.DYNAMICS)
self.avatar.setScale(1,1,1)
self.avatar.visible(False)
self.shadowTex = viz.addTexture('shadow.png')
self.shadow = vizshape.addQuad(parent = self.avatar, axis = vizshape.AXIS_Y)
self.shadow.texture(self.shadowTex)
self.shadow.zoffset()
self.head = self.avatar.getBone('Bip01 Head')
viz.playSound('footsteps.wav',viz.SOUND_PRELOAD)
viz.playSound('../sounds/ARETHERE.wav',viz.SOUND_PRELOAD)
self.avatarSpeak = vizact.speak('../sounds/ARETHERE.wav')
self.avatar.visible(False)
#
# Used to setup a new training phase. Takes in the route used for this phase and the failure
# coordinates. Failure coordinates are used to detect when a user strays from tha path during
# the training phase. The route is used to set up a list of sensors which will be used to detect
# AND control the avatar movement along the route. Avatar and user position are also initialised here
#
def setUpExperiment(self, route, failureCoords):
self.distanceFromAvatar = 0
self.avatarWalking = True
self.speakingFlag = True
self.experimentEnded = False
self.firstRun = False
self.failureCoordinates = [ Sensor(coord, size=2) for coord in failureCoords ]
self.avatarStartLocation = [ route[0][0], route[0][1], route[0][2]+5 ]
self.avatarLookAtLocation = route[1]
self.goalLocation = route[-1]
self.startLocation = route[0]
self.sensors = [ Sensor(loc) for loc in route ]
del self.sensors[0] # We only needed the first coordinate to set the above positions
print "About reset the Avatar Euler"
self.avatar.setPosition(self.avatarStartLocation)
self.avatar.lookAt([0,0,0])
viz.collision(viz.OFF)
viz.MainView.setPosition(self.startLocation)
viz.MainView.reset(viz.HEAD_ORI | viz.BODY_ORI)
viz.collision(viz.ON)
self.actions = [
vizact.method.playsound('footsteps.wav',viz.LOOP),
vizact.walkTo(self.sensors[0].getPosition(), 1, turnSpeed = 25.0),
vizact.method.playsound('footsteps.wav',viz.STOP),
vizact.turn(self.sensors[0].getPosition()),
]
self.avatar.visible(True)
return 0
#
# The main run function for an experiment instance. Calls the main internal functions used to
# control the experiment.
#
def runExperiment(self):
if(self.firstRun == False):
self._runFirst()
self._updatePositionInformation()
self._checkDistanceFromAvatar()
self._checkSensors()
self._checkForStray()
#
# This function is run once at the start of an experiment. It kick starts the avatar's actions.
#
def _runFirst(self):
self.avatar.runAction(vizact.sequence(self.actions))
self.firstRun = True
#
# Updates positional data which is used throughout this class. Also calculated the distance
# between the user and the avatar.
#
def _updatePositionInformation(self):
self.avatarPos = self.head.getPosition(viz.ABS_GLOBAL)
self.position = viz.MainView.getPosition()
self.distanceFromAvatar = vizmat.Distance(self.avatarPos,self.position)
#
# Checks to see if we are further than 15 metres away from the avatar. If so then the avatar
# is halted in order to wait for the user to catch up. If not then the avatar continues on
#
def _checkDistanceFromAvatar(self):
if(self.distanceFromAvatar > 15):
self.avatar.state(1)
self.avatarWalking = False
self.avatar.endAction(pool=0)
elif(self.distanceFromAvatar < 15 and self.avatarWalking == False):
self.avatar.state(2)
self.avatarWalking = True
self.avatar.runAction(vizact.sequence(self.actions))
#
# Checks the sensors for avatar and player collision. Uses these collisions to determine
# when the avatar should turn and continue to the next route location as well as sensing
# when the player has arrived at the final destination of the route which triggers the
# end of the training phase.
#
def _checkSensors(self):
if(len(self.sensors) > 1 ):
if(self.sensors[0].onEnter(self.avatarPos)):
try:
self.nextLocation = self.sensors[1].getPosition()
except IndexError:
print "Index Error"
self.actions = [
vizact.method.playsound('footsteps.wav',viz.LOOP),
vizact.walkTo(self.nextLocation, 1, turnSpeed = 200.0),
vizact.method.playsound('footsteps.wav',viz.STOP),
vizact.turn(self.goalLocation),
]
self.avatar.runAction(vizact.sequence(self.actions))
del self.sensors[0]
elif(len(self.sensors) == 1 and self.sensors[0].onEnter(self.avatarPos)):
self.avatar.state(1)
if(self.sensors[0].onEnter(self.position)):
self.firstRun = False
self.avatar.visible(False)
self.experimentEnded = True
def _checkForStray(self):
pass
def returnAvatarEuler(self):
return self.avatar.getEuler()
def setAvatarEuler(self):
self.avatar.lookAt([0,0,0,])