PDA

View Full Version : viewpoint movement


spacefarer
12-01-2004, 10:59 AM
Hi!

I would like to move my view point smoothly 1m per pressing an button and to rotate it 90 degrees if I press another button, and wrote a program shown as below.

But there are two major problems.
1. The viewpoint does'nt rotate exactly 90 degrees (like 89.999925...). I want it to rotate just 90 degrees evey time.
2. If you press the button during the view point is changing, the view point moves 1m or rotates 90 degrees from the moment.
I want the [x,y,z] of the view point to be always integer when the view point stops.

I would appreciate your suggestions.
Thank you.

------
def mykeyboard(key):
pos = viz.get(viz.HEAD_POS)
tx = pos[0]
ty = pos[1]
tz = pos[2]
trans = viz.get(viz.BODY_LOOK)
# Translate_Forward
if viz.iskeydown(viz.KEY_UP):
tx = tx + trans[0]
ty = ty + trans[1]
tz = tz + trans[2]
view.goto(tx,ty,tz,1,viz.TIME)
# Yaw_Right
elif viz.iskeydown('6'):
viz.starttimer(1, 0.01,89)

def mytimer(num):
if num == 2: #Yaw-Right
view.rotate(0,1,0,1,viz.BODY_ORI,viz.RELATIVE_LOCA L)
-------

farshizzo
12-01-2004, 12:35 PM
Hi,

I wrote the following sample script that should fix your problems. I use the viewpoints built-in animation engines to translate and rotate. When they are finished I translate/rotate them to the final value just to be sure they are exact. Also, when I calculate where to move/turn, I round the values to integers. Also, I check if the viewpoint is currently being animated when a key is pressed.import viz
viz.go()

#Add a ground
viz.add('tut_ground.wrl')

#Get main viewpoint object
view = viz.get(viz.MAIN_VIEWPOINT)

#Create a variable that will tell whether viewpoing is currently moving/turning
view.animating = 0

#Variable that holds current destination value
final = [0,0,0,0]

def onkeydown(key):
if key == viz.KEY_UP:
#Make sure view is not animating
if not view.animating:
pos = view.get(viz.HEAD_POS)
trans = view.get(viz.BODY_LOOK)
#Round values to nearest integer
final[0] = int(round(pos[0] + trans[0]))
final[1] = int(round(pos[1] + trans[1]))
final[2] = int(round(pos[2] + trans[2]))
#Start animating viewpoint
view.goto(final,1,viz.TIME)
view.animating = 1
elif key == '6':
#Make sure view is not animating
if not view.animating:
#Compute rotation of turning body 90 degrees to right
xform = viz.Transform(view.get(viz.BODY_MAT))
xform.postRot(0,1,0,90)
rot = xform.getRot()
#Round values to nearest integer
final[0] = int(round(rot[0]))
final[1] = int(round(rot[1]))
final[2] = int(round(rot[2]))
final[3] = int(round(rot[3]))
#Start animating viewpoint
view.spinmask(viz.BODY_ORI) #Spin the body orientation
view.spinto(final,45) #Spin with speed of 45 deg/sec
view.animating = 1

viz.callback(viz.KEYDOWN_EVENT,onkeydown)

def onstop(object, type):
if type == viz.MOVE:
#Viewpoint is done moving, translate it to the final value just to be sure
view.translate(final)
view.animating = 0
elif type == viz.SPIN:
#Viewpoint is done spinning, rotate it to the final value just to be sure
view.rotate(final,viz.BODY_ORI)
view.animating = 0

view.callback(viz.STOP_EVENT,onstop)

spacefarer
12-01-2004, 05:24 PM
Thank you very much.
It worked!
But I have a new problem.
I actually want 6DOF viewpoint movement.
When I applied the yaw rotation program to pitch and roll, the visual scene is sometimes distorted because I think my matrix is simply wrong.
Could you also tell me pitch and roll cases?

farshizzo
12-01-2004, 08:29 PM
Hi,

Once you begin to introduce pitch and roll, you cannot use integers to represent the Axis-Angle rotation. I've modified the script so that it doesn't round the rotation values. I also changed the rotation code so that it performs a pre-rotation instead of a post-rotation. This makes each rotation relative to the current reference frame.

If you still need the extra precision you could round the angle value of the rotation to an integer. You could also round the axis values of the rotation, but you need to make sure that you don't round the value when it is close to ±0.57735import viz
viz.go()

#Add a ground
viz.add('tut_ground.wrl')

#Get main viewpoint object
view = viz.get(viz.MAIN_VIEWPOINT)

#Create a variable that will tell whether viewpoing is currently moving/turning
view.animating = 0

#Variable that holds current destination value
final = [0,0,0,0]

def rotateview(x,y,z,angle):
#Make sure view is not animating
if not view.animating:
#Compute rotation of turning body 90 degrees to right
xform = viz.Transform(view.get(viz.BODY_MAT))
xform.preRot(x,y,z,angle)
final[:] = xform.getRot()[:]
#Start animating viewpoint
view.spinmask(viz.BODY_ORI) #Spin the body orientation
view.spinto(final,2,viz.TIME) #Spin for 2 seconds
view.animating = 1

def onkeydown(key):
if key == viz.KEY_UP:
#Make sure view is not animating
if not view.animating:
pos = view.get(viz.HEAD_POS)
trans = view.get(viz.BODY_LOOK)
#Round values to nearest integer
final[0] = int(round(pos[0] + trans[0]))
final[1] = int(round(pos[1] + trans[1]))
final[2] = int(round(pos[2] + trans[2]))
#Start animating viewpoint
view.goto(final,1,viz.TIME)
view.animating = 1
elif key == '6': #yaw right
rotateview(0,1,0,90)
elif key == '4': #yaw left
rotateview(0,1,0,-90)
elif key == '8': #pitch up
rotateview(1,0,0,-90)
elif key == '2': #pitch down
rotateview(1,0,0,90)
elif key == '9': #roll right
rotateview(0,0,1,-90)
elif key == '7': #roll left
rotateview(0,0,1,90)

viz.callback(viz.KEYDOWN_EVENT,onkeydown)

def onstop(object, type):
if type == viz.MOVE:
#Viewpoint is done moving, translate it to the final value just to be sure
view.translate(final)
view.animating = 0
elif type == viz.SPIN:
#Viewpoint is done spinning, rotate it to the final value just to be sure
view.rotate(final,viz.BODY_ORI)
view.animating = 0

view.callback(viz.STOP_EVENT,onstop)

spacefarer
12-02-2004, 07:23 AM
Thank you so much again.
I've tried your modified program and each axis is up to only 10^-7 order off from the exact value. So I think I just round the values when I record the axes data.