ninth
June 19, 2010, 8:50pm
1
from direct.directbase import DirectStart
from pandac.PandaModules import *
base.disableMouse()
base.cam.setPos(0,-30,0)
base.cam.lookAt(0,0,0)
normaly = [loader.loadModel("smiley") for i in xrange(5)]
for m in normaly:
m.reparentTo(render)
strange = loader.loadModel("frowney")
strange.reparentTo(render)
normaly[0].setPos(-3,0,3)
strange.setPos(-3,0,0)
normaly[1].setPos(-3,0,-3)
normaly[2].setPos(3,0,3)
normaly[3].setPos(3,0,0)
normaly[4].setPos(3,0,-3)
def myTask(task):
q = Quat()
q.setHpr(normaly[0].getHpr()+Vec3(1,0,0))
normaly[0].setQuat(q)
q = Quat()
q.setHpr(strange.getHpr()+Vec3(0,1,0)) #<< HERE
strange.setQuat(q)
q = Quat()
q.setHpr(normaly[1].getHpr()+Vec3(0,0,1))
normaly[1].setQuat(q)
normaly[2].setHpr(normaly[2].getHpr()+Vec3(1,0,0))
normaly[3].setHpr(normaly[3].getHpr()+Vec3(0,1,0))
normaly[4].setHpr(normaly[4].getHpr()+Vec3(0,0,1))
return task.cont
taskMgr.add(myTask,"tsk")
run()
why it does not rotate?
Panda 1.7.0, Win 7 x64
Craig
June 19, 2010, 9:33pm
2
Interesting.
I suspect it has to do with pitches beyond +/- 90 degrees being kinda strange. If you go past pointing straight down, the same rotation can be expressed as -90 pitch, 180 H and 180 roll (I think). Which representation panda chooses is arbitrary, but choosing the one with a abs§ less than 90 makes sense. Thus, adding to pitch moves it back toward straight down! Nothing is wrong, and the quats do everything properly. Hpr is simply not 1:1. There are infinite HPR that produce the same orientation, and if you go through a quat and back, you can end up having sudden changes in the HPR values from this.
Anyway, this does work: strange.setP(strange.getP()+1)
I’d just stay away from Hpr if you are going to have high pitch values.
ninth
June 20, 2010, 9:39am
3
Well, ok, I wrote two procedures to obtain the custom quaternion from H and from P, and… see…
from direct.directbase import DirectStart
from pandac.PandaModules import *
import math
base.disableMouse()
base.cam.setPos(0,-30,0)
base.cam.lookAt(0,0,0)
normaly,normaly2 = loader.loadModel("smiley"),loader.loadModel("smiley")
normaly.reparentTo(render)
normaly2.reparentTo(render)
strange = loader.loadModel("frowney")
strange.reparentTo(render)
normaly.setPos(0,0,2)
strange.setPos(0,0,0)
normaly2.setPos(0,0,-2)
def customQuatFromH(h):
h = h*0.5
h = (math.pi/180)*h
sin_h = math.sin(h)
q = Quat()
q.setR(math.cos(h))
q.setI(0*sin_h) #=0
q.setJ(0*sin_h) #=0
q.setK(1*sin_h)
return q
def customQuatFromP(p):
p = p*0.5
p = (math.pi/180)*p
sin_p = math.sin(p)
q = Quat()
q.setR(math.cos(p))
q.setI(1*sin_p)
q.setJ(0*sin_p) #=0
q.setK(0*sin_p) #=0
return q
def myTask(task):
normaly.setQuat(customQuatFromH(normaly.getH()+1)) #<< here it work
strange.setQuat(customQuatFromP(strange.getP()+1)) #<< and here not work
normaly2.setQuat(normaly2,customQuatFromP(1)) #<< here work again
return task.cont
taskMgr.add(myTask,"tsk")
run()
Craig
June 20, 2010, 4:07pm
4
If you really must use quats and Hpr together, do it like this:
q = strange.getQuat()
q2 = Quat()
q2.setHpr(Vec3(0,1,0))
strange.setQuat(q.multiply(q2))
This way the orientation on your object stats a quat the whole time.
Note that the above does happen to have the same effect as this:
strange.setHpr(strange,0,1,0)
ninth
June 20, 2010, 7:06pm
5
Yes, it’s work! Thanks!
I use quaternions to interpolate the data obtained from the network. And I can get the angular velocity only as the Vec3