PDA

View Full Version : objects move when quat values are scripted


PFS
04-21-2003, 01:43 PM
Hey everyone,

Long time listener, first time caller. :buttrock:

Got a question about rotation. I'm writing a script right now that will automate missile animation...should be trés cool when it's done, and when it's done I'll be sure to post it for your all of your use. But right now, I've hit a bit of a roadblock.

Whenever I try to animate rotation of the missile object (using quat values), position is affected as well. The positional changes produce the effect of rotating the object around the world origin, rather than around the object axis (as usual). Very strange behaviour indeed.

I've been at it for hours now and simply can't figure it out. Does anyone out there have any ideas? Cheers in advance my friends.
:beer:

LFShade
04-21-2003, 04:18 PM
Have you tried wrapping the rotation assignment(s) in a coordsys local context? It would also help to know how you're deriving the rotation values you're trying to assign. Can you give a specific example of what sort of rotation you're trying to achieve? Maybe a snippet of code would help us troubleshoot for you.

-RH

PFS
04-21-2003, 05:26 PM
Yeah, I've tried the local context, but then quad rotation values for all objects are just [0, 0, 0, 1], so nothing happens.

Here's what I'm trying to do. (It will be more sophisitcated when I've got the basics working.) On each frame, I turn the object a little toward it's target using the slerp method, and then I move the object a constant amount along its local Z axis.

The local movement is no problem. I disabled the rotation part to check that, and it's fine.

This is the code that's causing the trouble:
ang = slerp cur goal .07
at time count missile.rotation = ang

"cur" = current missile rotation, "goal" = orientation that points at target.

It seems that if an object's rotation value is assigned to a quat, not only will the object be rotated around its pivot, but object's position will change as well, to reflect a rotation of the same value around the world origin. I've done extremely simple testing just using the listener and this always seems to be the case, so I'm certain it is something to do with the nature of quats and not how I'm using them.

To see what I mean, create an object somewhere other than the origin, and set its rotation to an arbitrary quat in the listener. Ex:
$c.rotation = quat 0.343 0.342 0.424 1

What I *have* noticed is that the "rotate" method will turn the object in place, as expected. However, in this case, you need to know how much to rotate by, not what you want the final rotation to be- which is what slerp gives you. And I can't figure out how to find the quat to rotate by to achieve a rotation from an initial orientation to a desired end orientation.

Hopefully this lot helps...thanks LFShade, and everyone else too. :) :buttrock:

LFShade
04-21-2003, 06:31 PM
Right about now I wish I had Max in front of me to try some stuff out:(

As a general rule, rotations should be performed prior to translations, so you might just want to store obj.pos into a temp variable, do the rotation, set obj.pos=temp and then do the local z translation. Maybe that will give you the result you're after.

Also, after thinking about this, there may be another way to get the effect you're looking for. I don't remember the exact process, but I once worked out a way to do a pseudo-lookat-controller via script or expression. This could be applied to the missile object with a time offset, which would come pretty close to the same effect as slerp-ing to the goal. Applying Z translation would still be a trivial matter. Let me do a proof-of-concept on this tonight and we can compare notes:)

-RH

PFS
04-21-2003, 07:43 PM
LFShade,

I tried storing the position before, and it didn't work...forgot to mention that in my second post...

*However*, I just tried it again, and it turns out I made a mistake the first time. It's now almost working...but, with so many mnaipulations, the "at time" contexts are getting really messy, and right now the missile object rotates in place without moving along its Z axis. I'm certain that's just a bug though.

I'll look more into it...it's going to be extraordinarily messy to do the more advance scripting (acceleration, gravity, etc) if this is how the basic operation is carried out. At this point, I'd love to find a way to calculate the intermediary quat so the "rotate" method can be used.

If you could check out that idea you were mentioned that would be awesome....thank you! If you like, I'll notate the script so it's readable and send it your way so you can see what I've got so far.

Right now I really should be studying though...this script was supposed to be simple study break and it's turned into a consuming distraction!

Cheers, :beer:

PFS

LFShade
04-22-2003, 07:46 PM
I played around with my idea last night, and I think it could work. I just need to get a lock on the best way to animate the locomotion (z-translation) of the missile so that it believably follows (or rather, appears to drive) the rotations.

Ulitimately, though, I think a method that would use slerp() or some other mathematics to find an offset with which to use the rotate() function will be the most reliable and versatile solution. I'll do some more thinking on that in the near future.

-RH

PFS
04-24-2003, 12:08 AM
Cool...I got slerp working as well, by copying the position into a temp variable, as you suggested. Worked perfectly, except that I've now figured out that, for my purposes, slerp is pretty useless. I want to turn the missile so that it turns most directly towards its target, regardless of its local z rotation. But, slerp takes that into account, and interpolates between z rotations as well, and it farks things up.

It's easy to see visually...execute this lot to this to see what I mean...

----------
cylinder name:"pos1" radius:1.5 height:30
$pos1.transform = (matrix3 [-0.707107,0.707107,0] [-0.707107,-0.707107,0] [0,0,1] [0,0,0])
cylinder name:"pos2" radius:1.5 height:30
$pos2.transform = (matrix3 [0.707107,0,-0.707107] [0,1,0] [0.707107,0,0.707107] [0,0,0])
cylinder name:"pointer" radius:1 height:50

animate on
(
for a = 0 to 100 do
(
at time a $pointer.rotation = slerp $pos1.rotation $pos2.rotation ((float)a/100)
)
)
---------

Should be a nice simple sweep between the two posts, right? But, the pointer swings way out to the side. When the missile object is travelling fast, that sweep forms a giant corkscrew motion and looks reeeeeally dumb.

However, I've since discovered a better implementation and got it working fully, along the lines that you suggested of finding an offset. I do a few cross products and construct a matrix3 to use as the coordSys, such that the x axis is perpendicular to the plane defined by the missile z axis and the mis-targ direction vector. Thus, rotating the missile around the matrix3's x axis will rotate the missile toward the object in the most direct manner possible, without worrying about local z rotation.

My last exam is tomorrow...after that I'm going to go party for a few days, and then I'm going to clean up the script and get thing thing working nicely. LFShade, I will send you a copy so you can see what I've done...it's all I can in return for your help on this one. Thanks very much my friend! :beer:

CGTalk Moderation
01-14-2006, 10:00 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.