iskin.h

Go to the documentation of this file.
00001  /**********************************************************************
00002  
00003     FILE: ISkin.h
00004 
00005     DESCRIPTION:  Skin Bone Deformer API
00006 
00007     CREATED BY: Nikolai Sander, Discreet
00008 
00009     HISTORY: 7/12/99
00010 
00011 
00012  *> Copyright (c) 1998, All Rights Reserved.
00013  **********************************************************************/
00014 
00015 #pragma once
00016 #include <WTypes.h>
00017 #include "maxheap.h"
00018 #include "ISkinCodes.h"
00019 #include "point3.h"
00020 #include "strbasic.h"
00021 #include "tab.h"
00022 #include "maxtypes.h"
00023 #include "ref.h"
00024 #include "iparamb2.h"
00025 #include "matrix3.h"
00026 
00027 // forward declarations
00028 class INode;
00029 class Matrix3;
00030 class BitArray;
00031 class ViewExp;
00032 class Box3;
00033 class ModContext;
00034 class GraphicsWindow;
00035 class HitRecord;
00036 class SubObjAxisCallback;
00037 
00038 #define I_SKIN 0x00010000
00039 #define I_SKINIMPORTDATA 0x00020000
00040 
00041 //New interface for max 6
00042 #define I_SKIN2 0x00030000
00043 
00044 #define I_GIZMO 9815854
00045 //Gizmo interface for r5 additions
00046 #define I_GIZMO2 9815855
00047 //Gizmo interface for r5.1 additions
00048 #define I_GIZMO3 9815856
00049 
00050 #define SKIN_INVALID_NODE_PTR 0
00051 #define SKIN_OK               1
00052 
00053 //#define SKIN_CLASSID Class_ID(0x68477bb4, 0x28cf6b86)
00054 #define SKIN_CLASSID Class_ID(9815843,87654)
00055 
00056 #pragma warning(push)
00057 #pragma warning(disable:4100)
00058 
00059 
00067 class ISkinContextData: public MaxHeapOperators
00068 {
00069 public:
00071     virtual ~ISkinContextData() {}
00074     virtual int GetNumPoints()=0;
00080     virtual int GetNumAssignedBones(int vertexIdx)=0;
00088     virtual int GetAssignedBone(int vertexIdx, int boneIdx)=0;
00095     virtual float GetBoneWeight(int vertexIdx, int boneIdx)=0;
00096     
00097     // These are only used for Spline animation
00105     virtual int GetSubCurveIndex(int vertexIdx, int boneIdx)=0;
00113     virtual int GetSubSegmentIndex(int vertexIdx, int boneIdx)=0;
00121     virtual float GetSubSegmentDistance(int vertexIdx, int boneIdx)=0;
00128     virtual Point3 GetTangent(int vertexIdx, int boneIdx)=0;
00136     virtual Point3 GetOPoint(int vertexIdx, int boneIdx)=0;
00137 
00138 };
00139 
00144 class ISkin: public MaxHeapOperators 
00145 {
00146 public:
00148     virtual ~ISkin() {}
00161     virtual int GetBoneInitTM(INode *pNode, Matrix3 &InitTM, bool bObjOffset = false)=0;
00174     virtual int GetSkinInitTM(INode *pNode, Matrix3 &InitTM, bool bObjOffset = false)=0;
00177     virtual int GetNumBones()=0;
00185     virtual INode *GetBone(int idx)=0;
00209     virtual DWORD GetBoneProperty(int idx)=0;
00215     virtual ISkinContextData *GetContextInterface(INode *pNode)=0;
00216 //new stuff
00224     virtual MCHAR *GetBoneName(int index) = 0;
00226     virtual int GetSelectedBone() = 0;
00228     virtual void UpdateGizmoList() = 0;
00241     virtual void GetEndPoints(int id, Point3 &l1, Point3 &l2) = 0;
00246     virtual Matrix3 GetBoneTm(int id) = 0;
00254     virtual INode *GetBoneFlat(int idx)=0;
00257     virtual int GetNumBonesFlat()=0;
00259     virtual int GetRefFrame()=0;
00260 
00261 };
00262 
00263 
00264 // The following {class, member, macro, flag} has been added
00265 // in 3ds max 4.2.  If your plugin utilizes this new
00266 // mechanism, be sure that your clients are aware that they
00267 // must run your plugin with 3ds max version 4.2 or higher.
00268 
00269 
00278 class ISkinImportData: public MaxHeapOperators
00279 {
00280 public:
00281 
00283     virtual ~ISkinImportData() {}
00284 
00285 /*** BOOL AddBoneEx(INode *node, BOOL update) ***/
00286 /*
00287 INode *node the bone to be added to skin
00288 BOOL update is used to update the UI
00289 
00290  Adds a bone to the skin system.  Return TRUE if the operation succeeded.
00291 */
00302     virtual BOOL AddBoneEx(INode *boneNode, BOOL update)=0;
00303 
00304 
00305 
00306 /**** virtual BOOL SetSkinBaseTm(INode *skinNode, Matrix3 tm) ***/
00307 /*
00308 INode *boneNode is that node that skin is applied to, need this so I can extract the local mod data
00309 Matrix3 objectTm is the object matrix to assign as the new skin object tm
00310 Matrix3 nodeTm is the node matrix to assign as the new skin node tm
00311 
00312 When skin is applied to a node, that nodes initial objecttm is stored off so we can recompute the initial position
00313 of the skin object.  This function allows you to change that tm.  It will store tm and the inverse tm of the 
00314 matrix passed to it.  Return TRUE if the operation succeeded.
00315 
00316 Below is the actual code that computes this when skin is added (node is the node that skin is applied to)
00317                 d->BaseTM = node->GetObjectTM(RefFrame);
00318                 d->BaseNodeTM = node->GetNodeTM(RefFrame); //ns
00319                 d->InverseBaseTM = Inverse(d->BaseTM);
00320 */
00336     virtual BOOL SetSkinTm(INode *skinNode, Matrix3 objectTm, Matrix3 nodeTm)=0;
00337 
00338 
00339 /**** virtual BOOL SetBoneTm(INode *boneNode, Matrix3 objectTm, Matrix3 nodeTm) ***/
00340 /*
00341 INode *boneNode is the pointer to the bone that is having its initial matrix change
00342 Matrix3 objectTm is the object matrix to assign as the new skin object tm
00343 Matrix3 nodeTm is the node matrix to assign as the new skin node tm
00344 
00345 When a bone is added to skin it stores off the initial object and node tm of that bone.  This function allows 
00346 you to change the intial matrix of a particular bone. Return TRUE if the operation succeeded.
00347 
00348 Below is the actual code from skin that is called when a bone is added (t.node is the node of the bone being added)
00349 
00350             Matrix3 otm = t.Node->GetObjectTM(RefFrame);  //ns  
00351             Matrix3 ntm = t.Node->GetStretchTM(RefFrame) * t.Node->GetNodeTM(RefFrame); 
00352     
00353             BoneData[current].InitObjectTM = otm;       //ns
00354             BoneData[current].InitNodeTM = ntm;
00355             BoneData[current].tm    = Inverse(otm);
00356 */
00371     virtual BOOL SetBoneTm(INode *boneNode, Matrix3 objectTm, Matrix3 nodeTm)=0;
00372 
00373 
00374 
00375 /*** BOOL AddWeights(INode *skinNode, int vertexID, Tab<INode*> &boneNodeList, Tab<float> &weights) ***/
00376 /*
00377 INode *skinNode  is the node that has skin applied to it, need this so I can get the local mod data for that node and skin since the same modifier can be applied to mulitple nodes thhrough instancing
00378 int vertexID is the index of the vertex that you want to apply weights to
00379 Tab<INode*> &boneNodeList is the list of bones that will control the vertex, these must already be added to the skin modifier
00380 Tab<float> &weights is the weight of each bone
00381 */
00400     virtual BOOL AddWeights(INode* skinNode, int vertexID, Tab<INode*>& boneNodeList, Tab<float>& weights)=0;
00401 };
00402 
00403 
00404 // End of 3ds max 4.2 Extension
00405 
00406 //New For Max6
00407 //this exposes the initial stretch matrix that a bone as since we seperated this out from the base
00408 //matrix so we could turn it off.
00409 
00419 class ISkin2: public MaxHeapOperators
00420 {
00421 public:
00423     virtual ~ISkin2() {}
00431     virtual BOOL SetBoneStretchTm(INode *boneNode, Matrix3 stretchTm)=0;
00432 
00436     virtual Matrix3 GetBoneStretchTm(INode *boneNode)=0;
00437 
00441     virtual void GetVertexSelection(INode *skinNode, BitArray &sel) = 0;
00442 
00446     virtual void SetVertexSelection(INode *skinNode, BitArray &sel) = 0;
00447 };
00448 
00457 class IGizmoBuffer: public MaxHeapOperators
00458 {
00459 public:
00460     Class_ID cid;
00462     virtual ~IGizmoBuffer() {}
00466     virtual void DeleteThis()=0;
00467 
00468 };
00469 
00470 
00492 class GizmoClass : public ReferenceTarget
00493 {
00494 // all the refernce stuff and paramblock stuff here
00495 public:
00496 
00497     ISkin *bonesMod;
00498     IParamBlock2 *pblock_gizmo_data;
00499 
00500     GizmoClass() { pblock_gizmo_data = NULL; bonesMod = NULL; }
00504     int NumParamBlocks() { return 1; }
00510     IParamBlock2* GetParamBlock(int i)
00511                 {
00512                 if (i == 0) return pblock_gizmo_data;
00513                 else return NULL;
00514                 }
00520     IParamBlock2* GetParamBlockByID(BlockID id)
00521                 {
00522                 if (pblock_gizmo_data->ID() == id) return pblock_gizmo_data ;
00523                  else return  NULL; 
00524                  }
00525 
00526     int NumRefs() {return 1;}
00527     RefTargetHandle GetReference(int i)
00528         {
00529         if (i==0)
00530             {
00531             return (RefTargetHandle)pblock_gizmo_data;
00532             }
00533         return NULL;
00534         }
00535 
00536 protected:
00537     virtual void SetReference(int i, RefTargetHandle rtarg)
00538         {
00539         if (i==0)
00540             {
00541             pblock_gizmo_data = (IParamBlock2*)rtarg;
00542             }
00543         }
00544 public:
00546     void DeleteThis()=0;
00547 
00548 
00549     int NumSubs() {return 1;}
00550     Animatable* SubAnim(int i) { return GetReference(i);}
00551  
00552 
00553     MSTR SubAnimName(int i) {return _M(""); }
00554 
00555     int SubNumToRefNum(int subNum) {return -1;}
00556 
00557     RefResult NotifyRefChanged( Interval changeInt,RefTargetHandle hTarget, 
00558            PartID& partID, RefMessage message)  
00559         {
00560         return REF_SUCCEED;
00561         }
00562 
00563     virtual void BeginEditParams(IObjParam  *ip, ULONG flags,Animatable *prev) {}
00564     virtual void EndEditParams(IObjParam *ip,ULONG flags,Animatable *next) {}         
00565     virtual IOResult Load(ILoad *iload) {return IO_OK;}
00566     virtual IOResult Save(ISave *isave) {return IO_OK;}
00567 
00568 //  void* GetInterface(ULONG id);  
00569 
00570 //this retrieves the boudng bx of the gizmo in world space
00571     virtual void GetWorldBoundBox(TimeValue t,INode* inode, ViewExp *vpt, Box3& box, ModContext *mc){}               
00572 // this called in the bonesdef display code to show the gizmo
00573     virtual int Display(TimeValue t, GraphicsWindow *gw, Matrix3 tm ) { return 1;}
00574     virtual Interval LocalValidity(TimeValue t) {return FOREVER;}
00578     virtual BOOL IsEnabled() { return TRUE; }
00584     virtual BOOL IsVolumeBased() {return FALSE;}
00594     virtual BOOL IsInVolume(Point3 p, Matrix3 tm) { return FALSE;}
00595 
00596 //this is what deforms the point
00597 // this is passed in from the Map call in bones def
00616     virtual  Point3 DeformPoint(TimeValue t, int index, Point3 initialP, Point3 p, Matrix3 tm)
00617         {return p;}
00618 //this is the suggested name that the gizmo should be called in the list
00622     virtual void SetInitialName() {}
00623 //this is the final name of the gizmo in th list
00627     virtual const MCHAR *GetName(){return NULL;}
00628 //this sets the final name of the gizmo in the list
00635     virtual void SetName(const MCHAR *name) {}
00636 
00638     virtual void SetName(MCHAR *name) { SetName(const_cast<const MCHAR*>(name)); }
00639 
00640 // this is called when the gizmo is initially created
00641 // it is passed to the current selected verts in the world space
00642     //count is the number of vertice in *p
00643     //*p is the list of point being affected in world space
00644     //numberOfInstances is the number of times this modifier has been instanced
00645     //mapTable is an index list into the original vertex table for *p
00665     virtual BOOL InitialCreation(int count, Point3 *p, int numbeOfInstances, int *mapTable) { return TRUE;}
00666 //this is called before the deformation on a frame to allow the gizmo to do some
00667 //initial setupo
00675     virtual void PreDeformSetup(TimeValue t) {}
00683     virtual void PostDeformSetup(TimeValue t) {}
00684 
00690     virtual IGizmoBuffer *CopyToBuffer() { return NULL;}
00699     virtual void PasteFromBuffer(IGizmoBuffer *buffer) {}
00700 
00707     virtual void Enable(BOOL enable) {}
00714     virtual BOOL IsEditing() { return FALSE;}
00718     virtual void EndEditing() {}
00728     virtual void EnableEditing(BOOL enable) {}
00729 
00730 // From BaseObject
00758     virtual int HitTest(TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt, ModContext* mc, Matrix3 tm) {return 0;}
00780     virtual void SelectSubComponent(HitRecord *hitRec, BOOL selected, BOOL all, BOOL invert=FALSE) {}
00806     virtual void Move( TimeValue t, Matrix3& partm, Matrix3& tmAxis, Point3& val, Matrix3 tm, BOOL localOrigin=FALSE ) {}
00826     virtual void GetSubObjectCenters(SubObjAxisCallback *cb,TimeValue t,INode *node, Matrix3 tm) {}
00847     virtual void GetSubObjectTMs(SubObjAxisCallback *cb,TimeValue t,INode *node, Matrix3 tm) {}
00856     virtual void ClearSelection(int selLevel) {}
00865     virtual void SelectAll(int selLevel) {}
00875     virtual void InvertSelection(int selLevel) {}
00876 };
00877 
00878 #pragma warning(pop)
00879 
00880     
00881 //Gizmo extensions for R5
00882 class IGizmoClass2: public MaxHeapOperators 
00883     {
00884 public:
00885     virtual ~IGizmoClass2() {}
00886 
00887     //this lets skin pass some tms to the gizmo so they can deal with the double transform
00888     //when the skin object and the skeleton are linked to the same node and that node is moved there will be a double transformation
00889     //in R5 we have an option to remove that transformation,
00890 
00891     //points come into the gizmo with the double trsansform on, this lets the gizmo remove and put back the transfrom
00892     //skin expects the points to have the double transform when it gets the points back from the gizmo since it willl
00893     //remove it later on
00894     //removeDoubleTransform - is a matrix3 that will remove the double transform
00895     //putbackDoubleTransform - is a matrix3 that will putback the double transform
00896     virtual void SetBackTransFormMatrices(Matrix3 removeDoubleTransform, Matrix3 putbackDoubleTransform) = 0;
00897     };
00898 
00899 
00900 //Gizmo extensions for R5.1
00901 class IGizmoClass3: public MaxHeapOperators 
00902     {
00903 public:
00904     virtual ~IGizmoClass3() {}
00905     //This exposes a tool that lets the gizmo know that the user wants to reset the plane of rotation using
00906     //the current bone orientation to define the plabe
00907     virtual void ResetRotationPlane()=0;
00908     };
00909 
00910