ptjt255
07-30-2009, 07:50 AM
Hi,
I wonder if someone can help me, I am trying to set up a semi-circle array of positions on the left hand side of the screen, depending on how many distractors are selected (e.g. either 2, 4, 6 or 8) each position should contain one target object and the rest distractors, these should be randomised. I then want the target position to be a hotspot. But at this stage I'm having trouble just getting an array of positions where I want them with the correct objects in them.
Any help would be hugely appreciated.
Thank you.
import viz
import viztask
import random
viz.go()
Z_dist = -5
#viz.move(0,0,Z_dist)
viz.MainView.move(0.5,0,-10)
# Add distractor and target objects
ballsize = [2.0,2.0,2.0,1.0,1.0,1.0]
# Distractor ball
distractor = viz.add('soccerball.ive')
distractor.setScale(ballsize[0],ballsize[1],2)
distractor.addAction(vizact.spin(0,1,0,100))
# Target Ball
target = viz.add('ball.wrl')
target.setScale(ballsize[3],ballsize[4],1)
target.addAction(vizact.spin(0,1,0,100))
# Set up zones for the objects to appear on the screen
choice = ['2', '4', '6', '8']
select = viz.choose('How many distractors?', choice)
#make a list with the objects in it
objects = [distractor,target]
# keep 2 positions in an array
pos = [[-1.0,0.0,Z_dist],[-1.0,0.5,Z_dist],[-2.0,1.0,Z_dist],[-1.0,1.5,Z_dist],[-1.0,2.0,Z_dist],[-1.0,2.5,Z_dist],[-1.0,3.0,Z_dist],[-1.0,3.5,Z_dist]]
rand_positions = []
def sceneOn(num):
global rand_positions
positions = [0,1,2,3,4,5,6,7]
if select == 0:
#set objects to 2 different random positions
rand_positions = random.sample(positions,2)
objects[0].setPosition(pos[rand_positions[0]])
objects[1].setPosition(pos[rand_positions[1]])
if select == 1:
#set objects to 4 different random positions
rand_positions = random.sample(positions,4)
objects[0].setPosition(pos[rand_positions[0]])
objects[0].setPosition(pos[rand_positions[1]])
objects[0].setPosition(pos[rand_positions[2]])
objects[1].setPosition(pos[rand_positions[3]])
if select == 2:
#set objects to 4 different random positions
rand_positions = random.sample(positions,6)
objects[0].setPosition(pos[rand_positions[0]])
objects[0].setPosition(pos[rand_positions[1]])
objects[0].setPosition(pos[rand_positions[2]])
objects[0].setPosition(pos[rand_positions[3]])
objects[0].setPosition(pos[rand_positions[4]])
objects[1].setPosition(pos[rand_positions[5]])
if select == 3:
rand_positions = random.sample(positions,8)
objects[0].setPosition(pos[rand_positions[0]])
objects[0].setPosition(pos[rand_positions[1]])
objects[0].setPosition(pos[rand_positions[2]])
objects[0].setPosition(pos[rand_positions[3]])
objects[0].setPosition(pos[rand_positions[4]])
objects[0].setPosition(pos[rand_positions[5]])
objects[0].setPosition(pos[rand_positions[6]])
objects[1].setPosition(pos[rand_positions[7]])
sceneOn(1)
farshizzo
08-03-2009, 04:51 PM
Your script was only creating 2 object, even when more than 2 distractors were selected. I modified your script to dynamically create the objects based on the number of distractors. I also modified the sceneOn function to be more general in positioning the objects.
I'm still not sure what you mean by placing the objects in a semi-circle. The list of positions you have pretty much places all the objects in a vertical line.
Anyway, here's the modified script:import viz
import viztask
import random
viz.go()
Z_dist = -5
#viz.move(0,0,Z_dist)
viz.MainView.move(0.5,0,-10)
# Add distractor and target objects
ballsize = [2.0,2.0,2.0,1.0,1.0,1.0]
# Set up zones for the objects to appear on the screen
choice = ['2', '4', '6', '8']
select = viz.choose('How many distractors?', choice)
numDistractors = int(choice[select])
#make a list with the objects in it
objects = []
# Distractor ball
for x in range(numDistractors-1):
distractor = viz.add('soccerball.ive')
distractor.setScale(ballsize[0],ballsize[1],2)
distractor.addAction(vizact.spin(0,1,0,100))
objects.append(distractor)
# Target Ball
target = viz.add('ball.wrl')
target.setScale(ballsize[3],ballsize[4],1)
target.addAction(vizact.spin(0,1,0,100))
objects.append(target)
# keep 2 positions in an array
pos = [[-1.0,0.0,Z_dist],[-1.0,0.5,Z_dist],[-2.0,1.0,Z_dist],[-1.0,1.5,Z_dist],[-1.0,2.0,Z_dist],[-1.0,2.5,Z_dist],[-1.0,3.0,Z_dist],[-1.0,3.5,Z_dist]]
def sceneOn(num):
# Get random sample of positions
rand_positions = random.sample(pos,numDistractors)
# Apply positions to objects
for p,o in zip(rand_positions,objects):
o.setPosition(p)
sceneOn(1)
ptjt255
08-04-2009, 03:06 AM
Thanks very much for your reply. I have been working hard on this code and it is now completely different from when I posted my initial question. Please see below.
I am having some problems which I would really appreciate help with:
1. how do I stop the avatar going out of the screen?
2. when the avatar's right arm hits the target, I want the avatar to do something e.g. dance, if the avatars right arm hits a distractor then it should something else, e.g. ball should change colour - I have tried setting this up using collisions and hotspots and can't get either to work?
3. I still haven't managed to get the objects in a semi-circle so that they are all equidistant from the avatar start position
Any help would be huegly appreciated. Sorry the code is such a mess, any help with tidying it up would also be greatly appreciated.
Thank you.
import viz
import viztask
import random
import vizjoy
viz.go()
def createlabel():
global trialNumber, time, xPosition
#Create background quad for labels
viz.startlayer(viz.QUADS)
viz.vertexcolor(0,0.2,0)
viz.vertex(0,0,0)
viz.vertex(0,0.05,0)
viz.vertex(0.20,0.05,0)
viz.vertex(0.205,0,0)
InfoQuad = viz.endlayer(viz.SCREEN)
InfoQuad.draworder(30)
InfoQuad.disable(viz.DEPTH_WRITE)
InfoQuad.alpha(0.5)
InfoQuad.translate(1-0.20,0)
#Create label for trial number
trialNumber = InfoQuad.add(viz.TEXT3D,'0')
trialNumber.scale(0.3,0.3,1)
trialNumber.translate(0.01,0.02)
trialNumber.font('times.ttf')
trialNumber.color(viz.GREEN)
trialNumber.draworder(31)
trialNumber.disable(viz.LIGHTING)
trialNumber.alignment(viz.TEXT_LEFT_CENTER)
#Create label for nv
time = InfoQuad.add(viz.TEXT3D,'0')
time.scale(0.3,0.3,1)
time.translate(0.04,0.02)
time.font('times.ttf')
time.color(viz.GREEN)
time.draworder(31)
time.disable(viz.LIGHTING)
time.alignment(viz.TEXT_LEFT_CENTER)
#Create label for reversals
xPosition = InfoQuad.add(viz.TEXT3D,'0')
xPosition.scale(0.3,0.3,1)
xPosition.translate(0.08,0.02)
xPosition.font('times.ttf')
xPosition.color(viz.GREEN)
xPosition.draworder(31)
xPosition.disable(viz.LIGHTING)
xPosition.alignment(viz.TEXT_LEFT_CENTER)
createlabel()
joystick = vizjoy.add()
viz.mouse(viz.OFF)
viz.mouse.setTrap(viz.ON)
#viz.mouse.setVisible(viz.OFF)
Z_dist = -5
viz.MainView.move(0.5,0,-10)
filename = viz.input('Input data file name')
file = filename + 'T1StaticObjects' + '.txt'
print 'Filename: ', file
#viz.window.setSize(-1) # set to full size
# Add distractor and target objects
ballsize = [2.0,2.0,2.0]
# Distractor ball
distractor = viz.add('soccerball.ive')
distractorClone1 = distractor.clone() #Copy the object
distractorClone1.setScale(ballsize[0],ballsize[1],2)
distractorClone1.addAction(vizact.spin(0,1,0,100))
distractorClone2 = distractor.clone() #Copy the object
distractorClone2.setScale(ballsize[0],ballsize[1],2)
distractorClone2.addAction(vizact.spin(0,1,0,100))
distractorClone3 = distractor.clone() #Copy the object
distractorClone3.setScale(ballsize[0],ballsize[1],2)
distractorClone3.addAction(vizact.spin(0,1,0,100))
distractorClone4 = distractor.clone() #Copy the object
distractorClone4.setScale(ballsize[0],ballsize[1],2)
distractorClone4.addAction(vizact.spin(0,1,0,100))
distractorClone5 = distractor.clone() #Copy the object
distractorClone5.setScale(ballsize[0],ballsize[1],2)
distractorClone5.addAction(vizact.spin(0,1,0,100))
# Target Ball
target = viz.add('soccerball.ive')
target.setScale(ballsize[0],ballsize[1],2)
target.addAction(vizact.spin(0,-1,0,100))
pos = [[-1.5,1.5,Z_dist],[-1.5,2.5,Z_dist]]
pos1 = [[-1.5,0.75,Z_dist],[-1.5,1.5,Z_dist],[-1.5,2.25,Z_dist],[-1.5,3.0,Z_dist]]
pos2 = [[-1.5,0.5,Z_dist],[-1.5,1.0,Z_dist],[-1.5,1.5,Z_dist],[-1.5,2.0,Z_dist],[-1.5,2.5,Z_dist],[-1.5,3.0,Z_dist]]
objects = [target,distractorClone1,distractorClone2,distracto rClone3,distractorClone4,distractorClone5]
# Set up zones for the objects to appear on the screen
choice = ['1', '3', '5']
select = viz.choose('How many distractors?', choice)
def sceneOn():
global target_position,rand_pos,Rotation
if select == 0:
# set objects to 2 random positions
rand_pos = random.sample(pos,2)
objects[0].setPosition(rand_pos[0])
objects[1].setPosition(rand_pos[1])
target_position = rand_pos[0]
print 'target position:', target_position
if select == 1:
#set objects to 4 different random positions
rand_pos = random.sample(pos1,4)
objects[0].setPosition(rand_pos[0])
objects[1].setPosition(rand_pos[1])
objects[2].setPosition(rand_pos[2])
objects[3].setPosition(rand_pos[3])
target_position = rand_pos[0]
print 'target position:', target_position
if select == 2:
#set objects to 6 different random positions
rand_pos = random.sample(pos2,6)
objects[0].setPosition(rand_pos[0])
objects[1].setPosition(rand_pos[1])
objects[2].setPosition(rand_pos[2])
objects[3].setPosition(rand_pos[3])
objects[4].setPosition(rand_pos[4])
objects[5].setPosition(rand_pos[5])
target_position = rand_pos[0]
print 'target position:', target_position
# Set up male and female avatars
choice2 = ['male', 'female']
select2 = viz.choose('Gender of participant?', choice2)
if select2 == 0:
avatar = viz.add('vcc_male.cfg')
if select2 == 1:
avatar = viz.add('vcc_female.cfg')
avatar.lookat(-10, 0, -10)
avatar.state(1)
import time
def position_loop():
global pos_inc, x, y, Rotation, start_position, target_position, rand_pos
tinc = 1/500
pos_inc = [0,0]
start_position = (3.0, 1.0,Z_dist)
start_time = time.time()
elapsed_time = time.time() - start_time
total_reps = 10
def position_timer(num):
global pos_inc, start_position, target_position,Rotation
position = joystick.getPosition()
Rotation = joystick.getRotation()
pos_inc[0] = pos_inc[0] + position[0]/50
pos_inc[1] = pos_inc[1] + position[1]/50
x = start_position[0]+pos_inc[0]
y = start_position[1]+pos_inc[1]
avatar.setPosition(x,y,Z_dist)
if Rotation > 1:
elapsed_time = time.time() - start_time
#print 'Elapsed Time: ', elapsed_time, 'X Position: ', x, 'Y Position: ', y #Y',"%.2f, %.2f, %.2f" % (elapsed_time,x,y)
SaveData(select, select2, elapsed_time, x, y)
viz.callback(viz.TIMER_EVENT,position_timer)
viz.starttimer(1,tinc,viz.FOREVER)
def experiment():
global pos_inc, x, y, Rotation, start_position, target_position, select, select2, elapsed_time,rand_pos
#updatelabel(0,0,0)
total_reps = 10
for i in range (total_reps):
print total_reps
yield viztask.waitKeyDown(' ')
position_loop()
#Ready = viz.ask('Are You Ready?')
#yield viztask.waitKeyDown(' ')
yield viztask.waitMouseDown(viz.MOUSEBUTTON_LEFT)
avatar.lookat(-10, 0, -5)
sceneOn()
avatar.state(2)
armBone = avatar.getBone('Bip01 R UpperArm')
# Don't move the bone with built-in animations
armBone.lock()
# Raise arm
armBone.setEuler(0, 0, -70)
#updatelabel(tr,round(x,1), round(elapsed_time),1)
#def updatelabel(tr,x,elapsed_time):
# global trialNumber, time, xPosition
# trialNumber.message(str(tr))
# time.message(str(elapsed_time))
# xPosition.message(str(x))
import vizinfo
# Define a function that saves data
file = open(filename + 'T1StaticObjects', 'w')
def SaveData(a,b,c,d,e):
# Create the output string
out = str(a) + '\t' + str(b) + '\t' + str(c) + '\t' + str(d) + '\t' + str(e) + '\n'
out_headings = 'Distractor Number' + '\t' + 'Avatar' + '\t' + 'Elapsed Time' + '\t' + 'x Position' + '\t' + 'y Position' + '\t'
if a == 0:
file.write (out_headings)
# Write the string to the output file
file.write(out)
# Makes sure the file data is really written to the harddrive
file.flush()
viztask.schedule(experiment())
vBulletin® v3.8.7, Copyright ©2000-2025, vBulletin Solutions, Inc.