![]() |
|
|
|
#1
|
|||
|
|||
|
I think I'm not doing a very good job of communicating what we are trying to do. I spoke to another person that works here in the lab and he said that he remembered hearing that this software was used for military shooting simulations. Our application is similar. I'm thinking that if the military does it, the "gun" should be relatively accurate. For some reason ours isn't. I've attached the entire prototyped code for your reference. Any suggestions? If after looking at this code you still think it's impossible to get proper accuracy, then I'll move on and try something else. As I mentioned before, it works w/o stereo mode, but not with.
Thanks ![]() Code:
import viz
import vizmat
import math
import time
viz.go(viz.STEREO)
#arrays
avatars = [] #for avatars
collidables = [] #for collidable objects
bullets = [] #for number of balls
#constants
NUM_BULLETS = 3 #number of balls in the array
nextBullet = 0 #index for the next ball in the array
BULLET_SPEED = 250 #speed in meters/secs of the bullet
ANIMATION = 1 #animation ID
NUM_AVATARS = 5 #the number of avatars
court = viz.add('terrain1.wrl')
court.scale(0.5,0.5,0.5)
court.rotate(0,1,0,-90)
court.translate(-5,0,-10)
court.appearance(viz.MODULATE)
court.disable(viz.LIGHT0)
#Add a crosshair
crosshair = viz.add(viz.TEXQUAD,viz.SCREEN)
crosshair.texture(viz.add('crosshair.tif'))
#Create six avatars
def startAvatar(location):
global court
for i in range(NUM_AVATARS):
newX = -math.cos(-2*i+15) * 2
newZ = math.sin(i^2+1) * 2
male = viz.add('male.cfg')
male.translate(newX,0,newZ)
male.rotate(180,0,0)
avatars.append(male) #Save avatar in list
startAvatar(court)
def onmousedown(button):
if button == viz.MOUSEBUTTON_LEFT:
node = viz.pick() #Get object that was clicked
if node in avatars: #Check if object is one of the avatars
node.execute(7) #Execute the "shot" animation
#Create action to wait for the animation duration then freeeze the avatar
WaitThenFreeze = vizact.sequence( vizact.waittime(node.getduration(7)-.1), vizact.speed_node(0) )
node.add(WaitThenFreeze) #Add the action to the avatar
viz.callback(viz.MOUSEDOWN_EVENT,onmousedown)
for x in range(0,NUM_BULLETS):
#create a bullet that is initially hidden
bullet = viz.add('ball.wrl')
bullet.scale(.1,.1,.1)
bullet.visible(viz.OFF)
#add a shadow, To be removed once final program is completed
bullet.shadow = viz.add('shadow.wrl')
bullet.shadow.alpha(0.7)
bullet.shadow.visible(viz.OFF)
#Enable collisions with the ball based on a sphere shape
bullet.collidesphere(0.25)
bullet.isTarget = 0
collidables.append(bullet)
#keep track of the last object the ball hit
bullet.lastHit = 0
#add the ball to the ball list
bullets.append(bullet)
bullet.active = 0
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
bulletvector = viz.screentoworld(viz.mousepos())
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 and it's shadow visible
bullet.visible(viz.ON)
bullet.shadow.visible(viz.ON)
#mark the bullet as active
bullet.active = 1
def MoveBullet(bullet,elapsed):
hitObject = 0
#check if bullet is colliding with an object
for object in collidables:
#perform the collision check with the object
info = bullet.collidingwith(object,1)
if info.intersected:
#set the bullets new vector to the reflection vector
bullet.vector = viz.Vector(vizmat.ReflectionVector(bullet.vector,info.normalVector))
#create a vector of the normal of the collision
normal = viz.Vector(info.normalVector)
#Check dot product of velocity and normal
if bullet.vector * normal <0:
bullet.vector*= -1
#calculate the rotation vector of the ball
bullet.rotvector = bullet.vector * rotRight
#if object.isTarget and ball.lastHit != object:
hitObject = object
#play ball bounce sound
viz.playsound('bounce.wav')
break
#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)
bullet.translate(futurePos.get())
#rotate the bullet along it's rotation vector
#bullet.rotate(bullet.rotvector[0],bullet.rotvector[1],ball.rotvector[2],90*elapsed,viz.RELATIVE_WORLD)
#Update the bullet's shadow
bullet.shadow.translate(futurePos.x,0,futurePos.z)
def mytimer(num):
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)
#Update the crosshair position
crosshair.translate(viz.mousepos()+[0])
#
# elif num == START_DUCK:
# global nextDuck
# #Get the next available duck and start it
# duck = ducks[nextDuck]
# beginDuck(duck)
# nextDuck = (nextDuck + 1) % NUM_DUCKS
# viz.starttimer(START_DUCK,TIME_BETWEEN_DUCKS)
#
#Shoot a ball whenever left mousebutton is clicked
vizact.onmousedown(viz.MOUSEBUTTON_LEFT,shootBullet)
#Create callbacks for timer events
viz.callback(viz.TIMER_EVENT,mytimer)
##Start a timer which starts the next available duck
#viz.starttimer(START_DUCK,0.01)
#Start the animation timer, which animates the ball and checks for collisions
viz.starttimer(ANIMATION,0.01,-1)
#Move the head position back
viz.translate(viz.HEAD_POS,0,0,-10)
#Disable mouse navigation
viz.mouse(viz.OFF)
|
|
#2
|
|||
|
|||
|
Hi,
I've attached a modified version of the script which I hope will point out why you are experiencing this problem. First of all, I removed the crosshair because you shouldn't be using objects attached to the screen when using stereo. Second, I set the ipd value to 0. The ipd is the eye distance value. So both eyes will be at the same location. Third, I multiplied the x value of the mouse position by 2.0 when using the screentoworld command. This should cause the the bullet to come directly from the mouse position, for the left half of the screen. If you set the IPD value back to normal, you will experience your problem again. This is because in stereo mode the eyes are offset from the actual viewpoint position. I've attached an image which shows why the bullet appears to go to the left (excuse my crappy drawing skills ). Do you plan on the user using the mouse to aim while wearing the HMD?Code:
import viz
import vizmat
import math
viz.go(viz.STEREO)
#arrays
avatars = [] #for avatars
collidables = [] #for collidable objects
bullets = [] #for number of balls
#constants
NUM_BULLETS = 3 #number of balls in the array
nextBullet = 0 #index for the next ball in the array
BULLET_SPEED = 250 #speed in meters/secs of the bullet
ANIMATION = 1 #animation ID
NUM_AVATARS = 5 #the number of avatars
court = viz.add('terrain1.wrl')
court.scale(0.5,0.5,0.5)
court.rotate(0,1,0,-90)
court.translate(-5,0,-10)
court.appearance(viz.MODULATE)
court.disable(viz.LIGHT0)
#Set eye distance to 0 to show why the bullet goes to the left of the mouse
viz.ipd(0)
#Create six avatars
def startAvatar(location):
global court
for i in range(NUM_AVATARS):
newX = -math.cos(-2*i+15) * 2
newZ = math.sin(i^2+1) * 2
male = viz.add('male.cfg')
male.translate(newX,0,newZ)
male.rotate(180,0,0)
avatars.append(male) #Save avatar in list
startAvatar(court)
for x in range(0,NUM_BULLETS):
#create a bullet that is initially hidden
bullet = viz.add('ball.wrl')
bullet.scale(.1,.1,.1)
bullet.visible(viz.OFF)
#add a shadow, To be removed once final program is completed
bullet.shadow = viz.add('shadow.wrl')
bullet.shadow.alpha(0.7)
bullet.shadow.visible(viz.OFF)
#Enable collisions with the ball based on a sphere shape
bullet.collidesphere(0.25)
bullet.isTarget = 0
collidables.append(bullet)
#keep track of the last object the ball hit
bullet.lastHit = 0
#add the ball to the ball list
bullets.append(bullet)
bullet.active = 0
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]*2.0,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 and it's shadow visible
bullet.visible(viz.ON)
bullet.shadow.visible(viz.ON)
#mark the bullet as active
bullet.active = 1
def MoveBullet(bullet,elapsed):
hitObject = 0
#check if bullet is colliding with an object
for object in collidables:
#perform the collision check with the object
info = bullet.collidingwith(object,1)
if info.intersected:
#set the bullets new vector to the reflection vector
bullet.vector = viz.Vector(vizmat.ReflectionVector(bullet.vector,info.normalVector))
#create a vector of the normal of the collision
normal = viz.Vector(info.normalVector)
#Check dot product of velocity and normal
if bullet.vector * normal <0:
bullet.vector*= -1
#if object.isTarget and ball.lastHit != object:
hitObject = object
#play ball bounce sound
viz.playsound('bounce.wav')
break
#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)
bullet.translate(futurePos.get())
#Update the bullet's shadow
bullet.shadow.translate(futurePos.x,0,futurePos.z)
def mytimer(num):
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)
#Shoot a ball whenever left mousebutton is clicked
vizact.onmousedown(viz.MOUSEBUTTON_LEFT,shootBullet)
#Create callbacks for timer events
viz.callback(viz.TIMER_EVENT,mytimer)
##Start a timer which starts the next available duck
#viz.starttimer(START_DUCK,0.01)
#Start the animation timer, which animates the ball and checks for collisions
viz.starttimer(ANIMATION,0.01,-1)
#Move the head position back
viz.translate(viz.HEAD_POS,0,0,-10)
#Disable mouse navigation
viz.mouse(viz.OFF)
|
|
#3
|
|||
|
|||
|
For now we plan to use the mouse, however, when I tried this code, it didn't work for me. When I "shot" the avatars, nothing happened to them. So, now, after looking at this code, are you still sure that there is no way to adjust for the accuracy of the bullet when shooting to the sides? Thanks,
|
|
#4
|
|||
|
|||
|
Hi,
The code I posted was made with the latest internal version of Vizard. I realized that it won't work with the version you have. You just need to change the screentoworld command to the following: Code:
bulletvector = viz.screentoworld(pos[0]+0.25,pos[1]) |
|
#5
|
|||
|
|||
|
What do you mean by useless? I tried using the code w/the HMD and the bullet came exactly from the mouse position. Is there a way to make them perform an action when they are hit by a bullet? I wouldn't mind keeping the IPD at zero as long as the avatars would fall when they got hit.
|
|
#6
|
|||
|
|||
|
The whole point of wearing an HMD is that each eye gets a different view of the scene. This is what make the image look 3D. Setting IPD to zero will effectively disable stereo since both eyes will be receiving the same view of the scene.
Here is some sample code that will play the hit animation when the avatar is hit by a bullet. Replace the code with whatever action you need: Code:
import viz
import vizmat
import math
viz.go(viz.STEREO)
#arrays
avatars = [] #for avatars
bullets = [] #for number of balls
#constants
NUM_BULLETS = 3 #number of balls in the array
nextBullet = 0 #index for the next ball in the array
BULLET_SPEED = 250 #speed in meters/secs of the bullet
ANIMATION = 1 #animation ID
NUM_AVATARS = 5 #the number of avatars
court = viz.add('terrain1.wrl')
court.scale(0.5,0.5,0.5)
court.rotate(0,1,0,-90)
court.translate(-5,0,-10)
court.appearance(viz.MODULATE)
court.disable(viz.LIGHT0)
#Set eye distance to 0 to show why the bullet goes to the left of the mouse
viz.ipd(0)
#Create six avatars
def startAvatar(location):
global court
for i in range(NUM_AVATARS):
newX = -math.cos(-2*i+15) * 2
newZ = math.sin(i^2+1) * 2
male = viz.add('male.cfg')
male.translate(newX,0,newZ)
male.rotate(180,0,0)
avatars.append(male) #Save avatar in list
startAvatar(court)
for x in range(0,NUM_BULLETS):
#create a bullet that is initially hidden
bullet = viz.add('ball.wrl')
bullet.scale(.1,.1,.1)
bullet.visible(viz.OFF)
bullet.disable(viz.COLLISION)
bullet.active = 0
#add the ball to the ball list
bullets.append(bullet)
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:
info.object.add(vizact.animation(7))
bullet.visible(0)
bullet.active = 0
#Update balls positions
bullet.translate(futurePos.get())
def mytimer(num):
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)
#Shoot a ball whenever left mousebutton is clicked
vizact.onmousedown(viz.MOUSEBUTTON_LEFT,shootBullet)
#Create callbacks for timer events
viz.callback(viz.TIMER_EVENT,mytimer)
#Start the animation timer, which animates the ball and checks for collisions
viz.starttimer(ANIMATION,0.01,-1)
#Move the head position back
viz.translate(viz.HEAD_POS,0,0,-10)
#Disable mouse navigation
viz.mouse(viz.OFF)
|
|
#7
|
|||
|
|||
|
Thank you very much!
|
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|