#1
|
|||
|
|||
viewpoint movement
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) ------- |
#2
|
|||
|
|||
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. Code:
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) |
#3
|
|||
|
|||
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? |
#4
|
|||
|
|||
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.57735 Code:
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 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) |
#5
|
|||
|
|||
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. |
|
|