Announcements

Between mid-October and November, the content on AREA will be relocated to the Autodesk Community M&E Hub and the Autodesk Community Gallery. Learn more HERE.

Setting an INode's transformation, consistent with animation

Setting an INode's transformation, consistent with animation

contact
Contributor Contributor
1,250 Views
8 Replies
Message 1 of 9

Setting an INode's transformation, consistent with animation

contact
Contributor
Contributor

Hello!

 

I'm having trouble setting an INode's transformation in a way that is consistent with keys are set in the user interface (time line buttons etc).

Simply put: the plug-in sets the transformation (position and rotation) of an object,

and the user can create keys in the timeline (with the "set key" button or with "auto key" and playback.

 

First I tried

inode->SetNodeTM(t, mat); // mat being a Matrix3

This works if there are no keys on the object yet,

but if there are prior keys, then the transformation becomes corrupted / broken.

 

So I switched to

Control* c = inode->GetTMController();
SetXFormPacket pkg(mat); // mat being a Matrix3
c->SetValue(t, &pkg, 0, CTRL_ABSOLUTE);

Which works when no keys are on the timeline and doesn't result in corrupted transformations, but:

- when using "auto key" with playback, only rotational keys are recorded

- when a positional key is already in the timeline, then the position is ignored, only rotation is applied

 

So next I tried:

c->GetRotationController()->SetValue(t, &pkg, 0, CTRL_ABSOLUTE);
c->GetPositionController()->SetValue(t, &pkg, 0, CTRL_ABSOLUTE);

But now, depending on which order the two are called, position or rotation will be ignored.

 

If I use setValue() with parameter commit=1, then I'm back to the original problem of having a broken transformation.

 

I'd be happy if someone could let me know which is the correct way to set a transformation.

Thank you!

0 Likes
1,251 Views
8 Replies
Replies (8)
Message 2 of 9

istan
Advisor
Advisor

..and what do you see in the track view?

..and what values you get back, if you read back all keys of each controller?

0 Likes
Message 3 of 9

denisT.MaxDoctor
Advisor
Advisor

@contact wrote:

Hello!

 

I'm having trouble setting an INode's transformation in a way that is consistent with keys are set in the user interface (time line buttons etc).

Simply put: the plug-in sets the transformation (position and rotation) of an object,

and the user can create keys in the timeline (with the "set key" button or with "auto key" and playback.

 


Unlike MXS or UI modes, "Set Key" and "Auto Key" for SDK methods are only "request". You have to specify the animation mode youself using methods:

 

CoreExport int Animating();    // is the animate switch on??
CoreExport void AnimateOn();  // turn animate on
CoreExport void AnimateOff();  // turn animate off
CoreExport void SuspendAnimate(); // suspend animation (uses stack)
CoreExport void ResumeAnimate();   // resume animation ( " )

 

there are a lof examples of the using in the SDK .. just search these methods

 

 

if you use Animate mode both ways (SetNodeTM and SetValue (for controllers) ) must work. 


Another way you can create a key at specified time and set its value. In this case you don't need to specify the Animate mode.

 

0 Likes
Message 4 of 9

contact
Contributor
Contributor

@istan  Thank you for your reply!

 


@istan wrote:

..and what do you see in the track view?


I see rotational keys but no positional keys.

 


@istan wrote:

..and what values you get back, if you read back all keys of each controller?


If I call NumKeys() on the inode or the inode's control directly, it returns -1.
If I call NumKeys() on the inode's GetPositionController(), it returns 0;

0 Likes
Message 5 of 9

contact
Contributor
Contributor

@denisT.MaxDoctorThank you for your reply!

 

Sorry, but I think we have a misunderstanding.
I don't want to set keys or change auto-key mode from C++.
I only want to change the object's position and rotation and allow the user to press the "set keys", "auto key" and "play" buttons in the 3dsmax UI to capture the current object transformation in a key frame.
But as I wrote above: either some of the positional data is not captured, or the transformation is corrupted.

 

If I use AnimateOn() in combination with use SetNodeTM(), keys are created even when auto-key is not enabled by the user, which is what I don't want.

Also, if I use AnimateOn() with the controllers SetValue() and in the 3dsMax UI activate auto-key and playback, only rotation keys are created, not position keys.

 

0 Likes
Message 6 of 9

denisT.MaxDoctor
Advisor
Advisor

I am probably really missing something, despite the fact that I have written many animation plugins for 3DS MAX ...

Do you want to or not to set keys when changing node transform? What does "corrupted transform" mean? And how does "animation corruption" look like?

0 Likes
Message 7 of 9

contact
Contributor
Contributor

@denisT.MaxDoctorThanks again for the message.

I only want to change the position and rotation of an object to which I have the Inode.

However, I want the user to be able to capture that position/rotation as keys.

So let's say my C++ code makes the object "earth" orbit around the object "sun" at a steady pace - both position and rotation are updated, and I can see it in the viewport. All is good.

The user now turns on "auto keys" and presses play.

(1) if I use control->setValue(currentFrame, mat); then only rotation keyframes are recorded, ie: I see the earth move during the recording, but when playing back the animation, the earth spins in place without moving

(2) if I use inode->setNodeTM(currentFrame, mat); then both position and rotation are recorded. However, if there already are any keys on the object before the current frame, then the transformation is not applied correctly anymore. The earth is rotated randomly and scaled in weird constantly changing ways. So in the viewport now the earth goes completely haywire.

0 Likes
Message 8 of 9

denisT.MaxDoctor
Advisor
Advisor

@contact wrote:

However, I want the user to be able to capture that position/rotation as keys.

So let's say my C++ code makes the object "earth" orbit around the object "sun" at a steady pace - both position and rotation are updated, and I can see it in the viewport. All is good.

The user now turns on "auto keys" and presses play.

 


The functionality you described is similar to a tool created in c++. Well .. This is not a plugin or a controller (which might make a difference).

So ... my suggestion is ... and it is based on my experience: Make a button in your tool's UI -> Bake Transform

where now you know for sure that the current animation sequence should be baked into keys. After that, proceed as described above (animate in any way: animate ON, create a key, etc.)

0 Likes
Message 9 of 9

contact
Contributor
Contributor

@denisT.MaxDoctorThank you again for your reply.

I don't understand how that would be a solution though.

Again, if there are already keys on the object (for example from a previous "bake" at frame 1, and now the user moved to frame 2),

(a) if I use inode->SetNodeTM(t, mat); then the transformation is corrupted

(b) if I use control->SetValue(t, &pkg, 0, CTRL_ABSOLUTE); then either position or rotation are not applied

I can only avoid these issues by forcing a new key to be set, but the user may not want a key on frame 2.

0 Likes