PDA

View Full Version : Resetting Transform results in different transform?


thatoneguy
11-11-2010, 10:40 PM
So I've got a problem.

I create a teapot like such with some animation:
tim = teapot()
with animate on
(
at time 0
(
rotate tim (eulerangles -75 0 0)
rotate tim (eulerangles 0 90 0)
tim.position = point3 10 20 30
)
at time 2
(
tim.rotation = (quat 0 0 0 1)
tim.position = point3 0 0 0
)
)

And then I need to zero it out for export on frame 0 and then put it back how I found it. Problem is it doesn't go back to the way I found it. It's a little bit off.

slidertime = 0
bob = tim.transform
tim.transform = matrix3 [1,0,0] [0,1,0] [0,0,1] [0,0,0]
tim.transform = bob
slidertime = 3

Is this a max bug or is there a correct way to zero an object and return it unmolested?

Bobo
11-11-2010, 11:47 PM
This is not exactly a bug, but the way Euler rotations work and the reason Quaternions were in the base of both 3D Studio and Max.

In short, when you modify the transformations on frame 0 when assigning the identity matrix for export, all keys on the following frames have to be recalculated to also perform the same reorientation since Animation is off. So now you have completely new Euler values for all X, Y and Z keys. When you assign the original matrix after export on frame 0, all following keys have to be modified again, and the way Euler values are transformed when specifying absolute quaternion orientations (what the matrix dictates here) can lead to new unexpected values. That's where things get messed up.

A simple solution is to change the rotation controller of tim to a Quaternion one (TCB_Rotation) right after creation:

tim.rotation.controller = tcb_rotation()

After this, the script works as expected. I remember doing this when importing Euler data from Maya and XSI as it would totally avoid gimbal problems and axis flipping.

An alternative method would be to assign a Layer or List controller to the objects, set the new transforms in a second track while suppressing the original animation, then remove or switch back to the original animation without touching the keys.

thatoneguy
11-12-2010, 12:30 AM
An alternative method would be to assign a Layer or List controller to the objects, set the new transforms in a second track while suppressing the original animation, then remove or switch back to the original animation without touching the keys.

Thanks. I'll have to try this approach. It's for an exporter so I can't control what controllers it was animated in. I considered just copying the object applying the transformation, deleting it and exporting but that could cause trouble with heavy meshes going slow.

thatoneguy
11-12-2010, 12:38 AM
This seems to work. Do you forsee any new problems I would introduce by just doing this?

slidertime = 0
bobpos = copy tim.pos.controller
bobrot = copy tim.rotation.controller
bobscale = copy tim.scale.controller
tim.transform = matrix3 [1,0,0] [0,1,0] [0,0,1] [0,0,0]
tim.pos.controller = bobpos
tim.rotation.controller = bobrot
tim.scale.controller = bobscale
slidertime = 3

denisT
11-12-2010, 12:57 AM
So I've got a problem. ..

...It's a little bit off.

slidertime = 0
bob = tim.transform
tim.transform = matrix3 [1,0,0] [0,1,0] [0,0,1] [0,0,0]
tim.transform = bob
slidertime = 3

Is this a max bug or is there a correct way to zero an object and return it unmolested?

that's not a bug. when you apply new transform at frame 0 you create a new keys for transform controllers. do it with animate off and it should stay as it was.

Bobo
11-12-2010, 01:03 AM
This seems to work. Do you forsee any new problems I would introduce by just doing this?

slidertime = 0
bobpos = copy tim.pos.controller
bobrot = copy tim.rotation.controller
bobscale = copy tim.scale.controller
tim.transform = matrix3 [1,0,0] [0,1,0] [0,0,1] [0,0,0]
tim.pos.controller = bobpos
tim.rotation.controller = bobrot
tim.scale.controller = bobscale
slidertime = 3

I don't see a problem with this, especially if you tested it and it worked ;)

thatoneguy
11-12-2010, 01:19 AM
I don't see a problem with this, especially if you tested it and it worked ;)

Haha, well as far as I could tell the old system had been working perfectly for over a year without me or anyone else noticing a problem. :D

denisT
11-12-2010, 01:38 AM
Haha, well as far as I could tell the old system had been working perfectly for over a year without me or anyone else noticing a problem. :D

there is no problem. max works as expected. you created one set of euler keys at frame 0 and applied the another set later. you expect to get the same result, don't you?

Bobo
11-12-2010, 01:46 AM
there is no problem. max works as expected. you created one set of euler keys at frame 0 and applied the another set later. you expect to get the same result, don't you?

No, that is as expected. What is not totally expected is that if you disable animate context, modify the values on frame 0 back to identity (which automatically adjust all keys after that to new values to keep the relative rotations intact), then restore the original orientation of frame 0, the values restored in the following keys don't match the original values. This only happens with Euler rotations (Rotation_XYZ) and not with Quaternion-based TCB controllers.

Ruramuq
11-12-2010, 02:12 AM
Not convinced, its not like blaming eulers..
The problem is because you're relying on matrices and quats, which are good for math, but this is a controllers/max issue

You should access float controllers directly. thats the most realiable way, otherwise max internally will be converting values all the time, its just a bad idea in many situations as you don't know exactly what is happening inside; mathematically makes sense, but you may loose the original animation values entered by the user by obviously differences between euler quaternions.

denisT
11-12-2010, 04:32 AM
that's not a bug. when you apply new transform at frame 0 you create a new keys for transform controllers. do it with animate off and it should stay as it was.

OK. it's my bad. i didn't have MAX on my hands, so i couldn't double-check my supposition.
the applying of a transform on 0 keyframe screws the eulers up.

as an excuse I give you my solution that has to reset any type of node's initial transform:

-- initialize
delete objects
tim = teapot()
with animate on
(
at time 0
(
rotate tim (eulerangles -75 0 0)
rotate tim (eulerangles 0 90 0)
tim.position = point3 10 20 30
)
at time 2
(
tim.rotation = (quat 0 0 0 1)
tim.position = point3 0 0 0
)
)
-- reset
with animate off
(
tm = tim.track
tim.track = (execute "prs")()
slidertime = 0
tim.transform = matrix3 1
tim.track = tm
slidertime = 3
)


PS. don't trust your memory; double-check with MXS help! (or Bobo ;))

Ruramuq
11-12-2010, 05:09 AM
Looks like tim.track = (execute "prs")() is the same as tim.track = prs()
max detects that the same controller is applied, and will do nothing.

to create a new track I do this : copy (prs())
and no need to use tim.transform=matrix3 1

denisT
11-12-2010, 05:46 AM
Looks like tim.track = (execute "prs")() is the same as tim.track = prs()
max detects that the same controller is applied, and will do nothing.

to create a new track I do this : copy (prs())
and no need to use tim.transform=matrix3 1
yes. it works your way too.

denisT
11-12-2010, 06:15 AM
...
to create a new track I do this : copy (prs())
and no need to use tim.transform=matrix3 1

the line tim.transform = matrix3 1 doesn't mean that the node has to be exported with identity matrix transform. It means that it might be ANY.

CGTalk Moderation
11-12-2010, 06:15 AM
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.