How do I change a Physical Camera from the SDK?

How do I change a Physical Camera from the SDK?

johnny.johanssonSZ55P
Participant Participant
555 Views
5 Replies
Message 1 of 6

How do I change a Physical Camera from the SDK?

johnny.johanssonSZ55P
Participant
Participant

Specifically I need to change the Vertical Lens Shift at certain points in time. I have found that I can read the current settings like this:

 

MaxSDK::IPhysicalCamera* physical_camera = dynamic_cast<MaxSDK::IPhysicalCamera*>(camera_inode->EvalWorldState(0).obj);

for (int frame{ 0 }; frame < 20; ++frame) {
  Interval I;
  Point2 const P{ physical_camera->GetFilmPlaneOffset(frame * ticks_per_frame, I) };
  // P.y contains the value I want to change on the camera
}

 

... but there is no "SetFilmPlaneOffset" method in the IPhysicalCamera class, and I can't figure out how to change this or any camera setting.

 

If anyone can point me in the right direction, that would be very helpful!

0 Likes
Accepted solutions (1)
556 Views
5 Replies
Replies (5)
Message 2 of 6

johnny.johanssonSZ55P
Participant
Participant
Accepted solution

I found a way to do this and I am posting an example in case someone else finds the question and wants to know. Also, if anyone knows of a better way, please let me know!

 

Animatable *sub_animatable = physical_camera->SubAnim(0);
IParamBlock2 *parameter_block = dynamic_cast<IParamBlock2 *>(sub_animatable);
parameter_block->SetValueByName(L"vertical_shift", shift_amount, frame * ticks_per_frame);

(All error checking removed for brevity)

0 Likes
Message 3 of 6

denisT.MaxDoctor
Advisor
Advisor

@johnny.johanssonSZ55P wrote:

I found a way to do this and I am posting an example in case someone else finds the question and wants to know. Also, if anyone knows of a better way, please let me know!

 

 

Animatable *sub_animatable = physical_camera->SubAnim(0);
IParamBlock2 *parameter_block = dynamic_cast<IParamBlock2 *>(sub_animatable);
parameter_block->SetValueByName(L"vertical_shift", shift_amount, frame * ticks_per_frame);

 

 

 

(All error checking removed for brevity)


looks like physical_camera is ReferenceTarget* in your case, so you can get param block as:

 

IParamBlock2* pb2 = physical_camera->GetParamBlock(0);

 

 

Another thing that confuses me a little:

frame * ticks_per_frame

usually we don't have time in frames working with SDK... but you better know what type of time you have

 

(Always thanks for sharing a working solution)

  

0 Likes
Message 4 of 6

denisT.MaxDoctor
Advisor
Advisor

 

Another thing that confuses me a little:

frame * ticks_per_frame

usually we don't have time in frames working with SDK... but you better know what type of time you have  


since you're using frames as time value, I'm assuming you want to "bake" the #vertical_shift value... if that's the case, it's better to apply the controller right away and set its keys.

0 Likes
Message 5 of 6

johnny.johanssonSZ55P
Participant
Participant

Thank you for your suggestions Denis. Using "GetParamBlock" makes the code more compact, especially when including error checking, which is always welcome!

 

What I want to accomplish with my confusing time parameters is to set a specific value of the vertical shift for each rendered image (frame) in the animation sequence.

 

I define ticks_per_frame as

constexpr int fps{ 30 };
if (GetFrameRate() != fps) SetFrameRate(fps);
constexpr int ticks_per_frame{ TIME_TICKSPERSEC / fps };

 

Regarding your suggestion that " if that's the case, it's better to apply the controller right away and set its keys.", I currently do not have a good enough understanding of things for this to make much sense to me. (Like, what is "the controller", how do I access it and what does it mean to set its keys?). But if you have any tips on how I can get a better understanding, I would appreciate it!

 

Regards,

Johnny

0 Likes
Message 6 of 6

denisT.MaxDoctor
Advisor
Advisor

@johnny.johanssonSZ55P wrote:

What I want to accomplish with my confusing time parameters is to set a specific value of the vertical shift for each rendered image (frame) in the animation sequence.

I was expecting something like what you want to do. If you need to render an animation, the scene must be set to render, which means that all animation controls must be already animated according to your purpose.

To animate a parameter (SubAnim), you need to apply the appropriate controller and set the keys.

Look for:

((Animatable*)client)->AssignController (Animatable *control, int subAnim)
((Animatable*)control)->AddNewKey (TimeValue t, DWORD flags)
IKeyControl* GetKeyControlInterface(control)
IKeyControl::GetKey(int i,IKey *key)

 

Another option is to SetValue with AnimateOn (examples you can find in the SDK by searching these two keywords).

 

And of course, feel free to ask questions.

 

 

 

0 Likes