[Closed] SDK-C# Set transform controller value
I’m trying to set value for a node’s transform controller, but not working:
using Autodesk.Max;
using System.Windows;
namespace TestLibrary
{
public partial class TestWindow : Window
{
private readonly static IGlobal globalInterface = GlobalInterface.Instance;
private readonly static IInterface coreInterface = globalInterface.COREInterface;
private void Button_Click(object sender, RoutedEventArgs e)
{
int time = coreInterface.Time;
IINode selNode = coreInterface.GetSelNode(0);
if (selNode == null) MessageBox.Show("Selection empty.");
else
{
IMatrix3 matrix = globalInterface.Matrix3.Create(true);
selNode.TMController.SetValue(time,matrix,true,GetSetMethod.Absolute);
globalInterface.COREInterface.RedrawViews(time, RedrawFlags.Normal, null);
}
}
public TestWindow()
{
InitializeComponent();
}
}
}
What is wrong in my code?
have you tried…
selNode.SetNodeTM(time, matrix);
?
otherwise you need to know what controller you are going to be dealing with usually a PRS so you have to deal with the sub controllers e.g.
Control *c;
c = node->GetTMController()->GetPositionController();
I think the setvalue above would only work if you were using a dedicated tm controller
I want to save and load a pose for the entire rig, it may be biped or cat or max bones. SetNodeTM works globally, I need the local one. I’m just wondering why SetValue for the transform controller doesn’t work.
try the c# version of this…
SetXFormPacket pckt(destTM);
tmControl->SetValue(ip->GetTime(), &pckt);
I can’t convert this to the C# code, Would you explain why we should use this?
It should be pretty straightforward in theory, but in practice it throws system exception and crashes max
Don’t know if it will work when used from compiled c# dll
code
tea = Teapot isSelected:true
g = (dotNetClass "Autodesk.Max.GlobalInterface").Instance
n = g.coreinterface14.getselnode 0
tm_parent = g.Matrix3.create()
tm_parent.IdentityMatrix()
tm = g.Matrix3.create()
tm.IdentityMatrix()
tm.SetTranslate (g.point3.create 0 0 50)
tm_xf = g.SetXFormPacket.Create tm tm_parent
g.suspendanimate()
n.TMController.SetValue currenttime.ticks tm_xf true (dotNetClass "Autodesk.Max.GetSetMethod").absolute
g.resumeanimate()
virtual void Control::SetValue ( TimeValue t,
void * val,
int commit = 1,
GetSetMethod method = CTRL_ABSOLUTE
) [pure virtual]
This method sets the value of the controller at the specified time.
val Points to an instance of a data type that corresponds with the controller type. These are the same as GetValue() above with the following exceptions:
For rotation controllers, if the GetSetMethod is CTRL_RELATIVE, *val points to an AngAxis, while if it is CTRL_ABSOLUTE it points to a Quat.
For Matrix3 controllers *val points to an instance of class SetXFormPacket. See Class SetXFormPacket.
It will crash in C# also:
object setXFormPacket = globalInterface.SetXFormPacket.Create(matrix,globalInterface.Matrix3.Create());
node.TMController.SetValue(coreInterface.Time, setXFormPacket, true, GetSetMethod.Absolute);
globalInterface.SetXFormPacket.Create has more overloads, maybe we should use it another way.
“&” in &pckt means we should send the pointer not variable, right? how we can do it in C#?
I tried something like this:
ISetXFormPacket setXFormPacket2 = globalInterface.SetXFormPacket.Create();
setXFormPacket2.Aa = globalInterface.AngAxis.Create();
setXFormPacket2.Command = SetXFormCommand.Set;
setXFormPacket2.LocalOrigin = true;
setXFormPacket2.P = globalInterface.Point3.Create();
setXFormPacket2.Q = globalInterface.Quat.Create();
setXFormPacket2.TmAxis = globalInterface.Matrix3.Create();
setXFormPacket2.TmParent = globalInterface.Matrix3.Create();
IntPtr setXFormPacket = Wrappers.CustomMarshalerSetXFormPacket.GetInstance(string.Empty).MarshalManagedToNative(setXFormPacket2);
node.TMController.SetValue(time, setXFormPacket, true, GetSetMethod.Absolute);
But again crashing …