Object Target Expression in Python
Tudor last edited by r_gigante
I try to build the Object Target Expression in Python.
So far I have this and it works but with a little issue.
I have a flipping problem and I don't know how to build the up-vector in, so that it works perfectly.
import c4d cam = op.GetObject() target = op[c4d.ID_USERDATA,1] def main(): cObj = cam.GetMg().off tObj = target.GetMg().off upV = c4d.Vector(0, 1, 0) m = c4d.Matrix() m.off = cObj m.v1 = (tObj-cObj).Cross(cObj-upV).GetNormalized() m.v3 = (tObj-cObj).GetNormalized() m.v2 = (tObj-cObj).Cross(m.v1).GetNormalized() cam.SetMg(m)
looking at your code I think there's a wrong assumption about the up-vector and how consequently it is used in the definition of the transformation matrix.
The correct approach should look like:
import c4d cam = op.GetObject() target = cam[c4d.ID_USERDATA, 1] def main(): # get "from" and "to vectors fromVec = cam.GetMg().off toVec = target.GetMg().off # use a temporary Up-vector tmpVec = c4d.Vector(0, 1, 0) # calculate the forward-vector fVec = (toVec - fromVec).GetNormalized() # calculate the right-vector rVec = tmpVec.Cross(fVec) # recalculate the proper up-vector uVec = fVec.Cross(rVec) # fill-up the transformation matrix m = c4d.Matrix() m.off = fromVec m.v1 = rVec m.v2 = uVec m.v3 = fVec # set the camera transformation cam.SetMg(m)
Last but not least, please set tags accordingly to your topic and use the Q&A functionality.
thank you for your help.
After I put GetNormalized() in your line rVec and uVec it works.
But now I get a flipping problem if the cam-Obj is direct over (or under) the target-Obj.
The same happened by the Target-Tag. The Target-Tag has a option to stabilize the system with an up-Vector.
Could I calculate this up-Vector to my matrix to stabilize it too? Or maybe there is a other approach?
Hi Tudor, thanks for following up.
The issue you notice takes place when the temporary up-vector is aligned with the forward-vector: under this scenario the rVec is ambiguous and the whole system results unstable. The solution to the issue is represented by Quaternions or, alternatively you can try to mitigate the effect by putting in place some "work-around" like:
... uVec = fVec.Cross(rVec).GetNormalized() # try to mitigate Gimbal-lock if (fVec + tmpVec).z < 0: uVec.x = -uVec.x if abs(rVec.x - 1.0) < 0.001: rVec.x = -rVec.x # fill-up the transformation matrix ...
I really do not understand it yet but it works.
There are some strange camera behaviors in the viewport but the system still stable.
I have tried also the Quaternions-solution, but I don't know really now the syntax work.
Do you have an idea?
Hi Tudor, with regard to using quaternions, I suggest to search around the web for it: there are hundreds of sites talking extensively about.
I warmly suggest to have a look here where Gimbal lock is presented and some notes are spent on how to avoid it.
Does anyone have a suggestion how to work with Quaternions in my case to avoid the gimbal lock? I realy dont find any examples or approaches to this. Other APIs have different methods for this like SetFromToRotation, SetLookRotation, lookAt ....
Maybe its possible to extend the Python Library with other classes? Don‘t have any idea and not very advanced in this.
unfortunately we can't help developing algorithms. So, what has been said here and in the Quaternion Rotation thread, is probably all we can contribute from MAXON's side.
Maybe somebody from our community is willing to step into this and help out?