Max.NET provides a mechanism for creating and using ParamBlock2 structures to store, animate, and use parameters of your objects. Must of this functionality is a direct mapping of the standard C++ SDK, however, certain points are different.
Everything that doesn't have to do with definition and creation of parameter blocks is identical to functionality and use in the standard C++ SDK. For example, IIParamBlock2 contains methods for accessing parameters (such as GetValue and SetValue). These can be used in exactly the same was as you would in C++ SDK. Therefore, you can refer to the standard 3d Studio Max SDK help files to figure out how to use these.
The definition of parameter block itself, although similar, is not identical to C++ SDK in Max.NET. You need to take care to follow the correct steps during this definition to make sure your parameters are setup properly.
Inside your class descriptor constructor you need to create an instance of IParamBlockDesc2 class. You can also do this in another place, however, the most logical place is inside the ClassDesc2 constructor of your plugin.
The IParamBlockDesc2 class must be constructed using the following parameters:
IParamBlockDesc2 Create( short ID, string int_name, IntPtr local_name, IClassDesc2 cd, ParamBlock2Flags flags, params object[] param5 );
An example of create method for parameter block descriptor:
this.paramBlockDesc = this.global.ParamBlockDesc2.Create( 0, "Parameters", IntPtr.Zero, this,
(ParamBlock2Flags)( (int)ParamBlock2Flags.Version + (int)ParamBlock2Flags.AutoConstruct + (int)ParamBlock2Flags.AutoUi ),
new object[] { 1, 0 } );
Currently only parameters of these types are supported:
After instantiating a parameter block descriptor use the instance to add parameters one by one using AddParam(...) call. The variable parameters you pass to this method must strictly follow the following format:
An example of this call would be:
this.paramBlockDesc.AddParam( 0, new object[]{
"width", ParamType2.Float, ParamBlock2Flags.Animatable, 0,
5.0f, 0.0f, 10.0f } );
Inside your object's class add a IIParamBlock2 member named paramBlock. You will need to override following methods:
NumRefs, GetReference, SetReference, NumSubs, SubAnim, NumParamBlocks, GetParamBlock
NumRefs, NumSubs, and NumParamBlocks should all return 1 (if you are only referencing parameter block; if you reference other objects as well then this number should be more than 1).
All the other methods should return your paramBlock class member when index 0 is requested. So, for example, GetReference(...) should return this.paramBlock when i is 0. Likewise, SetReference(...) should store the passed reference target into this.paramBlock when i is 0. This is important!
Inside your object class' constructor add the following line:
myClassDesc2.MakeAutoParamBlocks( this );
myClassDesc2 is the ClassDesc2 instance that you need to pass to your class' constructor. This class will create IIParamBlock2 instance and assign it through SetReference(...) method to your object's paramBlock class member (if everything is properly set up from step 3).
Max.NET can automatically setup any panel rollouts for you based on the parameters that you defined. To do this override the following methods in your object's class:
BeginEditParams, EndEditParams
In BeginEditParams call the following:
this.paramMap = this.myClassDesc2.paramBlockDesc.CreateParamMap2( ip, null, IntPtr.Zero, this.paramBlock );
paramBlockDesc must be a member of your ClassDesc2-derived class, and it must be the instance of the IParamBlockDesc2 class we set up earlier.
this.paramMap is a IIParamMap2 member that you need to add to your object class.
To properly clean up the user interface after used is done using your plugin call the following in EndEditParams:
if( this.paramMap != null )
{
this.global.DestroyCPParamMap2( this.paramMap );
this.paramMap = null;
}