Class Animatable

3DS Max Plug-In SDK

Class Animatable

See Also: Class Interface, Class INode, List of Animatable Flags, Class IGraphObjectManager, Class IGraphNode, Class Object.

class Animatable : public InterfaceServer

Description:

This is the base class for almost all classes related to animation. Methods are available for getting the ClassID and SuperClassID of the plug-in, deleting this instance of the plug-in class, and parameter editing in the command panel. There are also methods that deal with the sub-animatables of the plug-in. Most of the track view related methods are here as well.

Method Groups

These hyperlinks take you to the start of groups of related methods within the class.

Bitmap Related Methods

Class Name, ClassID and SuperClassID Methods

Memory Management

Parameter Editing Methods

Sub-Anims Methods

Controller Assignment

Animation Properties

Make Unique Control

Flag Access Methods

RenderBegin and RenderEnd

System Plug-in Related Methods

Sub-Class Indication

AppData, Interfaces, and Set/GetProperties Methods

Operations to Keys

Track View Methods

Clipboard Methods

Interactive Adjustment

AnimTree and Auxiliary File Enumeration

NoteTracks

Parameter Block2 Methods

Schematic View Methods

Custom Attributes

Data Members:

protected:

unsigned long aflag;

The flags. These may be manipulated using the methods SetAFlag(), ClearAFlag(), and TestAFlag(). See List of Animatable Flags.

AnimPropertyList aprops;

This is a table of properties that a plug-in may use for its own storage needs. This table is also used by the system (for example Note Tracks and APP_DATA). A plug-in may use this, for example, when a class has some data that is used while its user interface is up. It can store the UI data on the property list temporarily and not have to carry around the data when it is not needed. See the methods of Template Class Tab for how to add and delete items from the list. Also see the methods GetProperty() and SetProperty() and Class AnimPropertyList.

Methods:

Class Name, ClassID and SuperClassID Methods

Prototype:

virtual void GetClassName(TSTR& s)

Remarks:

Implemented by the Plug-In.

Retrieves the name of the plug-in class. This name is usually used internally for debugging purposes. For Material plug-ins this method is used to put up the material "type" name in the Material Editor.

Parameters:

TSTR& s

The string to store the name of the class.

Prototype:

virtual Class_ID ClassID();

Remarks:

Implemented by the Plug-In.

This method must return the unique ID for the object. If two ClassIDs conflict, the system will only load the first one it finds. Therefore all ClassIDs must be unique to ensure they are loaded properly. A program is provided to generate these randomly. Generate a random Class_ID.

Return Value:

The Class_ID of the plug-in.

See Also: Class ClassID, List of Class IDs.

Prototype:

virtual SClass_ID SuperClassID();

Remarks:

Implemented by the Plug-In.

This method returns a system defined constant describing the class this plug-in class was derived from. The entire list of available super class IDs is in the include file PLUGAPI.H. Note: typedef ulong SClass_ID;

Return Value:

The super class ID of the plug-in. See List of Super Class IDs.

Memory Management

Prototype:

virtual void DeleteThis();

Remarks:

Implemented by the Plug-In.

When the system needs to delete an instance of a plug-in class it calls this method. The developer must use the same memory manager to allocate and deallocate memory. For example, if the developer used the 'new' operator to allocate memory, he or she should use the 'delete' operator to deallocate it. See the method ClassDesc::Create() for details on the allocation of memory.

Note: The default implementation of this method contains an assert(0) statement. This is because developers MUST override this default implementation. If the memory is not to be deleted this method should be implemented as {} so the assertion doesn't happen. See Memory Allocation.

See Also: DLL Functions and Class Descriptors, Class ClassDesc.

Prototype:

virtual void BeginEditParams(IObjParam *ip,ULONG flags,Animatable *prev=NULL)

Remarks:

Implemented by the Plug-In.

This method is called by the system when the user may edit the item's (object, modifier, controller, etc.) parameters.

Parameters:

IObjParam *ip

This is an interface pointer passed in. The developer may use the interface pointer to call methods such as AddRollupPage(). Note that this pointer is only valid between BeginEditParams() and EndEditParams(). A developer should not hang onto and use this pointer outside this interval.

ULONG flags

These flags describe which branch of the command panel or dialog the item is being editing in.

BEGIN_EDIT_CREATE

Indicates an item is being edited in the create branch.

BEGIN_EDIT_MOTION

Indicates a controller is being edited in the motion branch.

BEGIN_EDIT_HIERARCHY

Indicates a controller is being edited in the Pivot subtask of the hierarchy branch.

BEGIN_EDIT_IK

Indicates a controller is being edited in the IK subtask of the hierarchy branch.

BEGIN_EDIT_LINKINFO

Indicates a controller is being edited in the Link Info subtask of the hierarchy branch.

Animatable *prev=NULL

This parameter may be used in the motion and hierarchy branches of the command panel. This pointer allows a plug-in to look at the ClassID of the previous item that was being edited, and if it is the same as this item, to not replace the entire UI in the command panel, but simply update the values displayed in the UI fields. This prevents the UI from 'flickering' when the current item begins its edit. For example, if you are in the motion branch and are looking at an item's PRS controller values, and then select another item that is displayed with a PRS controller, the UI will not change - only the values displayed in the fields will change. If however you selected a target camera that has a lookat controller (not a PRS controller) the UI will change because a different set of parameters need to be displayed. Note that for items that are edited in the modifier branch this field can be ignored.

Prototype:

virtual void EndEditParams(IObjParam *ip, ULONG flags,Animatable *next=NULL)

Remarks:

Implemented by the Plug-In.

This method is called when the user is finished editing an objects parameters. The system passes a flag into the EndEditParams() method to indicate if the rollup page should be removed. If this flag is TRUE, the plug-in must un-register the rollup page, and delete it from the panel.

Parameters:

IObjParam *ip

This is an interface pointer passed in. The developer may use the interface pointer to call methods such as DeleteRollupPage().

ULONG flags

The following flag may be set:

END_EDIT_REMOVEUI

If TRUE, the item's user interface should be removed.

Animatable *next=NULL

This parameter may be used in the motion and hierarchy branches of the command panel. This pointer allows a plug-in to look at the ClassID of the next item that was being edited, and if it is the same as this item, to not replace the entire UI in the command panel. Note that for items that are edited in the modifier branch this field can be ignored.

Bitmap Related Methods

Prototype:

virtual void FreeAllBitmaps();

Remarks:

This method is available in release 2.0 and later only.

This method frees all bitmaps in this Animatable but doesn't recurse. This is used for freeing all the scene bitmaps after a render.

Default Implementation:

{}

Methods for Sub-Anims.

See Also: Advanced Topics Sub-Anims.

Prototype:

virtual int NumSubs()

Remarks:

Implemented by the Plug-In.

The system uses a = 4) BSPSPopupOnMouseOver(event);;">virtual array mechanism to access the sub-anims of a plug-in. This method returns the total number of sub-anims maintained by the plug-in. If a plug-in is using a parameter block to manage its parameters it should just return 1 for all the parameters directed by the parameter block.

Return Value:

The number of sub-anims used by the plug-in.

Default Implementation:

{ return 0; }

Prototype:

virtual Animatable* SubAnim(int i)

Remarks:

Implemented by the Plug-In.

This method returns a pointer to the 'i-th' sub-anim. If a plug-in is using a parameter block to manage all its parameters it should just return a pointer to the parameter block itself from this method. This method may return NULL so developers need to check the return value before calling other sub anim methods (such as SubAnimName()).

Parameters:

int i

This is the index of the sub-anim to return.

Default Implementation:

{ return NULL };

Prototype:

virtual TSTR SubAnimName(int i);

Remarks:

Implemented by the Plug-In.

This method returns the name of the 'i-th' sub-anim to appear in track view. The system has no idea what name to assign to the sub-anim (it only knows it by the virtual array index), so this method is called to retrieve the name to display. Developer need to make sure the 'i-th' SubAnim() is non-NULL or this method will fail.

Parameters:

int i

The index of the parameter name to return

Return Value:

The name of the 'i-th' parameter.

Prototype:

virtual BOOL SelectSubAnim(int subNum);

Remarks:

This method is available in release 2.0 and later only.

When a user is in Track View in Edit Keys mode and clicks on the green triangle of a controller then this method will be called on the client with the appropriate sub number that corresponds to it. For instance, the Editable Mesh object implements this to allow the user to select vertices that are animated from the Track View.

Parameters:

int subNum

The index of the sub-anim that was clicked on.

Return Value:

TRUE if implemented; otherwise FALSE. (Track View will call RedrawViewports() if something returns TRUE from this method).

Default Implementation:

{return FALSE;}

Prototype:

virtual ParamDimension* GetParamDimension(int i)

Remarks:

Implemented by the Plug-In.

Returns the type of dimension of the 'i-th' sub-anim. A dimension describes the type and order of magnitude of a sub-anim.

Parameters:

int i

Specifies the sub-anim (parameter) to return the dimension of.

Return Value:

The dimension of the 'i-th' sub-anim (parameter).

Default Implementation:

{return defaultDim;}

Prototype:

virtual DWORD GetSubAnimCurveColor(int subNum);

Remarks:

This method is available in release 2.0 and later only.

Implemented by the Plug-In.

Return the suggested color to draw a sub-anim's function curve. For example, the independent X, Y, Z position controller implements this method to return the suggested color for each of it's sub-controllers. The Euler Angle Controller uses these so its 3 sub-controllers are drawn in different colors.

Parameters:

int subNum

The index of the sub-anim.

Return Value:

One of the following values:

PAINTCURVE_GENCOLOR

PAINTCURVE_XCOLOR

PAINTCURVE_YCOLOR

PAINTCURVE_ZCOLOR

Default Implementation:

{return PAINTCURVE_GENCOLOR;}

Prototype:

virtual int SubNumToRefNum(int subNum)

Remarks:

Implemented by the Plug-In.

This method is used for copying and pasting in the track view. It converts an anim index to a reference index or returns -1 if there is no correspondence. If a client does not wish an anim to be copied or pasted then it can return -1 even if there is a corresponding reference num.

Parameters:

int subNum

The anim index to return the corresponding reference index of.

Default Implementation:

{ return -1}

Return Value:

The reference index corresponding to the anim index passed. Return -1 if there is no correspondence.

Prototype:

virtual BOOL CanCopyAnim()

Remarks:

Implemented by the Plug-In.

In addition to SubNumToRefNum(), if an anim doesn't want to be copied (via Track View or the Edit Modifier Stack 'Copy' button) it can return FALSE from this method, otherwise it can use the default implementation to return TRUE.

Default Implementation:

{return TRUE;}

Prototype:

int HasSubElements(int type=0);

Remarks:

Implemented by the System.

This method is used to determine if this Animatable has children or sub-anims. The type passed indicates what is tested.

Parameters:

int type=0

One of the following values:

0: Test for node children.

1: Test for sub-anims.

Return Value:

Nonzero if the item has children or sub-anims; otherwise zero.

Prototype:

virtual BOOL CanDeleteSubAnim(int i);

Remarks:

This method is available in release 3.0 and later only.

Implemented by the Plug-In.

Returns TRUE if the specified sub-anim controller can be deleted; otherwise FALSE.

A new "Delete Controller" button has been added to the Track View toolbar that is enabled when one or more delete-able tracks are selected. This method allows a plug-in to indicate to the Track View that one or more of its sub-controllers are delete-able. This provides a way to allow the user to delete node sub-controllers such as the visibility track, "Image Motion Blur Multiplier", "Object Motion Blur On/Off", etc. If the user selects one of the above-mentioned tracks in the Track View the "Delete Controller" button will become available.

Parameters:

int i

The zero based index of the sub-anim.

Default Implementation:

{return FALSE;}

Prototype:

virtual void DeleteSubAnim(int i);

Remarks:

This method is available in release 3.0 and later only.

Implemented by the Plug-In.

This method is called to delete the specified sub-anim controller. See the remarks in CanDeleteSubAnim() above.

Parameters:

int i

The zero based index of the sub-anim.

Default Implementation:

{}

Controller Assignment

Prototype:

virtual BOOL AssignController(Animatable *control, int subAnim);

Remarks:

Implemented by the Plug-In.

This method is called to assign the controller to the sub-anim whose index is passed.

Parameters:

Animatable *control

The controller to assign.

int subAnim

The index of the sub-anim to assign the controller to.

Default Implementation:

{ return FALSE; }

Return Value:

Returns TRUE if the controller was assigned; otherwise FALSE.

Animation Properties

Prototype:

virtual BOOL IsAnimated();

Remarks:

Implemented by the Plug-In.

Returns TRUE if this animatable actually has animation; otherwise FALSE. This method is recursive, so for example, if you call node->IsAnimated() it will return TRUE if any aspect of the node is animated; otherwise it will return FALSE.

Default Implementation:

The default implementation returns TRUE if a child anim has animation.

Make Unique Control

Prototype:

virtual BOOL CanMakeUnique()

Remarks:

Implemented by the Plug-In.

An anim can implement this method to return FALSE to prohibit make unique from being applied to it.

Default Implementation:

{return TRUE;}

Flag Access

Prototype:

void SetAFlag(int mask)

Remarks:

Implemented by the System.

Sets one or more of the bits of aflag.

Parameters:

int mask

The flags to set.

Prototype:

void ClearAFlag(int mask)

Remarks:

Implemented by the System.

Clears (sets to zero) one or more of the bits of aflag.

Parameters:

int mask

The flags to clear.

Prototype:

int TestAFlag(int mask)

Remarks:

Implemented by the System.

Used to test the state of one or more bits of aflag.

Parameters:

int mask

The flags to test.

Return Value:

Nonzero if the flags are set; otherwise 0.

Prototype:

virtual void FreeCaches()

Remarks:

Implemented by the Plug-In.

This is called to delete any item that can be rebuilt. For example, the procedural sphere object has a mesh that it caches. It could call Mesh::FreeAll() on the mesh from this method. This will free the vertex/face/uv arrays. If the sphere is ever evaluated again it can just rebuild the mesh. If an object (like a sphere) has modifiers applied to it, and those modifiers are not animated, then the result of the pipeline is cached in the node. So there is no reason for the sphere to also have a cache of its representation. Therefore when this method is called, the sphere can free the data of the mesh.

Default Implementation:

{}

AppData, Interfaces, and Properties.

The following methods deal with AppData. This is application specific data that may be attached to any Animatable in the scene. With these APIs any 3ds max object (controller, object, node, modifier, material, etc.) can have custom data attached by other objects. These chunks are saved in the .MAX file and can be accessed through the object they are attached to. Sample code using these APIs can be found in \MAXSDK\SAMPLES\UTILITIES\APPDATA.CPP.

Prototype:

void AddAppDataChunk(Class_ID cid, SClass_ID sid, DWORD sbid, DWORD len, void *d);

Remarks:

Implemented by the System.

This method is used to add an AppDataChunk to this Animatable. The chunk is identified using the Class_ID, and SuperClassID of the owner, and an ID for sub-chunks.

Note: Developers who want to add appdata to the scene should see the method:

ReferenceTarget *Interface::GetScenePointer().

Parameters:

Class_ID cid

The Class_ID of the owner of the chunk.

SClass_ID sid

The SuperClassID of the owner of the chunk.

DWORD sbid

An extra ID that lets the owner identify its sub-chunks.

DWORD len

The length of the data in bytes.

void *d

Points to the actual data. The data should be allocated using standard malloc() as it will be freed by the system using free().

Prototype:

AppDataChunk *GetAppDataChunk(Class_ID cid, SClass_ID sid, DWORD sbid);

Remarks:

Implemented by the System.

This method is used to retrieve a pointer to an AppDataChunk. The chunk is identified using the Class_ID, SuperClassID and sub-chunk ID of the owner.

Parameters:

Class_ID cid

The Class_ID of the owner of the chunk.

SClass_ID sid

The SuperClassID of the owner of the chunk.

DWORD sbid

An extra ID that lets the owner identify its sub-chunks.

Return Value:

A pointer to the AppDataChunk or NULL if it could not be found. See Class AppDataChunk.

Prototype:

BOOL RemoveAppDataChunk(Class_ID cid, SClass_ID sid, DWORD sbid);

Remarks:

Implemented by the System.

This method is used to delete an AppDataChunk. The chunk is identified using the Class_ID, SuperClassID and sub-chunk ID of the owner. Returns TRUE if the data was deleted and FALSE if it could not be found.

Parameters:

Class_ID cid

The Class_ID of the owner of the chunk.

SClass_ID sid

The SuperClassID of the owner of the chunk.

DWORD sbid

An extra ID that lets the owner identify its sub-chunks.

Return Value:

TRUE if the chunk was removed; otherwise FALSE.

Prototype:

void ClearAllAppData();

Remarks:

This method is available in release 2.0 and later only.

Implemented by the System.

Calling this method will remove all the AppData associated with this Animatable. Note: Plugins that call this method will erase all appdata chunks, not just their own. Therefore, it is usually more appropriate to use the RemoveAppDataChunk() API to remove AppData associated with a specific Class_ID.

Prototype:

virtual void* GetInterface(ULONG id)

Remarks:

Implemented by the Plug-In.

This method provides a mechanism for extending the class in the future. In 3ds max 4.0there are new interfaces that are accessed by passing an id to this method and it will respond by returning the corresponding interface pointer.

This method has been used however for a different purpose. It currently is used to determine if an object is of a particular class. With controllers for example, there is one base class Control, however there are many super classes (CTRL_FLOAT_CLASS_ID, CTRL_SCALE_CLASS_ID, etc.). If you wanted to find out if a given Animatable was a controller you would need to compare its SuperClassID to all the known types and only if it wasn't one of the known types could you be sure it wasn't a controller. Having to do this is inconvenient for a developer.

Instead the Control class implements this method. It looks at the id, and if it matches a predefined constant I_CONTROL, it returns its this pointer. In this way, given any Animatable, it is easy to find out if it is a controller by simply asking for the control interface. There is a macro that does this:

#define GetControlInterface(anim)

((Control*)anim->GetInterface(I_CONTROL))

A plug-in developer may use this macro as follows:

Control *c = GetControlInterface(anim);

This will either be NULL or a pointer to a valid controller.

This is the list of IDs currently defined for use with this macro. Note that these do NOT need to be released with method ReleaseInterface().

#define I_CONTROL 0x00001001

#define I_MASTER 0x00001010

#define I_EASELIST 0x00001020

#define I_MULTLIST 0x00001030

#define I_BASEOBJECT 0x00001040

#define I_PARTICLEOBJ 0x00001050

#define I_KEYCONTROL 0x00001060

#define I_TEXTOBJECT 0x00001070

#define I_WAVESOUND   0x00001080

#define I_SUBMTLAPI   0x00001090

#define I_MESHSELECT  0x000010A0

#define I_MESHSELECTDATA 0x000010B0

#define I_MAXSCRIPTPLUGIN 0x000010C0

#define I_MESHDELTAUSER  0x000010D0

#define I_MESHDELTAUSERDATA 0x000010E0

#define I_SPLINESELECT  0x000010F0

#define I_SPLINESELECTDATA 0x00001100

#define I_SPLINEOPS   0x00001110

#define I_PATCHSELECT  0x00001120

#define I_PATCHSELECTDATA 0x00001130

#define I_PATCHOPS   0x00001140

#define I_COMPONENT   0x0000F010

#define I_REFARRAY   0x0000F030

#define I_LINK_TARGET  0x0000F020

#define I_LAYER    0x0000F040

#define I_LAYER_MANAGER  0x0000F050

#define I_REAGENT   0x0000F060

Note: Plug-in defined interfaces should be greater than the following value:

#define I_USERINTERFACE 0x0000ffff

These other macros are defined for a similar purpose:

#define GetControlInterface(anim)

((Control*)anim->GetInterface(I_CONTROL))

#define GetObjectInterface(anim)

((BaseObject*)anim->GetInterface(I_BASEOBJECT))

#define GetParticleInterface(anim)

((ParticleObject*)anim->GetInterface(I_PARTICLEOBJ))

#define GetKeyControlInterface(anim)

((IKeyControl*)anim->GetInterface(I_KEYCONTROL))

#define GetMasterController(anim)

((ReferenceTarget*)anim->GetInterface(I_MASTER))

#define GetTextObjectInterface(anim)

((ITextObject*)anim->GetInterface(I_TEXTOBJECT))

#define GetWaveSoundInterface(anim)

((IWaveSound*)anim->GetInterface(I_WAVESOUND))

#define GetMeshSelectInterface(anim)

((IMeshSelect*)anim->GetInterface(I_MESHSELECT))

#define GetMeshSelectDataInterface(anim)

((IMeshSelectData*)anim->GetInterface(I_MESHSELECTDATA))

#define GetMeshDeltaUserInterface(anim)

((MeshDeltaUser*)anim->GetInterface(I_MESHDELTAUSER))

#define GetMeshDeltaUserDataInterface(anim)

((MeshDeltaUserData*)anim->GetInterface(I_MESHDELTAUSERDATA))

If a plug-in implements this method for its own purposes, it would, in general, switch on the id and if it is not aware of the id it would call this method on the base class. Otherwise it could respond to the id as it needed. See the sample code below for the how the Control class implements this method.

Parameters:

ULONG id

The id of the interface.

Default Implementation:

{ return NULL; }

Sample Code:

The following is the Control class implementation of this method. It looks at the id passed, and if it matches I_CONTROL it returns its this pointer. Otherwise it calls the base class method.

void* Control::GetInterface(ULONG id)

{

if (id==I_CONTROL) {

return this;

} else {

return Animatable::GetInterface(id);

}

}

Prototype:

virtual void ReleaseInterface(ULONG id,void *i)

Remarks:

Implemented by the Plug-In.

This method is not currently used. It is reserved for future use. Its purpose is for releasing an interface created with GetInterface().

Prototype:

virtual BaseInterface* GetInterface(Interface_ID id);

Remarks:

This method is available in release 4.0 and later only.

Returns a pointer to the Base Interface for the interface ID passed. The default implementation of this method retrieves this information from the ClassDesc for the plug-in.

Any future object-based interfaces should be allocated unique Interface_IDs (you can use Gencid.exe for this) and made available through this call.

The default implementation of GetInterface(Interface_ID) looks up a standalone interface of the given ID on the object's ClassDesc. This gives access to standalone interfaces via any of a plug-in's objects, without having to dig around for the ClassDesc, so you should fall back to calling the default implementation if you don't recognize an ID in your implementation of GetInterface(Interface_ID).

Parameters:

Interface_ID id

The unique ID of the interface to get. See Class Interface_ID.

Prototype:

virtual void ReleaseInterface(Interface_ID id, void* i);

Remarks:

This method is available in release 4.0 and later only.

Releases the interface retrieved above.

Prototype:

virtual int SetProperty(ULONG id, void *data)

Remarks:

Implemented by the Plug-In.

This is a general method for adding properties, when defining a new Interface would be too cumbersome. This method provides another way to extend the class without actually adding any methods. Sample code that implements this method to add properties to the property list is in \MAXSDK\SAMPLES\CONTROLLERS\PATHCTRL.CPP. See below.

Parameters:

ULONG id

The id for the property.

void *data

The data to store.

Return Value:

Nonzero if the property was set; otherwise zero.

Default Implementation:

{ return 0; }

Sample Code:

This code is from \MAXSDK\SAMPLES\CONTROLLERS\PATHCTRL.CPP. It is used to save the inverse kinematics user interface parameters of the path controller. It saves the property data on the aprops property list. See the Data Members at the beginning of Animatable for details on aprops.

int PathPosition::SetProperty(ULONG id, void *data)

 {

 if (id==PROPID_JOINTPARAMS) {

  if (!data) {

   int index = aprops.FindProperty(id);

   if (index>=0) {

    aprops.Delete(index,1);

    }

  } else {

   JointParamsPath *jp = (JointParamsPath*)GetProperty(id);

   if (jp) {

    *jp = *((JointParamsPath*)data);

    delete (JointParamsPath*)data;

   } else {

    aprops.Append(1,(AnimProperty**)&data);

    }

   }

  return 1;

 } else

 if (id==PROPID_INTERPUI) {

  if (!data) {

   int index = aprops.FindProperty(id);

   if (index>=0) {

    aprops.Delete(index,1);

    }

  } else {

   InterpCtrlUI *ui = (InterpCtrlUI*)GetProperty(id);

   if (ui) {

    *ui = *((InterpCtrlUI*)data);

   } else {

    aprops.Append(1,(AnimProperty**)&data);

    }

   }

  return 1;

 } else {

  return Animatable::SetProperty(id,data);

  }

 }

Prototype:

virtual void *GetProperty(ULONG id)

Remarks:

Implemented by the Plug-In.

This method is used to retrieve a property specified by the id passed (as stored by SetProperty()).

Note for 3ds max version 1.1:

Two new property IDs have been added:

PROPID_CLEARCACHES: When passed to a texture map or material, the material should dump any of its caches. For example, the bitmap texture responds to this by freeing the bitmap from memory. For sample code see \MAXSDK\SAMPLES\MATERIALS\BMTEX.CPP.

PROPID_HAS_WSM: When passed to an INode, will return TRUE if the node has World Space Modifiers applied to it or FALSE if it does not. For sample code see \MAXSDK\SAMPLES\IMPEXP\3DSEXP.CPP.

Note for 3ds max version 1.2:

A new id has been created and assigned the constant:

#define PROPID_EVAL_STEPSIZE_BUG_FIXED 0x1000.

This only effects the evaluation of objects when rendering them using motion blur. Motion blur works by evaluating the object numerous times (at fractions of a frame apart) and combining these images by blending them together.

Originally, 3ds max would make these evaluations in reverse order within a sub-frame -- from the last one, to the second to the last one, back to the first one. There is a problem with this for certain plug-ins that need to compute their state from time 0 forward. For these objects, the backwards approach may be too computationally intensive.

Both the forward and backward approaches exist in 3ds max and the developer may choose which method to use. 3ds max interrogates the object to see how it should handle the evaluation process -- either going backwards or forwards. It calls this method with id set to the constant PROPID_EVAL_STEPSIZE_BUG_FIXED. If a plug-in implements this method to return nonzero, it means the plug-in works correctly using forward stepping, and 3ds max will use that approach. If a plug-in does not implement this method and handle the id of PROPID_EVAL_STEPSIZE_BUG_FIXED it will return the default value of zero. This means the older method of backwards evaluation will be used.

Therefore, a plug-in object that wants to handle motion blur using forward stepping should implement this method, and if passed an id of PROPID_EVAL_STEPSIZE_BUG_FIXED, should return nonzero.

Parameters:

ULONG id

The id of the property to retrieve.

Default Implementation:

{ return NULL; }

Sample Code:

This code is from \MAXSDK\SAMPLES\CONTROLLERS\PATHCTRL.CPP. It is used to restore the inverse kinematics user interface parameters of the path controller. It retrieves the property data on the aprops property list. See the Data Members at the beginning of Animatable for details on aprops.

void* PathPosition::GetProperty(ULONG id)

 {

 if (id==PROPID_INTERPUI || id==PROPID_JOINTPARAMS) {

  int index = aprops.FindProperty(id);

  if (index>=0) {

   return aprops[index];

  } else {

   return NULL;

   }

 } else {

  return Animatable::GetProperty(id);

  }

 }

Clipboard Methods

Prototype:

virtual BOOL CanCopyTrack(Interval iv, DWORD flags)

Remarks:

Implemented by the Plug-In.

Returns TRUE if this item can copy its data over the specified range; otherwise returns FALSE.

Parameters:

Interval iv

The interval of time that would be copied.

DWORD flags

One or more of the following values:

TIME_INCLEFT

Include the left endpoint.

TIME_INCRIGHT

Include the right endpoint.

Default Implementation:

{return FALSE;}

Prototype:

virtual BOOL CanPasteTrack(TrackClipObject *cobj,Interval iv, DWORD flags)

Remarks:

Implemented by the Plug-In.

Returns TRUE if this item can paste its data over the specified range; otherwise returns FALSE.

Parameters:

TrackClipObject *cobj

The clipboard object that would be pasted. The item should look at the SuperClassID and Class_ID of the creator of the clip object to determine if it is a suitable object to paste. See Class TrackClipObject.

Interval iv

The interval of time that would be pasted.

DWORD flags

One or more of the following values:

TIME_INCLEFT

Include the left endpoint.

TIME_INCRIGHT

Include the right endpoint.

Default Implementation:

{return FALSE;}

Prototype:

virtual TrackClipObject *CopyTrack(Interval iv, DWORD flags)

Remarks:

Implemented by the Plug-In.

This method is called to copy the item's track data over the specified interval.

Parameters:

Interval iv

The interval of time over which to copy the track data.

DWORD flags

One or more of the following values:

TIME_INCLEFT

Include the left endpoint.

TIME_INCRIGHT

Include the right endpoint.

Return Value:

The item should return an instance of a class derived from TrackClipObject that contains the data for the item. See Class TrackClipObject.

Default Implementation:

{return NULL;}

Prototype:

virtual void PasteTrack(TrackClipObject *cobj, Interval iv, DWORD flags)

Remarks:

Implemented by the Plug-In.

This method is called to paste the specified clip object to this track. This method will not be called unless CanPasteTrack() returned TRUE.

Parameters:

TrackClipObject *cobj

The data to paste.

Interval iv

The interval of time to paste.

DWORD flags

One or more of the following values:

TIME_INCLEFT

Include the left endpoint.

TIME_INCRIGHT

Include the right endpoint.

Prototype:

virtual BOOL CanCopySubTrack(int subNum, Interval iv, DWORD flags);

Remarks:

This method is available in release 2.0 and later only.

Implemented by the Plug-In.

If CanCopyTrack() returns FALSE then this method is called on the sub-anim (passing the sub number).

This is used in particular for Parameter Blocks. In that case, if there is no controller plugged into the track, the copying and pasting of controllers can't be done (since there is no controller). However, this method allows the Parameter Block to handle it.

Parameters:

int subNum

Specifies the sub-anim to check.

Interval iv

The interval of time over which to copy the track data.

DWORD flags

One or more of the following values:

TIME_INCLEFT

Include the left endpoint.

TIME_INCRIGHT

Include the right endpoint.

Return Value:

TRUE if the specified item can copy its data over the specified range; otherwise FALSE.

Default Implementation:

{return FALSE;}

Prototype:

virtual BOOL CanPasteSubTrack(int subNum, TrackClipObject *cobj, Interval iv, DWORD flags);

Remarks:

This method is available in release 2.0 and later only.

Implemented by the Plug-In.

Returns TRUE if the specified item can paste its data over the specified range; otherwise returns FALSE.

Plug-ins can implement pasting for cases where their sub-anims don't implement it. An example of this is the Parameter Block class. It implements this method to allow pasting parameters that don't have controllers assigned to them. These aren't called on the client unless the sub-anim doesn't implement CanPasteTrack().

Parameters:

int subNum

Specifies the sub-anim to check.

TrackClipObject *cobj

The data to paste.

Interval iv

The interval of time to paste.

DWORD flags

One or more of the following values:

TIME_INCLEFT

Include the left endpoint.

TIME_INCRIGHT

Include the right endpoint.

Return Value:

TRUE if the specified item can paste its data over the specified range; otherwise FALSE.

Default Implementation:

{return FALSE;}

Prototype:

virtual TrackClipObject *CopySubTrack(int subNum, Interval iv, DWORD flags);

Remarks:

This method is available in release 2.0 and later only.

Implemented by the Plug-In.

This method is called to copy the specified sub anim's track data over the specified interval.

Parameters:

int subNum

The number of the sub-anim to copy.

Interval iv

The interval of time over which to copy the track data.

DWORD flags

One or more of the following values:

TIME_INCLEFT

Include the left endpoint.

TIME_INCRIGHT

Include the right endpoint.

Return Value:

The item should return an instance of a class derived from TrackClipObject that contains the data for the item. See Class TrackClipObject.

Default Implementation:

{return NULL;}

Prototype:

virtual void PasteSubTrack(int subNum, TrackClipObject *cobj,Interval iv, DWORD flags);

Remarks:

This method is available in release 2.0 and later only.

Implemented by the Plug-In.

This method is called to paste the specified clip object to the specified sub-anim track.

Parameters:

int subNum

The number of the sub-anim to paste.

TrackClipObject *cobj

The data to paste.

Interval iv

The interval of time to paste.

DWORD flags

One or more of the following values:

TIME_INCLEFT

Include the left endpoint.

TIME_INCRIGHT

Include the right endpoint.

Default Implementation:

{}

Interactive Adjustment

Prototype:

virtual void MouseCycleCompleted(TimeValue t);

Remarks:

This method is available in release 2.0 and later only (previously in Class Control in 1.x).

Implemented by the Plug-In.

This method is called on whatever controller the user is modifying with the mouse -- when the mouse button is released. For example when the user selects a node in the viewports, then drags, then releases the mouse button, this method is called. This method will also be called when the user clicks on a key in the track view and lets up. If a controller performs extensive calculation in its evaluation this method is handy. The controller could perhaps perform a simplified calculation during interactive adjustment of a node. Then when the user releases the mouse button this method is called and the extensive calculations are performed.

The default implementation of this method is recursive so it gets called on all sub-anims affected by a range bar operation.

Parameters:

TimeValue t

The time the mouse was released.

Prototype:

virtual void MouseCycleStarted(TimeValue t);

Remarks:

This method is available in release 2.0 and later only.

Implemented by the Plug-In.

This method is called on whatever controller the user is modifying with the mouse -- when the mouse button is pressed.

The default implementation of this method is recursive so it gets called on all sub-anims affected by a range bar operation.

Parameters:

TimeValue t

The time the mouse was first pressed.

Methods called when rendering is started and finished

Prototype:

virtual int RenderBegin(TimeValue t, ULONG flags=0)

Remarks:

Implemented by the Plug-In.

This method is called once at the beginning of each render. A plug-in can use this method to do any work required before a rendering actually begins. For example, some of the standard 3ds max plug-ins use this method to toggle between their 'viewport' state and the 'rendering' state. The Optimize modifier has two settings, one for the viewports and one for the rendering. When this method is called it then performs the switch from viewport to renderer.

Parameters:

TimeValue t

The time that the render is beginning.

ULONG flags=0

This is not used in 3ds max 1.x.

In 3ds max 2.0 and later the following flag value may be checked:

RENDERBEGIN_IN_MEDIT

Indicates that the render is occurring in the Material Editor.

Return Value:

Nonzero if the method is implemented; otherwise 0.

Default Implementation:

{ return 0; }

Prototype:

virtual int RenderEnd(TimeValue t)

Remarks:

Implemented by the Plug-In.

This method is called once at the end of each render.

Parameters:

TimeValue t

The time of the last rendered frame.

Return Value:

Nonzero if the method is implemented; otherwise 0.

Default Implementation:

{ return 0; }

System Plug-In Related Methods

Prototype:

virtual void GetSystemNodes(INodeTab &nodes, SysNodeContext)

Remarks:

Implemented by the Plug-In.

The master controller of a system plug-in should implement this method to give 3ds max a list of nodes that are part of the system. The master controller should fill in the given table with the INode pointers of the nodes that are part of the system. This will ensure that operations like cloning and deleting affect the whole system.

Said another way, GetSystemNodes() should be implemented for the master controller of a system, and should return a list of pointers to all nodes that are part of the system. GetInterface() should be implemented for the slave TM controllers of the system and return a pointer to the master controller.

3ds max will use GetInterface() in the TM controller of each selected node to retrieve the master controller and then call GetSystemNodes() on the master controller to get the list of nodes.

Parameters:

INodeTab &nodes

The table of nodes that are part of the system.

SysNodeContext

This parameter is available in release 4.0 and later only.

Previously, this method gathered related (system) nodes during cloning, deleting, file merging and saving.

This parameter can be used to specify the context under that the "syetem nodes" are used. These are; kSNCClone, kSNCDelete, kSNCFileMerge, and kSNCFileSave.

Default Implementation:

{}

The following methods deal with operations to Keys and Track View:

Prototype:

virtual BOOL BypassTreeView()

Remarks:

Implemented by the Plug-In.

This method indicates to the system that this anim should not appear in the Track View. Note: Track View was formally referred to as Tree View. This is what parameter blocks do for example. They don't show up in track view, just their sub-anims do. This prevents the extra level of the parameter block from appearing.

Return Value:

Return TRUE to not appear in the Track View. Note that if you return TRUE your children will appear in the track view regardless.

Default Implementation:

{ return FALSE; }

Prototype:

virtual BOOL BypassTrackBar();

Remarks:

This method is available in release 3.0 and later only.

Implemented by the Plug-In.

This method indicates to the system that this anim should not appear in the Track Bar. The anim won't show up in the Track Bar, just its sub-anims will. This function is similar to BypassTreeView(), but refers to the Track Bar instead of the Track View.

Return Value:

Return TRUE to not appear in the Track Bar. Note that if you return TRUE your children will appear in the Track Bar regardless.

Default Implementation:

{ return BypassTreeView(); }

Prototype:

virtual BOOL BypassPropertyLevel();

Remarks:

This method is available in release 3.0 and later only.

Implemented by the Plug-In.

Use this method in order to cause parameters in this Animatable (as a sub-anim) to appear to reside at the level of the parent Animatable in the scripter. Return TRUE and this Animatable won't appear as a property in the scripter however it's sub-anims children will. The default implementation returns FALSE indicating it will appear normally.

Default Implementation:

{ return FALSE; }

Prototype:

virtual BOOL InvisibleProperty();

Remarks:

This method is available in release 3.0 and later only.

Implemented by the Plug-In.

This method controls the visibility of this Animatable and all of it sub-anims to appear as properties in the scripter. Return TRUE and it won't nor will it's sub-anims. Returning FALSE (the default implementation) causes this Animatable and it's sub-anims to appear as normal.

Default Implementation:

{ return FALSE; }

Prototype:

virtual int NumKeys()

Remarks:

Implemented by the Plug-In.

This method returns the number of keys managed by the plug-in, or NOT_KEYFRAMEABLE if it does not work with keys.

Default Implementation:

{return NOT_KEYFRAMEABLE;}

Prototype:

virtual TimeValue GetKeyTime(int index)

Remarks:

Implemented by the Plug-In.

This method returns the time of the key specified by index.

Parameters:

int index

Specifies the key whose time should be returned.

Default Implementation:

{return 0;}

Prototype:

virtual int GetKeyIndex(TimeValue t)

Remarks:

Implemented by the Plug-In.

Returns the index of the key at time t or -1 if no key is found at the specified time.

Parameters:

TimeValue t

Specifies the time at which to retrieve the key index.

Default Implementation:

{return -1;}

Prototype:

virtual BOOL GetNextKeyTime(TimeValue t,DWORD flags,TimeValue &nt)

Remarks:

Implemented by the Plug-In.

An item should implement this method to allow the Key Mode button in 3ds max's UI to function properly. If Key Mode is set, and the user clicks the Previous Key or Next Key button, this method will be called to retrieve the next or previous key.

Parameters:

TimeValue t

The current time (frame slider position).

DWORD flags

One or more of the following value:

NEXTKEY_LEFT

Search to the left.

NEXTKEY_RIGHT

Search to the right.

NEXTKEY_POS

Next position key.

NEXTKEY_ROT

Next rotation key.

NEXTKEY_SCALE

Next scale key.

TimeValue &nt

The time of the previous or next key is returned here.

Return Value:

TRUE if the key time was retrieved; otherwise FALSE.

Default Implementation:

{ return FALSE;}

Prototype:

virtual void CopyKeysFromTime(TimeValue src,TimeValue dst,DWORD flags)

Remarks:

Implemented by the Plug-In.

This method is called to copy or interpolate a new key from a source time to a destination time.

Parameters:

TimeValue src

The source time.

TimeValue dst

The destination time.

DWORD flags

These filter flags are passed to a transform (Matrix3) controller. The TM can decide what to do with them. They have obvious meaning for the PRS controller. One or more of the following values:

COPYKEY_POS

Copy the position key.

COPYKEY_ROT

Copy the rotation key.

COPYKEY_SCALE

Copy the scale key.

Prototype:

virtual void DeleteKeyAtTime(TimeValue t)

Remarks:

Implemented by the Plug-In.

This method is called to delete the key at the specified time.

Parameters:

TimeValue t

Specifies the time to delete the key.

Default Implementation:

{}

Prototype:

virtual BOOL IsKeyAtTime(TimeValue t,DWORD flags)

Remarks:

Implemented by the Plug-In.

Returns TRUE if there is a key of the specified type at the specified time; otherwise FALSE.

Parameters:

TimeValue t

Specifies the time to check for a key.

DWORD flags

One or more of the following values:

KEYAT_POSITION

KEYAT_ROTATION

KEYAT_SCALE

Default Implementation:

{return FALSE;}

Prototype:

virtual int GetKeyTimes(Tab<TimeValue> &times,Interval range,DWORD flags)

Remarks:

Implemented by the Plug-In.

This method is called to build a table of time values, one time for each key within the interval passed. The plug-in should load up the table passed with the time of each key present over the specified time range.

Parameters:

Tab<TimeValue> &times

The table of time values to build. See Class Tab.

Interval range

The range of time over which to retrieve the key times. See Class Interval.

DWORD flags

One of the following values:

KEYAT_POSITION - Return for Position keys only.

KEYAT_ROTATION - Return for Rotation keys only.

KEYAT_SCALE - Return for Scale keys only.

Return Value:

The plug-in should return an offset so the system can access the keys using an index. Thus it should return the number of keys skipped because their times were before range.Start(). For example, say the first keyframe in the interval passed was actually the third key overall. The plug-in should return 2 (two keys preceded the first one stored). In this way, the system can access the key as the i-th key in the table plus 2.

Default Implementation:

{return 0;}

Prototype:

virtual int GetKeySelState(BitArray &sel,Interval range,DWORD flags)

Remarks:

Implemented by the Plug-In.

When this method is called, the plug-in should update the BitArray sel to indicate if its keys present in the interval passed are selected or deselected.

Parameters:

BitArray &sel

The bit array to update, one bit for each key within the interval range. If the key is selected, the corresponding bit should be 1, otherwise it should be 0. See Class BitArray.

Interval range

The range of time over which to retrieve the key selected state. Class Interval.

DWORD flags

One or more of the following values:

KEYAT_POSITION - Return for Position keys only.

KEYAT_ROTATION - Return for Rotation keys only.

KEYAT_SCALE - Return for Scale keys only.

Note: If the flags are passed as 0, use ALL keys within the range.

Return Value:

The number of keys skipped because their times were before range.Start().

Default Implementation:

{return 0;}

Prototype:

void OpenTreeEntry(int type, DWORD tv)

Remarks:

Implemented by the System.

This method may be called to open the specified Track View entry. The type parameter indicates if the child tree or the sub-anim (parameter) tree is opened.

Parameters:

int type

This value may be either 0 or 1. If 0, the child tree is opened. If 1, the sub-anim tree is opened.

DWORD tv

This parameter is available in release 2.0 and later only.

It specifies which Track View(s) are altered, one bit for each Track View. In 3ds max 2.0 the open/closed state is independent for each Track View. The low-order 16 bits represent the 16 track views.

Prototype:

void CloseTreeEntry(int type, DWORD tv)

Remarks:

Implemented by the System.

This method may be called to close the specified Track View entry. The type parameter indicates if the child tree or the sub-anim tree is closed.

Parameters:

int type

This value may be either 0 or 1. If 0, the child tree is closed. If 1, the sub-anim (parameter) tree is closed.

DWORD tv

This parameter is available in release 2.0 and later only.

It specifies which Track View(s) are altered, one bit for each Track View. In 3ds max 2.0 the open/closed state is independent for each Track View. The low-order 16 bits represent the 16 track views.

Prototype:

int IsTreeEntryOpen(int type, DWORD tv);

Remarks:

Implemented by the System.

Returns nonzero if the specified tree is opened for this item, and zero if it is closed.

Parameters:

int type

This value may be either 0 or 1. If 0, the child tree is checked. If 1, the sub-anim (parameter) tree is checked.

DWORD tv

This parameter is available in release 2.0 and later only.

Specifies which Track View to check -- one bit per Track View.

Prototype:

BOOL GetSelInTrackView(DWORD tv);

Remarks:

This method is available in release 2.0 and later only.

Implemented by the System.

Returns TRUE if this animatable is selected in the specified Track View; FALSE if not selected.

Parameters:

DWORD tv

Specifies which Track View to check -- one bit per Track View.

Prototype:

void SetSelInTrackView(DWORD tv, BOOL sel);

Remarks:

This method is available in release 2.0 and later only.

Implemented by the System.

Sets the state of this animatable to selected or deselected in the specified Track View.

Parameters:

DWORD tv

Specifies which Track View to check -- one bit per Track View.

BOOL sel

TRUE to select; FALSE to deselect.

Prototype:

BOOL InTrackViewSelSet(int which);

Remarks:

This method is available in release 2.0 and later only.

Implemented by the System.

Returns TRUE if this animatable is in the specified selection set; otherwise FALSE.

Parameters:

int which

Indicates the Track View selection set to check -- this should be >=0 and <MAX_TRACKVIEW_SELSETS

Prototype:

void SetTrackViewSelSet(int which, BOOL inOut);

Remarks:

This method is available in release 2.0 and later only.

Implemented by the System.

Sets the selected or deselected state of this animatable in the specified selection set.

Parameters:

int which

Indicates the Track View selection set to modify -- this should be >=0 and <MAX_TRACKVIEW_SELSETS

BOOL inOut

TRUE for in; FALSE for out.

Operations to a selected block of time.

Prototype:

virtual Interval GetTimeRange(DWORD flags);

Remarks:

Implemented by the System.

Returns an interval representing the tracks time range, based on the flags passed.

Parameters:

DWORD flags

One or more of the following values:

TIMERANGE_SELONLY

The bounding interval of selected keys only.

TIMERANGE_ALL

Whatever the channel's time range is - usually the bounding interval of all keys.

TIMERANGE_CHILDNODES

The node's time range should include its child nodes.

TIMERANGE_CHILDANIMS

A animatable's child anim ranges should be included.

Return Value:

An interval representing the tracks time range.

Prototype:

virtual void EditTimeRange(Interval range,DWORD flags)

Remarks:

Implemented by the Plug-In.

This method is called to change the range of the anim (usually a controller) to the given range. This is the range that is used to compute the Out of Range Types. For example, this method may be called when the user is working in Position Range mode in the Track View.

Keyframe controllers generally support this method. Other controllers may or may not support this method. For example, a procedural controller may want to maintain a range upon which the animation is based. The user may then move the range bar around to move the procedural animation around.

The range passed is the range used to compute the Out of Range Types. This may be used for example with the Loop ORT to extend the range, either past the last key or before the first key, so there is some time to loop back to the start.

The 3ds max keyframe controllers maintain an interval that is their range. It is normally defined to be the first key to the last key. If the user goes into Position Range mode and moves the range around, this method is called. The keyframe controllers set a flag to indicate that the range is no longer linked to the first key or the last key. Then the range is stored in the interval, and this is considered the 'in range' portion of the controller. If time is evaluated outside of this range it applies the ORTs to determine the value.

Parameters:

Interval range

The new range for the anim.

DWORD flags

EDITRANGE_LINKTOKEYS

If this flag is set, the controller should re-establish the link between the start and end keys and its range. This is passed if the user presses the link to keys button in Track View. Thus, if one of the ends of the interval is at a key, link it to the key so that if the key moves, the interval moves.

Default Implementation:

{}

Prototype:

virtual void DeleteTime(Interval iv, DWORD flags);

Remarks:

Implemented by the Plug-In.

This method is called to delete the specified interval of time (or the keys within the interval).

Parameters:

Interval iv

The interval of time to delete.

DWORD flags

One or more of the following values:

TIME_INCLEFT

Include the left endpoint.

TIME_INCRIGHT

Include the right endpoint.

TIME_NOSLIDE

Delete any keys in the interval but don't actually remove the block of time.

Default Implementation:

{}

Prototype:

virtual void ReverseTime(Interval iv, DWORD flags);

Remarks:

Implemented by the Plug-In.

This method is called to reverse the data within the specified interval. For example, if the interval passed is from frame 10 to 20, and there is a key at frame 12, the key should be moved to frame 18. Considered another way, if all the times were normalized, and there was a value n between 0 and 1, n should be changed to 1-n.

Parameters:

Interval iv

The interval of time over which to reverse the data.

DWORD flags

One or more of the following values:

TIME_INCLEFT

Include the left endpoint.

TIME_INCRIGHT

Include the right endpoint.

Default Implementation:

{}

Sample Code:

INTERP_CONT_TEMPLATE

void InterpControl<INTERP_CONT_PARAMS>::ReverseTime( Interval iv,

 DWORD flags )

 {

 Interval test = TestInterval(iv,flags);

 int n = keys.Count();

 HoldTrack();

 for ( int i = 0; i < n; i++ ) {

  if (keys[i].TimeLocked()) continue;

  if ( test.InInterval(keys[i].time) ) {

   TimeValue delta = keys[i].time - iv.Start();

   keys[i].time = iv.End()-delta;

   }

  }

 keys.KeysChanged();

 keys.CheckForDups();

 ivalid.SetEmpty();

 NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);

 }

Prototype:

virtual void ScaleTime(Interval iv, float s);

Remarks:

Implemented by the Plug-In.

This method is called to scale an interval of time by the specified scale factor.

Parameters:

Interval iv

The interval of time to scale. The origin of the scale is at iv.Start().

float s

The scale factor for the time.

Default Implementation:

{}

Sample Code:

INTERP_CONT_TEMPLATE

void InterpControl<INTERP_CONT_PARAMS>::ScaleTime( Interval iv, float s)

 {

 int n = keys.Count();

 TimeValue delta =

  int(s*float(iv.End()-iv.Start())) + iv.Start()-iv.End();

 HoldTrack();

 for ( int i = 0; i < n; i++ ) {

  if (keys[i].TimeLocked()) continue;

  if ( iv.InInterval(keys[i].time) ) {

   keys[i].time =

    int(s*float(keys[i].time - iv.Start())) + iv.Start();

  } else

  if (keys[i].time > iv.End()) {

   keys[i].time += delta;

   }

  }

 keys.KeysChanged();

 ivalid.SetEmpty();

 NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);

 }

Prototype:

virtual void InsertTime(TimeValue ins, TimeValue amount)

Remarks:

Implemented by the Plug-In.

This method is called to insert the specified amount of time at the specified insertion point.

Parameters:

TimeValue ins

The time to begin the insertion.

TimeValue amount

The amount of time to insert.

Default Implementation:

{}

Prototype:

virtual BOOL SupportTimeOperations()

Remarks:

Implemented by the Plug-In.

If an anim supports time operations in the track view (cut, copy, paste, etc.), it should implement this method to return TRUE. When it is FALSE the user cannot select blocks of time in the anim's track.

Default Implementation:

{return FALSE;}

Prototype:

virtual void MapKeys(TimeMap *map, DWORD flags);

Remarks:

Implemented by the Plug-In.

The method is called to update the keys specified by the flags, using the TimeMap passed. The plug-in should go through the specified keys and change their time to TimeMap::map(time). See the sample code below for how this is done.

Parameters:

TimeMap *map

This class provides a method, map(), that is applied to the keys. See Class TimeMap.

DWORD flags

The flags indicate the keys to operate on. One or more of the following values:

TRACK_DOSEL

Selected keys only.

TRACK_DOALL

All the keys, ignore their selection state.

TRACK_SLIDEUNSEL

Slide unselected keys to the right. Keys are slid by the amount the last key was transformed.

TRACK_RIGHTTOLEFT

Enumerate right to left. If TRACK_SLIDEUNSEL is set, keys will slide to the left.

TRACK_DOSUBANIMS

Sub-Animatables keys as well.

TRACK_DOCHILDNODES

Child Nodes keys as well

TRACK_MAPRANGE

The range, if not locked to first and last key, should be mapped as well.

Sample Code:

INTERP_CONT_TEMPLATE

void InterpControl<INTERP_CONT_PARAMS>::MapKeys(TimeMap *map,DWORD flags )

 {

 int n = keys.Count();

 BOOL changed = FALSE;

 if (!n) goto doneMapKeys;

 HoldTrack();

 if (flags&TRACK_DOALL) {

  for (int i = 0; i < n; i++) {

   if (keys[i].TimeLocked()) continue;

   keys[i].time = map->map(keys[i].time);

   changed = TRUE;

   }

 } else

 if (flags&TRACK_DOSEL) {

  BOOL slide = flags&TRACK_SLIDEUNSEL;

  TimeValue delta = 0, prev;

  int start, end, inc;

  if (flags&TRACK_RIGHTTOLEFT) {

   start = n-1;

   end = -1;

   inc = -1;

  } else {

   start = 0;

   end = n;

   inc = 1;

   }

  for (int i = start; i != end; i += inc) {

   if (keys[i].TimeLocked()) continue;

   if (keys[i].TestKFlag(KEY_SELECTED)) {

    prev = keys[i].time;

    keys[i].time = map->map(keys[i].time);

    delta = keys[i].time - prev;

    changed = TRUE;

   } else if (slide) {

    keys[i].time += delta;

    }

   }

  }

 if (flags&TRACK_MAPRANGE && keys.TestTFlag(RANGE_UNLOCKED)) {

  TimeValue t0 = map->map(keys.range.Start());

  TimeValue t1 = map->map(keys.range.End());

  keys.range.Set(t0,t1);

  }

 if (changed) {

  keys.KeysChanged();

  ivalid.SetEmpty();

  NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);

  }

doneMapKeys:

 Animatable::MapKeys(map,flags);

 }

Prototype:

virtual void DeleteKeys(DWORD flags)

Remarks:

Implemented by the Plug-In.

This method is called to delete keys, as specified by the flags passed.

Parameters:

DWORD flags

One or more of the following values:

TRACK_DOSEL

Delete selected keys only.

TRACK_DOALL

Delete all keys (ignore selection state).

TRACK_SLIDEUNSEL

Slide unselected keys to the right.

TRACK_RIGHTTOLEFT

Enumerate right to left. If TRACK_SLIDEUNSEL is set, keys will slide to the left.

Default Implementation:

{}

Prototype:

virtual void DeleteKeyByIndex(int index);

Remarks:

Implemented by the Plug-In.

Deletes the key specified by the index passed.

Parameters:

int index

The index of the key to delete.

Default Implementation:

{}

Prototype:

virtual void SelectKeys(TrackHitTab& sel, DWORD flags);

Remarks:

Implemented by the Plug-In.

This method is called to select or deselect a set of keys identified by the TrackHitTab and the specified flags.

Parameters:

TrackHitTab& sel

The table of track hit records. See Class TrackHitRecord and Class Tab. Note the following: typedef Tab<TrackHitRecord> TrackHitTab;

DWORD flags

Either SELKEYS_SELECT, SELKEYS_DESELECT, or a combination of SELKEYS_CLEARKEYS and SELKEYS_CLEARCURVE will be specified.

One or more of the following values:

SELKEYS_SELECT

The keys should be selected.

SELKEYS_DESELECT

The keys should be deselected.

SELKEYS_CLEARKEYS

All keys should be deselected.

SELKEYS_CLEARCURVE

All keys on the function curve should be deselected.

SELKEYS_FCURVE

Indicates that we are operating on the keys of a function curve, and not of a track.

Default Implementation:

{}

Prototype:

virtual void SelectSubKeys(int subNum, TrackHitTab& sel, DWORD flags);

Remarks:

This method is available in release 2.0 and later only.

Implemented by the Plug-In.

This method is called on the client when the client takes over control of an anims function curves. It's called to select or deselect a set of keys identified by the TrackHitTab and the specified flags.

Parameters:

int subNum

The index of the sub-anim to select or deselect

TrackHitTab& sel

The table of track hit records. See Class TrackHitRecord and Class Tab. Note the following: typedef Tab<TrackHitRecord> TrackHitTab;

DWORD flags

Either SELKEYS_SELECT, SELKEYS_DESELECT, or a combination of SELKEYS_CLEARKEYS and SELKEYS_CLEARCURVE will be specified.

One or more of the following values:

SELKEYS_SELECT

The keys should be selected.

SELKEYS_DESELECT

The keys should be deselected.

SELKEYS_CLEARKEYS

All keys should be deselected.

SELKEYS_CLEARCURVE

All keys on the function curve should be deselected.

SELKEYS_FCURVE

Indicates that we are operating on the keys of a function curve, and not of a track.

Default Implementation:

{}

Prototype:

virtual void SelectSubCurve(int subNum,BOOL sel);

Remarks:

This method is available in release 2.0 and later only.

Implemented by the Plug-In.

This method is called to set the selected state of the sub-curve whose index is passed.

Parameters:

int subNum

The index of the sub-anim to select or deselect

BOOL sel

TRUE to select the curve; FALSE to deselect it.

Default Implementation:

{}

Prototype:

virtual void SelectKeyByIndex(int i, BOOL sel);

Remarks:

This method is available in release 2.0 and later only.

Implemented by the Plug-In.

This method is called to set the selected state of the key whose index is passed.

Parameters:

int i

The key to select or deselect.

BOOL sel

TRUE to select the key; FALSE to deselect it.

Default Implementation:

{}

Prototype:

virtual void FlagKey(TrackHitRecord hit);

Remarks:

Implemented by the Plug-In.

This method is called to have the plug-in flag or mark a specific key identified by the TrackHitRecord.

As an example, when the user goes to move a selection set of keys in the Track View, a yellow marker is drawn. To move the group of keys, the user clicks on a single one. The system needs to track this one key as it is moved, and needs a way to identify it. This method is called so the developer can flag this key as the one that was selected. This is needed because the Track View doesn't know anything about a specific controllers ordering of keys and thus cannot refer to it by index.

The system will call GetFlagKeyIndex() (described below) to retrieve the index of the key that was flagged.

Parameters:

TrackHitRecord hit

The developer uses this class to identify a key. This is the hit record that the controller gave the Track View in the first place to identify the hit. Thus this is enough information to identify the key. See Class TrackHitRecord.

Default Implementation:

{}

Sample Code:

INTERP_CONT_TEMPLATE

void InterpControl<INTERP_CONT_PARAMS>::FlagKey(TrackHitRecord hit)

 {

 int n = keys.Count();

 for ( int i = 0; i < n; i++ ) {

  keys[i].ClearKFlag(KEY_FLAGGED);

  }

 assert(hit.hit>=0&&hit.hit<(DWORD)n);

 keys[hit.hit].SetKFlag(KEY_FLAGGED);

 }

Prototype:

virtual int GetFlagKeyIndex();

Remarks:

Implemented by the Plug-In.

Returns the index of the key that is flagged, or -1 if no keys are flagged. See the method above.

Default Implementation:

{return -1;}

Sample Code:

INTERP_CONT_TEMPLATE

int InterpControl<INTERP_CONT_PARAMS>::GetFlagKeyIndex()

 {

 int n = keys.Count();

 for ( int i = 0; i < n; i++ ) {

  if (keys[i].TestKFlag(KEY_FLAGGED)) {

   return i;

   }

  }

 return -1;

 }

Prototype:

virtual int NumSelKeys();

Remarks:

Implemented by the Plug-In.

Returns the number of selected keys.

Default Implementation:

{return 0;}

Prototype:

virtual void CloneSelectedKeys(BOOL offset=FALSE);

Remarks:

Implemented by the Plug-In.

This method is called to make a copy of the selected keys.

Parameters:

BOOL offset=FALSE

If TRUE, set the new key time to be centered between the original key and the next key.

Prototype:

virtual void AddNewKey(TimeValue t,DWORD flags);

Remarks:

Implemented by the Plug-In.

This method is called to add a new key at the specified time. The value of the key is set to the value of the previous key, or interpolated between keys, based on the flags passed.

Parameters:

TimeValue t

The time to add the key.

DWORD flags

One or more of the following values:

ADDKEY_SELECT

Select the new key and deselect any other selected keys.

ADDKEY_INTERP

If TRUE then initialize the new key to the interpolated value at that time. If FALSE, initialize the key to the value of the previous key.

Default Implementation:

{}

Prototype:

virtual void MoveKeys(ParamDimensionBase *dim,float delta,DWORD flags);

Remarks:

Implemented by the Plug-In.

This method is called to move selected keys vertically in the function curve editor. This moves the key values but does not alter the key times. The developer adds the delta to the selected key values, after converting them using the dimension *dim passed. See the sample code below for how this may be done.

Parameters:

ParamDimensionBase *dim

This class is used to scale the parameter's values into and out of units used in the user interface. For example, if the parameter was an angle, it would be shown in degrees, but stored in radians. Methods of this class allow the value to be converted back and forth. This is needed because the delta passed is in user interface units. Thus the selected key values need to be converted before the delta is applied. See Class ParamDimensBase.

float delta

The amount to move the keys (move the values - not the times). This is in the units of the user interface. For example, if an angle has a value in the function curve editor of 100 degrees, 100 would be passed as the delta.

DWORD flags

These are not currently used.

Default Implementation:

{}

Sample Code:

INTERP_CONT_TEMPLATE

void InterpControl<INTERP_CONT_PARAMS>::MoveKeys(ParamDimensionBase *dim,float delta,DWORD flags)

 {

 int n = keys.Count();

 if (!n) return;

 float m = 1.0f;

 Interval valid;

 BOOL changed = FALSE;

 HoldTrack();

 for (int i = 0; i < n; i++ ) {

  for (int j=0;j<ELS;j++) {

   if (keys[i].AnyElemSelected()) {

    m = GetMultVal(keys[i].time,valid);

    }

   if (keys[i].ElemSelected(j)) {

    keys[i][j] =

     dim->UnConvert(dim->Convert(keys[i][j]*m)+delta)/m;

    changed = TRUE;

    }

   }

  }

 if (changed) {

  // FALSE indicates that key times didn't

  // change so sorting isn't necessary.

  keys.KeysChanged(FALSE);

  ivalid.SetEmpty();

  NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);

  }

 }

Prototype:

virtual void ScaleKeyValues(ParamDimensionBase *dim,float origin, float scale,DWORD flags)

Remarks:

Implemented by the Plug-In.

This method is called to scale selected keys values. This scales the key values but does not alter the key times. The developer scales the selected key values about the specified origin, after converting them using the dimension *dim passed.

Note the following macro available for scaling about an origin:

#define ScaleAboutOrigin(val,origin,scale)

 ((((val)-(origin))*(scale))+(origin))

Parameters:

ParamDimensionBase *dim

This class is used to scale the parameter's values into and out of units used in the user interface. For example, if the parameter was an angle, it would be shown in degrees, but stored in radians. Methods of this class allow the value to be converted back and forth. See Class ParamDimensBase.

float origin

The origin about which the keys are scaled.

float scale

The scale factor to apply to the key values.

DWORD flags

These are not currently used.

Default Implementation:

{}

Sample Code:

INTERP_CONT_TEMPLATE

void InterpControl<INTERP_CONT_PARAMS>::ScaleKeyValues(

 ParamDimensionBase *dim,float origin,float scale,DWORD flags)

 {

 int n = keys.Count();

 if (!n) return;

 BOOL changed = FALSE;

 HoldTrack();

 for (int i = 0; i < n; i++ ) {

  for (int j=0;j<ELS;j++) {

   if (keys[i].ElemSelected(j)) {

    keys[i][j] = dim->UnConvert( ScaleAboutOrigin(

     dim->Convert(keys[i][j]),origin,scale) );

    changed = TRUE;

    }

   }

  }

 if (changed) {

  keys.KeysChanged(FALSE);

  ivalid.SetEmpty();

  NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);

  }

 }

Prototype:

virtual void SelectCurve(BOOL sel)

Remarks:

Implemented by the Plug-In.

The plug-in keeps track of whether its function curve is selected or not. This method is called to have the plug-in select or deselect its function curve.

Parameters:

BOOL sel

TRUE if the curve should be selected; FALSE if it should be deselected.

Default Implementation:

{}

Prototype:

virtual BOOL IsCurveSelected()

Remarks:

Implemented by the Plug-In.

Returns TRUE if the function curve is selected; otherwise returns FALSE.

Default Implementation:

{return FALSE;}

Prototype:

virtual BOOL IsKeySelected(int index)

Remarks:

Implemented by the Plug-In.

Returns TRUE if the key specified by the index is selected; otherwise FALSE.

Parameters:

int index

The index of the key to test.

Default Implementation:

{return FALSE;}

Prototype:

virtual int GetSelKeyCoords(TimeValue &t, float &val, DWORD flags);

Remarks:

Implemented by the Plug-In.

This method is used to determine the commonality of the selected keys for display in the time/value type in fields of Track View. It is also used to retrieve the value and/or time of the selected keys (if there is only one selected, or they are common to the selected keys). The flags parameter specified which values to retrieve. The return value indicates if nothing, or several keys were selected. It also indicates if the selected keys shared a common time and/or common value.

Parameters:

TimeValue &t

The time of the selected keys is returned here (if appropriate).

float &val

The value of the selected keys is returned here (if appropriate).

DWORD flags

One of the following values:

KEYCOORDS_TIMEONLY

Only the time t needs to be updated.

KEYCOORDS_VALUEONLY

Only the value val needs to be updated.

Return Value:

This indicates what was selected, and what these keys had in common. One or more of the following values should be set:

KEYS_NONESELECTED

This indicates that no keys are selected.

KEYS_MULTISELECTED

This indicates that multiple keys are selected.

Both of these last two bits could be set.

KEYS_COMMONTIME

If the selected keys share the same time then this flag should be set. In this case it is appropriate to update t if required.

KEYS_COMMONVALUE

If the selected keys share the same value then this flag should be set. In this case it is appropriate to update val if required.

Default Implementation:

{return KEYS_NONESELECTED;}

Prototype:

virtual void SetSelKeyCoords(TimeValue t, float val,DWORD flags)

Remarks:

Implemented by the Plug-In.

This method is called to update the time and/or value of the selected keys as specified by the flags. This is called if the user uses the time/value type in fields of Track View.

Parameters:

TimeValue t

The time to set for the selected keys (if the flags indicate this is needed).

float val

The value to set for the selected keys (if the flags indicate this is needed).

DWORD flags

One of the following values:

KEYCOORDS_TIMEONLY

Only the time needs to be updated.

KEYCOORDS_VALUEONLY

Only the value needs to be updated.

Default Implementation:

{}

Prototype:

virtual int SetSelKeyCoordsExpr(ParamDimension *dim, TCHAR *timeExpr, TCHAR *valExpr, DWORD flags);

Remarks:

Implemented by the Plug-In.

This method is available in release 2.0 and later only.

This method is similar to SetSelKeyCoords() above. In that case you're given a time and a value and are to update the selected keys with these values (based on the flags passed). In this case, you are instead passed time and value expressions (as strings). The ideas is that these strings are evaulated as expressions and the resulting values are used to updated the selected keys. For instance, the user could select a bunch of keys and then type in n+45. This would add 45 to all the values of the keys.

Developers can use the 3ds max expression parser (see Class Expr) to evaluate the strings. Debug SDK users can see \MAXSDKDB\SDKSRC\CTRLTEMP.H for an example (or see the sample code below)). If a plug-in doesn't support this feature it can return FALSE from this method and the old SetSelKeyCoords() method will be called. Note that the variable names are defined as KEYCOORDS_TIMEVAR and KEYCOORDS_VALVAR.

Parameters:

ParamDimension *dim

This is used to convert the parameter value once you get it.

TCHAR *timeExpr

A string containing the time expression.

TCHAR *valExpr

A string containing the value expression.

DWORD flags

One of the following values:

KEYCOORDS_TIMEONLY

Only the time t needs to be updated.

KEYCOORDS_VALUEONLY

Only the value val needs to be updated.

Return Value:

This indicates what was selected, and what these keys had in common. One or more of the following values should be set:

KEYCOORDS_EXPR_UNSUPPORTED

Don't implement this method

KEYCOORDS_EXPR_ERROR

Error in expression

KEYCOORDS_EXPR_OK

Expression evaluated

Default Implementation:

{return KEYCOORDS_EXPR_UNSUPPORTED;}

 

Sample Code:

INTERP_CONT_TEMPLATE

int InterpControl<INTERP_CONT_PARAMS>::SetSelKeyCoordsExpr(

  ParamDimension *dim,

  TCHAR *timeExpr, TCHAR *valExpr, DWORD flags)

 {

 Expr texpr, vexpr; 

 float vin, vout=0.0f, tfin, tfout=0.0f;

 

 if (timeExpr) {

  texpr.defVar(SCALAR_VAR,KEYCOORDS_TIMEVAR);

  if (texpr.load(timeExpr)!=EXPR_NORMAL) return KEYCOORDS_EXPR_ERROR;  

  }

 if (valExpr) {

  vexpr.defVar(SCALAR_VAR,KEYCOORDS_VALVAR);

  if (vexpr.load(valExpr)!=EXPR_NORMAL) return KEYCOORDS_EXPR_ERROR;  

  }

 

 int n = keys.Count();

 if (!n) return KEYCOORDS_EXPR_OK;

 HoldTrack();

 for (int i = 0; i < n; i++ ) {

  if (!(flags&KEYCOORDS_VALUEONLY)) {

   if (keys[i].TimeLocked()) continue;

   if (keys[i].TestKFlag(KEY_SELECTED)) {    

    tfin = float(keys[i].time)/float(GetTicksPerFrame());

    texpr.eval(&tfout, 1, &tfin);

    keys[i].time = int(tfout*GetTicksPerFrame());

    }

   }

  if (!(flags&KEYCOORDS_TIMEONLY)) {

   for (int j=0;j<ELS;j++) {

    if (keys[i].ElemSelected(j)) {

     vin = dim->Convert(keys[i][j]);

     vexpr.eval(&vout, 1, &vin);

     keys[i][j] = dim->UnConvert(vout);

     }

    }

   }

  } 

 keys.KeysChanged();

 keys.CheckForDups();

 ivalid.SetEmpty();

 NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);

 return KEYCOORDS_EXPR_OK;

Prototype:

virtual void AdjustTangents(TrackHitRecord hit,ParamDimensionBase *dim, Rect& rcGraph,float tzoom, int tscroll,float vzoom, int vscroll,int dx,int dy, DWORD flags)

Remarks:

Implemented by the Plug-In.

If a plug-in has tangent handles, this method is called if the user adjusts them. If a plug-in doesn't have tangent handles, this method may be ignored. This method is called if the user selects one of the handles and moves the mouse. This method is passed the dx, and dy of the mouse motion.

The plug-in may have any types of handles it wishes, and it is responsible for processing whatever needs to be done when the user adjusts them. The method is passed information about the screen space, such as the overall rectangle, and time and value scroll and zoom factors. See List of Screen-Time-Value Macros for macros to convert in and out of screen space.

Parameters:

TrackHitRecord hit

This identifies the handle that was selected (hit).

ParamDimensionBase *dim

The parameter dimension. See Class ParamDimensionBase.

Rect& rcGraph

This is the rectangle of the graph viewport.

float tzoom

This is the time zoom factor.

int tscroll

This is the time scroll factor.

float vzoom

This is the value zoom factor.

int vscroll

This is the value scroll factor.

int dx

The mouse movement in screen coordinates in the x direction.

int dy

The mouse movement in screen coordinates in the y direction.

DWORD flags

One of the following values:

ADJTAN_LOCK

Indicates the tangents are locked.

ADJTAN_BREAK

Indicates the tangents have been broken.

Default Implementation:

{}

Drawing and hit testing tracks

Prototype:

virtual int GetTrackVSpace(int lineHeight)

Remarks:

Implemented by the Plug-In.

Returns the vertical space occupied by the track in units of one line.

Parameters:

int lineHeight

The height of a single line in pixels.

Default Implementation:

{ return 1; }

Prototype:

virtual int HitTestTrack(TrackHitTab& hits,Rect& rcHit,Rect& rcTrack,float zoom,int scroll,DWORD flags)

Remarks:

Implemented by the Plug-In.

This method is called to determine which keys lie within the rcHit rectangle. Keys that are hit are added to the hits table.

Parameters:

TrackHitTab& hits

The table of TrackHitRecords to update. Each key that lies within the hit rectangle (is hit) should be added to this table. It is up to the plug-in to define a scheme that allows it to identify its hits using the data members of Class TrackHitRecord. Also see Class Tab for methods to add to the table.

Rect& rcHit

This is the region that was selected for hit testing. This may be a small rectangle about the mouse pick point, or a larger rectangle if the user selected by window.

Rect& rcTrack

This is the entire rectangular region of the track.

float zoom

The is the time zoom factor.

int scroll

This is the time scroll factor.

DWORD flags

One or more of the following value:

HITTRACK_SELONLY

Selected only.

HITTRACK_UNSELONLY

Unselected only.

HITTRACK_ABORTONHIT

Abort hit testing on first hit.

HITCURVE_TESTTANGENTS

Hit test curve tangents.

Return Value:

One of the following values:

TRACK_DONE

This indicates the track was hit tested.

TRACK_DORANGE

This indicates that the system will handle hit testing to the range bar for the item. For example a node returns this value because it does not have any keys. Therefore it just lets the user hit test the range bar. In general, anything that is not a leaf controller will not implement this method and return the default. The system will then simply hit test the range bar.

TRACK_ASKCLIENT

If a plug-in returns this value then the anim's client will be given a chance to paint the track in Track View. If a client returns this value then the method PaintSubTrack() will be called.

Default Implementation:

{ return TRACK_DORANGE; }

Prototype:

virtual int PaintTrack(ParamDimensionBase *dim, HDC hdc,Rect& rcTrack,Rect& rcPaint, float zoom, int scroll, DWORD flags)

Remarks:

Implemented by the Plug-In.

This method is called to display the item in the track view. If an item needs to draw itself in a special fashion, it implements this method to do so. For example, a sound plug-in may draw its waveform using this method. If an item does not need to draw itself, the default implementation may be used. This draws the range bar for the item.

Note: When drawing something to appear in Track View, a developer should not do any clipping of their own. 3ds max will take care of all clipping itself.

Parameters:

ParamDimensionBase *dim

This parameter is available in release 2.0 and later only.

The dimension for the parameter of this track.

HDC hdc

The handle of the = 4) BSPSPopupOnMouseOver(event);;">device context.

Rect& rcTrack

The entire rectangle of the inside of the track.

Rect& rcPaint

This is the rectangular region that needs to be repainted - the invalid region.

float zoom

The time zoom factor.

int scroll

The time scroll factor.

DWORD flags

One or more of the following values. These are filters for controllers with more than one curve. NOTE: RGB controllers interpret X as red, Y as green, and Z as blue.

DISPLAY_XCURVE

DISPLAY_YCURVE

DISPLAY_ZCURVE

Return Value:

One of the following values:

TRACK_DONE

Indicates the track was painted.

TRACK_DORANGE

Indicates the system should draw the range bars for the item.

TRACK_ASKCLIENT

Indicates the anim's client will be given a chance to paint the track in Track View. See Animatable::PaintSubTrack() which will be called to do this.

Default Implementation:

{ return TRACK_DORANGE; }

Prototype:

virtual int PaintSubTrack(int subNum, ParamDimensionBase *dim, HDC hdc, Rect& rcTrack, Rect& rcPaint, float zoom, int scroll, DWORD flags);

Remarks:

This method is available in release 2.0 and later only.

Implemented by the Plug-In.

This method will be called if PaintTrack returns TRACK_ASKCLIENT. This gives the anim's client a chance to paint the tracks in Track View.

Parameters:

int subNum

Specifies the sub-anim to paint.

ParamDimensionBase *dim

The dimension for the parameter of this track.

HDC hdc

The handle of the = 4) BSPSPopupOnMouseOver(event);;">device context.

Rect& rcTrack

The entire rectangle of the inside of the track.

Rect& rcPaint

This is the rectangular region that needs to be repainted - the invalid region.

float zoom

The time zoom factor.

int scroll

The time scroll factor.

DWORD flags

One or more of the following values. These are filters for controllers with more than one curve. NOTE: RGB controllers interpret X as red, Y as green, and Z as blue.

DISPLAY_XCURVE

DISPLAY_YCURVE

DISPLAY_ZCURVE

Return Value:

One of the following values:

TRACK_DONE

Indicates the track was painted.

TRACK_DORANGE

Indicates the system should draw the range bars for the item.

Default Implementation:

{return TRACK_DORANGE;}

Drawing and hit testing function curves

Prototype:

virtual int PaintFCurves(ParamDimensionBase *dim, HDC hdc, Rect& rcGraph,Rect& rcPaint, float tzoom, int tscroll, float vzoom, int vscroll, DWORD flags);

Remarks:

Implemented by the Plug-In.

This method is called to draw the function curve of the anim.

Parameters:

ParamDimensionBase *dim

The parameter dimension. See Class ParamDimensionBase.

HDC hdc

The handle of the = 4) BSPSPopupOnMouseOver(event);;">device context.

Rect& rcGraph

The entire rectangle of the inside of the graph region.

Rect& rcPaint

This is the rectangular region that needs to be repainted - the invalid region.

float tzoom

The time zoom factor.

int tscroll

The time scroll factor.

float vzoom

The value zoom factor.

int vscroll

The value scroll factor.

DWORD flags

One or more of the following values:

PAINTCURVE_SHOWTANGENTS

Show the curve tangent handles.

PAINTCURVE_FROZEN

Show the curve in a frozen state.

These are filters for controllers with more than one curve. NOTE: RGB controllers interpret X as red, Y as green and Z as blue.

DISPLAY_XCURVE

DISPLAY_YCURVE

DISPLAY_ZCURVE

PAINTCURVE_GENCOLOR

This option is availabe in 3ds max 2.0 and later only.

Draw the curve in its standard color.

The following options are passed to float controllers indicating a sugested color for drawing.

PAINTCURVE_XCOLOR

This option is availabe in 3ds max 2.0 and later only.

Draw the curve in red.

PAINTCURVE_YCOLOR

This option is availabe in 3ds max 2.0 and later only.

Draw the curve in green.

PAINTCURVE_ZCOLOR

This option is availabe in 3ds max 2.0 and later only.

Draw the curve in blue.

Return Value:

A plug-in should always return 0.

Default Implementation:

{ return 0; }

Prototype:

virtual int HitTestFCurves(ParamDimensionBase *dim,TrackHitTab& hits, Rect& rcHit, Rect& rcGraph,float tzoom, int tscroll,float vzoom,int vscroll, DWORD flags)

Remarks:

Implemented by the Plug-In.

This method is called to hit test the item's function curves. It is called to determine which keys on the curve lie within the rcHit rectangle. Keys that are hit are added to the hits table.

Parameters:

ParamDimensionBase *dim

The parameter dimension. See Class ParamDimensionBase.

TrackHitTab& hits

The table of TrackHitRecords to update. Each key that lies within the hit rectangle (is hit) should be added to this table. It is up to the plug-in to define a scheme that allows it to identify its hits using the data members of Class TrackHitRecord. Also see Class Tab for methods to add to the table.

Rect& rcHit

This is the region that was selected for hit testing. This may be a small rectangle about the mouse pick point, or a larger rectangle if the user selected by window.

Rect& rcGraph

This is the entire rectangle of the graph region.

float tzoom

This is the time zoom factor.

int tscroll

This is the time scroll factor.

float vzoom

This is the time zoom factor.

int vscroll

This is the time scroll factor.

DWORD flags

One or more of the following values:

HITTRACK_SELONLY

Selected only.

HITTRACK_UNSELONLY

Unselected only.

HITTRACK_ABORTONHIT

Abort hit testing on first hit.

HITCURVE_TESTTANGENTS

Hit Test curve tangent handles.

These are filters for controllers with more than one curve. NOTE: RGB controllers interpret X as red, Y as green and Z as blue.

DISPLAY_XCURVE

DISPLAY_YCURVE

DISPLAY_ZCURVE

Return Value:

One of the following values to indicate what was hit:

HITCURVE_KEY

Hit one or more keys.

HITCURVE_WHOLE

Hit the curve (anywhere).

HITCURVE_TANGENT

Hit a tangent handle.

HITCURVE_NONE

Nothing was hit.

HITCURVE_ASKCLIENT

Ask the client to hit test the function curve. See HitTestSubFCurve() below.

Default Implementation:

{ return HITCURVE_NONE; }

Prototype:

virtual int PaintSubFCurves(int subNum, ParamDimensionBase *dim, HDC hdc, Rect& rcGraph,Rect& rcPaint, float tzoom, int tscroll, float vzoom, int vscroll, DWORD flags);

Remarks:

Implemented by the Plug-In.

This method is called to draw the specified sub-anim function curve. This allows the client to paint its function curve.

Parameters:

int subNum

The sub-anim number to paint.

ParamDimensionBase *dim

The parameter dimension. See Class ParamDimensionBase.

HDC hdc

The handle of the = 4) BSPSPopupOnMouseOver(event);;">device context.

Rect& rcGraph

The entire rectangle of the inside of the graph region.

Rect& rcPaint

This is the rectangular region that needs to be repainted - the invalid region.

float tzoom

The time zoom factor.

int tscroll

The time scroll factor.

float vzoom

The value zoom factor.

int vscroll

The value scroll factor.

DWORD flags

One or more of the following values:

PAINTCURVE_SHOWTANGENTS

Show the curve tangent handles.

PAINTCURVE_FROZEN

Show the curve in a frozen state.

These are filters for controllers with more than one curve. NOTE: RGB controllers interpret X as red, Y as green and Z as blue.

DISPLAY_XCURVE

DISPLAY_YCURVE

DISPLAY_ZCURVE

PAINTCURVE_GENCOLOR

This option is availabe in 3ds max 2.0 and later only.

Draw the curve in its standard color.

The following options are passed to float controllers indicating a sugested color for drawing.

PAINTCURVE_XCOLOR

This option is availabe in 3ds max 2.0 and later only.

Draw the curve in red.

PAINTCURVE_YCOLOR

This option is availabe in 3ds max 2.0 and later only.

Draw the curve in green.

PAINTCURVE_ZCOLOR

This option is availabe in 3ds max 2.0 and later only.

Draw the curve in blue.

Return Value:

A plug-in should always return 0.

Default Implementation:

{ return 0; }

Prototype:

virtual int HitTestSubFCurves(int subNum, ParamDimensionBase *dim, TrackHitTab& hits, Rect& rcHit, Rect& rcGraph, float tzoom, int tscroll, float vzoom, int vscroll, DWORD flags);

Remarks:

Implemented by the Plug-In.

This method is called if HitTestFCurves() returns HITCURVE_ASKCLIENT. It allows the client to hit test its sub-anim curves.

Parameters:

int subNum

The sub-anim number to hit test.

ParamDimensionBase *dim

The parameter dimension. See Class ParamDimensionBase.

TrackHitTab& hits

The table of TrackHitRecords to update. Each key that lies within the hit rectangle (is hit) should be added to this table. It is up to the plug-in to define a scheme that allows it to identify its hits using the data members of Class TrackHitRecord. Also see Class Tab for methods to add to the table.

Rect& rcHit

This is the region that was selected for hit testing. This may be a small rectangle about the mouse pick point, or a larger rectangle if the user selected by window.

Rect& rcGraph

This is the entire rectangle of the graph region.

float tzoom

This is the time zoom factor.

int tscroll

This is the time scroll factor.

float vzoom

This is the time zoom factor.

int vscroll

This is the time scroll factor.

DWORD flags

One or more of the following values:

HITTRACK_SELONLY

Selected only.

HITTRACK_UNSELONLY

Unselected only.

HITTRACK_ABORTONHIT

Abort hit testing on first hit.

HITCURVE_TESTTANGENTS

Hit Test curve tangent handles.

These are filters for controllers with more than one curve. NOTE: RGB controllers interpret X as red, Y as green and Z as blue.

DISPLAY_XCURVE

DISPLAY_YCURVE

DISPLAY_ZCURVE

Return Value:

One of the following values to indicate what was hit:

HITCURVE_KEY

Hit one or more keys.

HITCURVE_WHOLE

Hit the curve (anywhere).

HITCURVE_TANGENT

Hit a tangent handle.

HITCURVE_NONE

Nothing was hit.

Default Implementation:

{ return HITCURVE_NONE; }

Prototype:

virtual void EditTrackParams(TimeValue t, ParamDimensionBase *dim, TCHAR *pname, HWND hParent, IObjParam *ip, DWORD flags)

Remarks:

Implemented by the Plug-In.

This method is called for the plug-in to put up a modal dialog and let the user edit the tracks parameters for the selected keys. This function should not return until the user has completed editing at which time any windows that were created should be destroyed. Unlike BeginEditParams() and EndEditParams() this interface is modal.

Parameters:

TimeValue t

This time represents the horizontal position of where the user right clicked to bring up the modal edit track parameters dialog. See the flags below for when this parameter is valid.

ParamDimensionBase *dim

The parameter dimension. See Class ParamDimensionBase.

TCHAR *pname

The name of the parameter as given by the client.

HWND hParent

This is the parent window that should be used to create any dialogs.

IObjParam *ip

An interface pointer available for calling functions in 3ds max.

DWORD flags

One or more of the following values:

EDITTRACK_FCURVE

The user is in the function curve editor.

EDITTRACK_TRACK

The user is in one of the track views.

EDITTRACK_SCENE

The user is editing a path in the scene.

EDITTRACK_BUTTON

The user invoked by choosing the properties button. In this case the time parameter is NOT valid.

EDITTRACK_MOUSE

The user invoked by right clicking with the mouse. In this case the time parameter is valid.

Default Implementation:

{}

Prototype:

virtual int TrackParamsType()

Remarks:

Implemented by the Plug-In.

This method returns a value that indicates how the track parameter editing is invoked.

Return Value:

One of the following values:

TRACKPARAMS_NONE

Has no track parameters. If this is returned then EditTrackParams() will not be called.

TRACKPARAMS_KEY

Entered by right clicking on a selected key. This should be used if the dialog provides parameters for the entire controller (for example as the Noise controller's dialog does).

TRACKPARAMS_WHOLE

Entered by right clicking anywhere in the track. This should be used if the dialog will represent the selection of keys (as a key info type dialog does).

Default Implementation:

{return TRACKPARAMS_NONE;}

Prototype:

virtual int GetFCurveExtents(ParamDimensionBase *dim,float &min, float &max, DWORD flags)

Remarks:

Implemented by the Plug-In.

This method is called to calculate the largest and smallest values of the anim.

Parameters:

ParamDimensionBase *dim

The dimension of the anim. See Class ParamDimensionBase.

float &min

The smallest value. These are in the units given by the dimension. For example, if it was an angle parameter that was displayed in degrees, the units returned through min should be in degrees as well.

float &max

The largest value. These are in the units given by the dimension. For example, if it was an angle parameter that was displayed in degrees, the units returned through max should be in degrees as well.

DWORD flags

These are filters for controllers with more than one curve. NOTE: RGB controllers interpret X as red, Y as green and Z as blue. One or more of the following values:

DISPLAY_XCURVE

DISPLAY_YCURVE

DISPLAY_ZCURVE

Return Value:

If this method is processed, return nonzero; otherwise zero.

Default Implementation:

{return 0;}

Sub-Class Indication

Prototype:

virtual BOOL IsSubClassOf(Class_ID classID)

Remarks:

Implemented by the Plug-In.

If an object is a sub-class of a particular class, it will have a different ClassID() because it is a different class. This method allows an object to indicate that it is a sub-class of a particular class and therefore can be treated as one. For example, a class could be derived from TriObject. This derived class would have a different ClassID() then the TriObject's class ID however it still can be treated (cast) as a TriObject because it is derived from TriObject. Note the default implelementation: a class is considered to also be a subclass of itself.

Parameters:

Class_ID classID

The Class_ID of the item that this class is a sub-class of.

Return Value:

TRUE if this class is a sub-class of classID; otherwise FALSE.

Default Implementation:

{return classID==ClassID();}

Enumeration of Anims and Auxiliary Files

Prototype:

int EnumAnimTree(AnimEnum *animEnum, Animatable *client, int subNum);

Remarks:

Implemented by the System.

This method recursively enumerates the Animatable hierarchy. It will call the AnimEnum::proc() method passing it the anim, that anim's parent (the client), and the sub-anim index of that anim to the client, for every anim and sub-anim in the hierarchy.

Parameters:

AnimEnum *animEnum

The callback object, called once for each sub anim from 0 to subNum-1. See Class AnimEnum.

Animatable *client

The client anim. This is the Animatalbe whose sub-anims are enumerated.

int subNum

The sub-anim index of the client at which to begin the enumeration. Pass 0 to do them all.

Return Value:

One of the following values:

ANIM_ENUM_PROCEED

ANIM_ENUM_STOP

ANIM_ENUM_ABORT

Prototype:

virtual void EnumAuxFiles(NameEnumCallback& nameEnum, DWORD flags)

Remarks:

Implemented by the Plug-In.

This method is used to enumerate any 'auxiliary' files maintained by the item and record the filename with the callback. Entities which actually need to load auxiliary files (for instance texture maps) must implement this method, possibly calling ReferenceMaker::EnumAuxFiles() also. The ReferenceMaker implementation simply calls itself on all its references (see below).

Class Interface has a method that may be used to call this on the entire system. This includes the renderer, materials editor, atmospheric effects, background, video post, lights, etc. -- everything that may have auxiliary files associated with it. After specifying the appropriate flags a list of filenames is created that matched the enumeration conditions as specified by the flags. This is used for instance by the Archive function in 3ds max to grab a list of bitmap files used by the system.

Parameters:

NameEnumCallback& nameEnum

The callback object that may be used to record the name. See Class NameEnumCallback.

DWORD flags

One or more of the following values. See List of EnumAuxFiles Flags

Sample Code:

This is the default implementation provided by ReferenceMaker.

void ReferenceMaker::EnumAuxFiles(NameEnumCallback& nameEnum, DWORD flags) {

 for (int i=0; i<NumRefs(); i++) {

  ReferenceMaker *srm = GetReference(i);

  if (srm) srm->EnumAuxFiles(nameEnum,flags);

  }

 }

Prototype:

virtual int NumChildren()

Remarks:

This method is used internally.

Prototype:

virtual Animatable* ChildAnim(int i)

Remarks:

This method is used internally.

Prototype:

virtual TSTR NodeName();

Remarks:

This method is used internally.

The following methods deal with Note Tracks.

Prototype:

void AddNoteTrack(NoteTrack *note);

Remarks:

Implemented by the System.

This method adds the specified note track.

Parameters:

NoteTrack *note

The note track to add. The Note Tracks provided by 3ds max are derived from Class DefNoteTrack (which is derived from NoteTrack). See that class for the methods and data members used to access Note Tracks.

Prototype:

void DeleteNoteTrack(NoteTrack *note);

Remarks:

Implemented by the System.

This method deletes the specified note track.

Parameters:

NoteTrack *note

The note track to delete. The Note Tracks provided by 3ds max are derived from Class DefNoteTrack (which is derived from NoteTrack). See that class for the methods and data members used to access Note Tracks.

Prototype:

BOOL HasNoteTracks();

Remarks:

Implemented by the System.

This method returns TRUE if the track has note tracks; otherwise FALSE.

Prototype:

int NumNoteTracks();

Remarks:

Implemented by the System.

This method returns the number of note tracks.

Prototype:

NoteTrack *GetNoteTrack(int i);

Remarks:

Implemented by the System.

This method retrieves the 'i-th' note track.

Parameters:

int i

Specifies the note track to retrieve.

Return Value:

A pointer to a Note Track. The Note Tracks provided by 3ds max are derived from Class DefNoteTrack (which is derived from NoteTrack). See that class for the methods and data members used to access Note Tracks.

Parameter Block2 Methods

Prototype:

virtual int NumParamBlocks();

Remarks:

This method is available in release 3.0 and later only.

Implemented by the Plug-In.

This method returns the number of ParamBlock2s in this instance.

Default Implementation:

{ return 0; }

Prototype:

virtual IParamBlock2* GetParamBlock(int i);

Remarks:

This method is available in release 3.0 and later only.

Implemented by the Plug-In.

This method return 'i-th' ParamBlock2 in this instance (or NULL if not available).

Parameters:

int i

The zero based index of the ParamBlock2 to return.

Default Implementation:

{ return NULL; }

Prototype:

virtual IParamBlock2* GetParamBlockByID(short id);

Remarks:

This method is available in release 3.0 and later only.

Implemented by the Plug-In.

This method returns a pointer to the ParamBlock2 as specified by the ID passed (or NULL if not available).

Parameters:

short id

The BlockID of the ParamBlock2 instance.

Default Implementation:

{ return NULL; }

Schematic View Methods

Prototype:

bool SvSaveData(ISave *isave, USHORT id);

Remarks:

This method is available in release 3.0 and later only.

Implemented by the System.

This is the save method for schematic view data. For classes derived from ReferenceMaker, there is no need to call these. However, if you have a class derived from Animatable and it appears in the schematic view and you want to save schematic view properties for the object (node position, selection state, etc.) then you have to call this in your Save() method.

Parameters:

ISave *isave

An interface for saving data. See Class ISave.

USHORT id

The Chunk id (choosen by the developer).

Return Value:

Returns true if saved okay; otherwise false.

Prototype:

bool SvLoadData(ILoad *iLoad);

Remarks:

This method is available in release 3.0 and later only.

Implemented by the System.

This is the load method for schematic view data. For classes derived from ReferenceMaker, there is no need to call these. However, if you have a class derived from Animatable and it appears in the schematic view and you want to load schematic view properties for the object (node position, selection state, etc.) then you have to call this in your Load() method.

Parameters:

ILoad *iLoad

An interface for loading data. See Class ILoad.

Return Value:

Returns true if loaded okay; otherwise false.

Prototype:

virtual SvGraphNodeReference SvTraverseAnimGraph(IGraphObjectManager *gom, Animatable *owner, int id, DWORD flags);

Remarks:

This method is available in release 3.0 and later only.

This method traverses the graph of objects in the 3ds max scene, adding desired objects to the schematic view. Developers can specialize this behaviour by overriding this method and adding whatever objects are interesting to the schematic view. Objects are added to the schematic view by calling IGraphObjectManager::AddAnimatable(...). Reference lines are added to the schematic view by calling IGraphObjectManager::AddReference(...). Implementers of this method should call it recursively to process other objects in the scene.

See Class IGraphObjectManager.

Parameters:

IGraphObjectManager *gom

Points to the schematic view window manager.

Animatable *owner

The owning animatable.

int id

This is usually the sub-anim number (but can actually be any value the developer chooses).

DWORD flags

See List of Schematic View AddAnimatable Flags.

Return Value:

A SvGraphNodeReference object.

Prototype:

SvGraphNodeReference SvStdTraverseAnimGraph(IGraphObjectManager *gom, Animatable *owner, int id);

Remarks:

This method is available in release 3.0 and later only.

This method is a default graph traversal function which can be called from SvTraverseAnimGraph(...) above to handle graph traversal in simple cases. This traversal follows the sub-anim and child references. See the code below.

Parameters:

IGraphObjectManager *gom

Points to the schematic view window manager.

Animatable *owner

The owning animatable.

int id

This is usually the sub-anim number (but can actually be any value the developer chooses).

DWORD flags

See List of Schematic View AddAnimatable Flags.

Return Value:

A SvGraphNodeReference object.

Default Implementation:

// A default graph traversal function which can be

// called from SvTraverseAnimGraph(...) to handle

// graph traversal in simple cases. Follows sub-anim

// and child references...

SvGraphNodeReference Animatable::SvStdTraverseAnimGraph(IGraphObjectManager *gom, Animatable *owner, int id, DWORD flags) {

 int i;

 SvGraphNodeReference nodeRef;

 SvGraphNodeReference childNodeRef;

 gom->PushLevel(this);

 nodeRef = gom->AddAnimatable(this, owner, id, flags);

 if (nodeRef.stat == SVT_PROCEED) {

  for (i = 0; i < NumSubs(); i++) {

   if (SubAnim(i)) {

    childNodeRef = SubAnim(i)->SvTraverseAnimGraph(gom, this, i, flags);

    if (childNodeRef.stat != SVT_DO_NOT_PROCEED)

     gom->AddReference(nodeRef.gNode, childNodeRef.gNode, REFTYPE_SUBANIM);

    }

   }

  }

 gom->PopLevel();

 return nodeRef;

 }

Prototype:

virtual bool SvCanInitiateLink(IGraphObjectManager *gom, IGraphNode *gNode);

Remarks:

This method is available in release 3.0 and later only.

Returns true if this animatable can be the initiator of a link operation in the schematic view.

Parameters:

IGraphObjectManager *gom

Points to the schematic view window manager.

IGraphNode *gNode

Points to this node in the schematic view.

Prototype:

virtual bool SvCanConcludeLink(IGraphObjectManager *gom, IGraphNode *gNode, IGraphNode *initiatingGNode);

Remarks:

This method is available in release 3.0 and later only.

Returns true if this animatable can be the receiver (parent) of a link operation in the schematic view.

Parameters:

IGraphObjectManager *gom

Points to the schematic view window manager.

IGraphNode *gNode

Points to this node in the schematic view.

IGraphNode *initiatingGNode

Points to the child node in the schematic view.

Default Implementation:

{ return false; }

Prototype:

virtual TSTR SvGetName(IGraphObjectManager *gom, IGraphNode *gNode, bool isBeingEdited);

Remarks:

This method is available in release 3.0 and later only.

Returns the name of the object as it appears in the schematic view.

Parameters:

IGraphObjectManager *gom

Points to the schematic view window manager.

IGraphNode *gNode

Points to this node in the schematic view.

bool isBeingEdited

true if the item is being edited; false if not.

Default Implementation:

{

Animatable *owner;

int subNum;

TSTR name; 

owner = gNode->GetOwner();

subNum = gNode->GetID();

name = owner->SubAnimName(subNum);

return name;

}

Prototype:

virtual bool SvCanSetName(IGraphObjectManager *gom, IGraphNode *gNode);

Remarks:

This method is available in release 3.0 and later only.

Return true to permit the object's name to be edited in the schematic view.

Parameters:

IGraphObjectManager *gom

Points to the schematic view window manager.

IGraphNode *gNode

Points to this node in the schematic view.

Default Implementation:

{ return false; }

Prototype:

virtual bool SvSetName(IGraphObjectManager *gom, IGraphNode *gNode, TSTR &name);

Remarks:

This method is available in release 3.0 and later only.

Called when the user changes the name of the object in the schematic view.

Parameters:

IGraphObjectManager *gom

Points to the schematic view window manager.

IGraphNode *gNode

Points to this node in the schematic view.

TSTR &name

The new name to set.

Return Value:

true if the name was changed; false if not.

Prototype:

virtual bool SvCanRemoveThis(IGraphObjectManager *gom, IGraphNode *gNode);

Remarks:

This method is available in release 3.0 and later only.

Return true if this object can be removed in the schematic view; false if not.

Parameters:

IGraphObjectManager *gom

Points to the schematic view window manager.

IGraphNode *gNode

Points to this node in the schematic view.

Default Implementation:

{ return false; }

Prototype:

virtual bool SvRemoveThis(IGraphObjectManager *gom, IGraphNode *gNode);

Remarks:

This method is available in release 3.0 and later only.

This is called when the user deletes this object in the schematic view.

Parameters:

IGraphObjectManager *gom

Points to the schematic view window manager.

IGraphNode *gNode

Points to this node in the schematic view.

Return Value:

true if deleted; false if not.

Prototype:

virtual bool SvIsHighlighted(IGraphObjectManager *gom, IGraphNode *gNode);

Remarks:

This method is available in release 3.0 and later only.

Returns true if the object is to be highlighted in the schematic view; otherwise false.

Parameters:

IGraphObjectManager *gom

Points to the schematic view window manager.

IGraphNode *gNode

Points to this node in the schematic view.

Default Implementation:

{ return false; }

Prototype:

virtual COLORREF SvHighlightColor(IGraphObjectManager *gom, IGraphNode *gNode);

Remarks:

This method is available in release 3.0 and later only.

Returns the highlight color for this node. The highlight color is used to outline nodes in the schematic view when SvIsHighlighted(...) returns true.

Parameters:

IGraphObjectManager *gom

Points to the schematic view window manager.

IGraphNode *gNode

Points to this node in the schematic view.

Return Value:

See COLORREF-DWORD format.

Default Implementation:

{ return gom->SvGetUIColor(SV_UICLR_PLUGIN_HIGHLIGHT); }

Prototype:

virtual COLORREF SvGetSwatchColor(IGraphObjectManager *gom, IGraphNode *gNode);

Remarks:

This method is available in release 3.0 and later only.

Returns a color which is used to paint the triangular color swatch that appears in the upper-right hand corner of the node in the schematic view. One can return SV_NO_SWATCH to indicate that no swatch is to be drawn.

Parameters:

IGraphObjectManager *gom

Points to the schematic view window manager.

IGraphNode *gNode

Points to this node in the schematic view.

Return Value:

See COLORREF-DWORD format.

Default Implementation:

{ return SV_NO_SWATCH; }

Prototype:

virtual bool SvIsInactive(IGraphObjectManager *gom, IGraphNode *gNode);

Remarks:

This method is available in release 3.0 and later only.

Returns true if this object is inactive; false is active. The schematic view draws inactive nodes in a grayed-out state.

Parameters:

IGraphObjectManager *gom

Points to the schematic view window manager.

IGraphNode *gNode

Points to this node in the schematic view.

Default Implementation:

{ return false; }

Prototype:

virtual bool SvLinkChild(IGraphObjectManager *gom, IGraphNode *gNodeThis, IGraphNode *gNodeChild);

Remarks:

This method is available in release 3.0 and later only.

This method is called to link this object to the gNodeChild passed.

Parameters:

IGraphObjectManager *gom

Points to the schematic view window manager.

IGraphNode *gNodeThis

Points to this node in the schematic view.

IGraphNode *gNodeChild

Points to the child node in the schematic view.

Return Value:

true if linked; false if not.

Default Implementation:

{ return false; }

Prototype:

virtual bool SvHandleDoubleClick(IGraphObjectManager *gom, IGraphNode *gNode);

Remarks:

This method is available in release 3.0 and later only.

This method is called when this node is double-clicked in the schematic view.

Parameters:

IGraphObjectManager *gom

Points to the schematic view window manager.

IGraphNode *gNode

Points to the node in the schematic view.

Return Value:

true is handled; false if not interested in the event.

Default Implementation:

{ return false; }

Prototype:

virtual MultiSelectCallback* SvGetMultiSelectCallback(IGraphObjectManager *gom, IGraphNode *gNode);

Remarks:

This method is called before a multiple select/deselect operation in the schematic view. Returns a callback used to perform the (de)selection. May return NULL if this object cannot be selected in some principle editor outside the schematic view.

Parameters:

IGraphObjectManager *gom

Points to the schematic view window manager.

IGraphNode *gNode

Points to the node in the schematic view.

Return Value:

A pointer to the callback object. See Class MultiSelectCallback.

Default Implementation:

{ return NULL; }

Prototype:

virtual bool SvCanSelect(IGraphObjectManager *gom, IGraphNode *gNode);

Remarks:

Returns true if this object can be selected in some editor (viewport, material editor, plug-in specific editor, etc.). Selection is actually accomplished by via the SvGetMultiSelectCallback(...) mechanism described above.

Parameters:

IGraphObjectManager *gom

Points to the schematic view window manager.

IGraphNode *gNode

Points to the node in the schematic view.

Default Implementation:

{ return false; }

Prototype:

virtual bool SvEditProperties(IGraphObjectManager *gom, IGraphNode *gNode);

Remarks:

This method is available in release 3.0 and later only.

This method is reserved for future use.

Default Implementation:

{ return false; }

Prototype:

virtual TSTR SvGetTip(IGraphObjectManager *gom, IGraphNode *gNode);

Remarks:

This method is available in release 3.0 and later only.

Returns a string to be displayed in the tip window for this object in the schematic view.

Parameters:

IGraphObjectManager *gom

Points to the schematic view window manager.

IGraphNode *gNode

Points to the node in the schematic view.

Default Implementation:

{ return SvGetName(gom, gNode, false); }

Prototype:

virtual TSTR SvGetRefTip(IGraphObjectManager *gom, IGraphNode *gNode, IGraphNode *gNodeMaker);

Remarks:

Returns a string to be displayed in the tip window in the schematic view for a reference from "gNodeMaker" to this.

Parameters:

IGraphObjectManager *gom

Points to the schematic view window manager.

IGraphNode *gNode

Points to the node in the schematic view.

IGraphNode *gNodeMaker

Points to the 'maker' node in the schematic view.

Sample Code:

{ return gNodeMaker->GetAnim()->SvGetName(gom, gNodeMaker, false) + " -> " + SvGetName(gom, gNode, false); }

Prototype:

virtual bool SvCanDetach(IGraphObjectManager *gom, IGraphNode *gNode);

Remarks:

This method is available in release 3.0 and later only.

Returns true is this object can respond to the SvDetach(...) method; false if not.

Parameters:

IGraphObjectManager *gom

Points to the schematic view window manager.

IGraphNode *gNode

Points to the node in the schematic view.

Default Implementation:

{ return false; }

Prototype:

virtual bool SvDetach(IGraphObjectManager *gom, IGraphNode *gNode);

Remarks:

This method is available in release 3.0 and later only.

This method is called to detach this object from its owner.

Parameters:

IGraphObjectManager *gom

Points to the schematic view window manager.

IGraphNode *gNode

Points to the node in the schematic view.

Return Value:

Returns true if detached; otherwise false.

Default Implementation:

{ return false; }

Prototype:

DWORD SvGetRefIndex();

Remarks:

This method is available in release 3.0 and later only.

This method is for internal use only.

Prototype:

void SvSetRefIndex(DWORD i);

Remarks:

This method is available in release 3.0 and later only.

This method is for internal use only.

Prototype:

bool SvDeleteRefIndex();

Remarks:

This method is available in release 3.0 and later only.

This method is for internal use only.

Operators:

Prototype:

Animatable& operator=(const Animatable& an)

Remarks:

Implemented by the System.

Assignment operator.

The following function is not a part of class Animatable but is available for use with note tracks:

Prototype:

NoteTrack *NewDefaultNoteTrack();

Remarks:

Implemented by the System.

This function is used internally. It returns a new default note track.

Custom Attributes

Prototype:

ICustAttribContainer *GetCustAttribContainer();

Remarks:

This method is available in release 4.0 and later only.

This method returns a pointer to the custom attributes container interface class.

See Class ICustAttribContainer for more information.

 

Prototype:

void AllocCustAttribContainer();

Remarks:

This method is available in release 4.0 and later only.

This method allocates space for a custom attributes container.

Prototype:

void DeleteCustAttribContainer();

Remarks:

This method deletes space used by a custom attributes container.