WorldViz User Forum

WorldViz User Forum (https://forum.worldviz.com/index.php)
-   Vizard (https://forum.worldviz.com/forumdisplay.php?f=17)
-   -   Obtaining Positional Data (https://forum.worldviz.com/showthread.php?t=110)

betancourtb82 03-20-2006 01:22 PM

Ok, everything works great so far. The only problem is that I am getting some kind of traceback error.

Code:

Traceback (most recent call last):
  File "Test2WithEyeAdjustment.py", line 185, in mytimer
    avatar = avatars[nextAvatar]
IndexError: list index out of range

This occurs whenever I shoot an avatar and he disappears. When I double click on the error it highlights:
Code:

def mytimer(num):
        global avatars
        if num == ANIMATION:
               
                #Calculate elapsed time since last update
                elapsed = viz.elapsed()
               
                #Update each active ball
                for bullet in bullets:
                        if bullet.active:
                                #Move the ball and check if it has collided with any objects
                                MoveBullet(bullet,elapsed)
               
        elif num == START_AVATAR:
                global nextAvatar
                #Get the next available avatar and start it
                avatar = avatars[nextAvatar]
                #favatar = favatars[nextAvatar]
                walkAvatar(avatar)
                #walkAvatar(favatar)
                nextAvatar = (nextAvatar + 1) % NUM_AVATARS
                viz.starttimer(START_AVATAR,TIME_BETWEEN_AVATARS)
#Create callbacks for timer events
viz.callback(viz.TIMER_EVENT,mytimer)

When I shoot the avatars, this function is called:
Code:

def shootBullet():
        global nextBullet
        #find the next available ball to shoot
        bullet = bullets[nextBullet]
        nextBullet = (nextBullet + 1) % NUM_BULLETS
        #Calculate the vector of the ball based on the mouse position
        pos = viz.mousepos()
        bulletvector = viz.screentoworld(pos[0]+0.25,pos[1]) #Need to account for stereo
        bullet.vector = viz.Vector(bulletvector[3]-bulletvector[0],bulletvector[4]-bulletvector[1],bulletvector[5]-bulletvector[2])
        bullet.vector.normalize()
        bullet.vector *= BULLET_SPEED
       
        #translate the bullet to the head position
        bullet.translate(viz.get(viz.HEAD_POS))
       
        #make the bullet visible
        bullet.visible(viz.ON)
       
        #mark the bullet as active
        bullet.active = 1

def MoveBullet(bullet,elapsed):
        #get the bullet's current position
        pos = bullet.get(viz.POSITION)
       
        #calculate the balls future position based on it's velocity
        futurePos = pos + (bullet.vector * elapsed)
       
        #Check if bullet intersected with anything
        info = viz.intersect(pos,futurePos)
        if info.intersected:
                if info.object in avatars:
                        #viz.starttimer(FREEZE_AVATAR,info.object.getduration(7)-0.1)
                        WaitThenFreeze = vizact.sequence( vizact.waittime(info.object.getduration(7)-0.05), vizact.speed_node(0) )
                        info.object.execute(7)
                        info.object.clear(viz.ALL)
                        info.object.clear(viz.CURRENT_ACTION)
                        info.object.add(WaitThenFreeze) #Add the action to the avatar
                        RemoveAvatarAction = vizact.call(RemoveAvatar,info.object)
                        info.object.add(RemoveAvatarAction) #Add action to remove avatar

                bullet.visible(0)
                bullet.active = 0
       
        #Update balls positions
        bullet.translate(futurePos.get())
#Shoot a ball whenever left mousebutton is clicked
vizact.onmousedown(viz.MOUSEBUTTON_LEFT,shootBullet)

What does the error mean? Can it be fixed

farshizzo 03-20-2006 02:17 PM

Hi,

That means you are trying to index into the avatar list with a value greater than the size of the list. Are you deleting items from the avatar list after you create it? If so then you need to change the way you increment to the next avatar:
Code:

nextAvatar = (nextAvatar + 1) % len(avatars)

betancourtb82 03-21-2006 09:26 AM

I'm still getting the same error. I'm not sure what is causing it. When a bullet "hits" or intersects an avatar, the following code is called:

Code:

if info.intersected:
                if info.object in avatars:
                        WaitThenFreeze = vizact.sequence( vizact.waittime(info.object.getduration(7)-0.005), vizact.speed_node(0) )
                        info.object.execute(7)
                        info.object.clear(viz.ALL)
                        info.object.clear(viz.CURRENT_ACTION)
                        info.object.add(WaitThenFreeze) #Add the action to the avatar
                        RemoveAvatarAction = vizact.call(RemoveAvatar,info.object)
                        info.object.add(RemoveAvatarAction) #Add action to remove avatar

The RemoveAvatar function is:
Code:

def RemoveAvatar(avatar):
       
        avatar.visible(0) #Hide avatar
        avatar.speed(1) #Restore speed
        avatars.remove(avatar) #Remove from list
        dead_list.append(avatar) #Add to dead list

I tried using the len(avatars) modulus division but it still gives me the same traceback error.

I also tried:
Code:

                if len(avatars) != NUM_AVATARS:
                        avatar = dead_list[nextAvatar]
                        nextAvatar = nextAvatar + 1 % len(dead_list)
                else:
                        avatar = avatars[nextAvatar]
                        nextAvatar = (nextAvatar + 1) % len(avatars)
                walkAvatar(avatar)

but that didn't work either.

betancourtb82 03-21-2006 10:47 AM

New question, similar problem. I have now been told that the avatars must appear with different faces, based on an input. Here is what I have done so far:

Code:

#define a choice variable
choice = viz.input("Please input the condition:")
global facepic
if choice == 1:
        facepic = 'biohead_talk.vzf'
else:
        facepic = 'morph_head.vzf'

#Create six avatars
for i in range(NUM_AVATARS):
        newX = -10 * math.sin(theta * i)
        newZ = 10 * math.tan(theta * i)
        if newZ <=10:
                newZ = -15
        else:
                newZ = 10 * math.tan(theta * i)
        #print i,"\t\t\t\t\t",newX,"\t",newZ
        male = viz.add('male.cfg')
        male.face(facepic)
        male.scale(1.25,1.25,1.25)
        male.translate(newX,-10,newZ)
        avPos = male.get(viz.POSITION)
        print 'original avatar position', avPos
        male.rotate(180,0,0)
        avatars.append(male) #Save avatar in list

Now, when I shoot the avatars, they fall and disappear, as planned. The problem I'm having is that the face still stays on the screen.

Here is the code for removing the avatars once shot:
Code:

        #Check if bullet intersected with anything
        info = viz.intersect(pos,futurePos)
        if info.intersected:
                print 'intersect point is',info.intersectPoint
                if info.object in avatars:
                        WaitThenFreeze = vizact.sequence( vizact.waittime(info.object.getduration(7)-0.005), vizact.speed_node(0) )
                        info.object.execute(7)
                        info.object.clear(viz.ALL)
                        info.object.clear(viz.CURRENT_ACTION)
                        info.object.add(WaitThenFreeze) #Add the action to the avatar
                        RemoveAvatarAction = vizact.call(RemoveAvatar,info.object)
                        info.object.add(RemoveAvatarAction) #Add action to remove avatar

Is there a reason why the face stays floating in the air. I'm assuming it should disappear with the body. Please help.

Thanks

farshizzo 03-21-2006 10:57 AM

Try incrementing the to the next avatar before you access it:
Code:

nextAvatar = (nextAvatar + 1) % len(avatars)
avatar = avatars[nextAvatar]

The face and body of the avatar are two separate objects, so you need to also hide the face when you hide the avatar.

betancourtb82 03-30-2006 01:07 PM

Earilier in this forum, when we discussed the crosshair, you mentioned that we shouldn't be using objects that are attached to the screen when using stereo. I spoke to Mattias this weekend at the VR conference in Alexandria, VA and he mentioned that if we use a 3d object, we would probably be able to fix the problem of the bullets (mentioned in above posts) without having to change the IPD. Is this the case. Is there some way of making a "3d crosshair" that will accurately point to where the bullet would go? If so, do you have any ideas on how this can be implemented? I was thinking of making a vector that would match the vector of the bullet and place an icon (crosshair) at some point on the vector, in 3d, to show an aiming point. How does this idea sound? Can it be done? Please help.

Below is the code I have for the bullet so far.
Code:

def shootBullet():
        global nextBullet
        #find the next available ball to shoot
        bullet = bullets[nextBullet]
        nextBullet = (nextBullet + 1) % NUM_BULLETS
        #Calculate the vector of the ball based on the mouse position
        pos = viz.mousepos()
        bulletvector = viz.screentoworld(pos[0]+0.25,pos[1]) #Need to account for stereo
        bullet.vector = viz.Vector(bulletvector[3]-bulletvector[0],bulletvector[4]-bulletvector[1],bulletvector[5]-bulletvector[2])
        bullet.vector.normalize()
        bullet.vector *= BULLET_SPEED
       
        #translate the bullet to the head position
        bullet.translate(viz.get(viz.HEAD_POS))
       
        #make the bullet visible
        bullet.visible(viz.ON)
       
        #mark the bullet as active
        bullet.active = 1

def MoveBullet(bullet,elapsed):
        global avatarsHit
        #get the bullet's current position
        pos = bullet.get(viz.POSITION)
       
        #calculate the balls future position based on it's velocity
        futurePos = pos + (bullet.vector * elapsed)
       
        #Check if bullet intersected with anything
        info = viz.intersect(pos,futurePos)
        if info.intersected:
                avatarsHit = avatarsHit + 1
                print 'Avatars hit: ', avatarsHit
                print 'intersect point is',info.intersectPoint
                if info.object in avatars:
                        WaitThenFreeze = vizact.sequence( vizact.waittime(info.object.getduration(7)-0.005), vizact.speed_node(0) )
                        info.object.execute(7)
                        info.object.clear(viz.ALL)
                        info.object.clear(viz.CURRENT_ACTION)
                        info.object.add(WaitThenFreeze) #Add the action to the avatar
                        RemoveAvatarAction = vizact.call(RemoveAvatar,info.object)
                        info.object.add(RemoveAvatarAction) #Add action to remove avatar

                bullet.visible(0)
                bullet.active = 0
       
        #Update balls positions
        bullet.translate(futurePos.get())


farshizzo 03-30-2006 01:19 PM

Yes, this is how most people implement crosshairs for stereo viewing. Here is a sample script that will place a crosshair 0.1 meters in front of the user.
Code:

import viz
viz.go(viz.STEREO)

viz.add('tut_ground.wrl')
viz.clearcolor(viz.GRAY)

crosshair = viz.add(viz.TEXQUAD)
crosshair.texture(viz.add('crosshair.png'))
crosshair.scale(0.01,0.01,0.01)

viz.mouse(viz.OFF)

def ontimer(num):
        line = viz.screentoworld(viz.mousepos())
        v = viz.Vector(viz.get(viz.HEAD_POS))
        dir = viz.Vector(line[3:]) - viz.Vector(line[:3])
        dir.normalize()
        dir *= 0.1 #Place crosshair 1/10th meter in front of user
        v += dir
        crosshair.translate(v.get())
        crosshair.rotatequat(viz.get(viz.VIEW_QUAT))
       
viz.callback(viz.TIMER_EVENT,ontimer)
viz.starttimer(0,0,viz.FOREVER)


betancourtb82 04-04-2006 09:40 AM

1 Attachment(s)
Ok, I implemented the crosshair as you said, however I'm still getting an offset between the bullet and the crosshair. Is there anyway to correct this now that I am using the "3d" version of the crosshair? I've attached a copy of the code.

farshizzo 04-04-2006 10:14 AM

I tried your script but I didn't see any bullet. I've modified my previous code so that it shoots a bullet from the center of the viewpoint towards the direction of the crosshair. There will always be an apparent offset between the crosshair and the bullet due to binocular vision.
Code:

import viz
viz.go(viz.STEREO)

viz.add('tut_ground.wrl')
viz.clearcolor(viz.GRAY)

crosshair = viz.add(viz.TEXQUAD)
crosshair.texture(viz.add('crosshair.png'))
crosshair.scale(0.01,0.01,0.01)

viz.mouse(viz.OFF)

def ontimer(num):
        line = viz.screentoworld(viz.mousepos())
        v = viz.Vector(viz.get(viz.HEAD_POS))
        dir = viz.Vector(line[3:]) - viz.Vector(line[:3])
        dir.normalize()
        dir *= 0.1 #Place crosshair 1/10th meter in front of user
        v += dir
        crosshair.translate(v.get())
        crosshair.rotatequat(viz.get(viz.VIEW_QUAT))
       
viz.callback(viz.TIMER_EVENT,ontimer)
viz.starttimer(0,0,viz.FOREVER)

bullet = viz.add('white_ball.wrl')

def shoot():
        pos = viz.Vector(viz.get(viz.HEAD_POS))
        dir = viz.Vector(crosshair.get(viz.POSITION)) - pos
        dir.normalize()
        dir *= 10
        bullet.translate(pos.get())
        bullet.goto((pos+dir).get(),3)
vizact.onmousedown(viz.MOUSEBUTTON_LEFT,shoot)


betancourtb82 04-04-2006 10:46 AM

1 Attachment(s)
I apologize. I think I sent you something I was working on earlier but I corrected it. I still get the same behavior. Would you mind taking a look at this one and let me know if there is something wrong? Thanks

farshizzo 04-04-2006 11:31 AM

In both calls to viz.screentoworld you are adding an offset to the x position. You don't need to do this when using a 3D cursor. Also, after adding the cursor you should disable collisions on it so the bullet does not hit it.
Code:

crosshair.disable(viz.COLLISION)


All times are GMT -7. The time now is 05:54 AM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Copyright 2002-2023 WorldViz LLC