| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405 |
- /*
- ** Command & Conquer Renegade(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : Commando Tools - WWSkin *
- * *
- * $Archive:: /Commando/Code/Tools/max2w3d/skin.h $*
- * *
- * $Author:: Moumine_ballo $*
- * *
- * $Modtime:: 2/21/02 4:41p $*
- * *
- * $Revision:: 9 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #ifndef SKIN_H
- #define SKIN_H
- #include <Max.h>
- #include "simpmod.h"
- #include "simpobj.h"
- #include "bpick.h"
- #include "namedsel.h"
- #include "w3d_file.h"
- #define SKIN_OBJ_CLASS_ID Class_ID(0x32b37e0c, 0x5a9612e4)
- #define SKIN_MOD_CLASS_ID Class_ID(0x6bad4898, 0x0d1d6ced)
- extern ClassDesc * Get_Skin_Obj_Desc();
- extern ClassDesc * Get_Skin_Mod_Desc();
- /*
- Writing a space warp plug-in involves creating instances of two key classes.
- One is derived from class WSMObject. (WSMObject stands for Word Space Modifier Object,
- just another name for Space Warp Object). The other class is subclassed off Modifier.
- These two classes work together. The space warp object handles the display and management
- of its user interface parameters, the display of the space warp node in the scene, and
- provides a world space orientation. The space warp modifier handles the actual deformation
- of the geometry of nodes bound to the space warp. Each node bound to the space warp
- will have a ModContext which we will store data in.
- The following class is the WSMObject for the westwood skin modifier.
- */
- class SkinWSMObjectClass : public SimpleWSMObject, BonePickerUserClass
- {
- public:
- SkinWSMObjectClass();
- virtual ~SkinWSMObjectClass();
- /*
- ** From Animatable
- */
- void DeleteThis() { OutputDebugString("Deleting SkinWSMObjectClass");delete this; }
- void BeginEditParams(IObjParam *ip, ULONG flags,Animatable *prev);
- void EndEditParams(IObjParam *ip, ULONG flags,Animatable *next);
- TCHAR * GetObjectName() { return _T("WWSkin"); }
- Class_ID ClassID() { return SKIN_OBJ_CLASS_ID; }
-
- /*
- ** From ReferenceTarget
- */
- RefTargetHandle Clone(RemapDir& remap = NoRemap());
- /*
- ** From Reference Maker. These three functions give access to the "virtual array" of references.
- ** For SkinWSMObjectClass, we have to remember that SimpleWSMObject already has a reference
- ** so we are taking ours on after
- */
- virtual int NumRefs() { return SimpleWSMObject::NumRefs() + Num_Bones();}
- virtual RefTargetHandle GetReference(int i);
- virtual void SetReference(int i, RefTargetHandle rtarg);
- RefResult NotifyRefChanged(Interval changeInt,RefTargetHandle hTarget,PartID& partID, RefMessage message);
- /*
- ** From Object
- */
- int DoOwnSelectHilite() { return TRUE; }
- CreateMouseCallBack * GetCreateMouseCallBack();
- /*
- ** From WSMObject
- */
- Modifier *CreateWSMMod(INode *node);
- /*
- ** From SimpleWSMObject
- */
- void BuildMesh(TimeValue t);
- /*
- ** Setup a triangle
- */
- void Build_Tri(Face * f, int a, int b, int c);
-
- /*
- ** Dialog box message processing
- */
- BOOL SkinWSMObjectClass::Skeleton_Dialog_Proc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
-
- /*
- ** Bone picking.
- */
- virtual void User_Picked_Bone(INode * node);
- virtual void User_Picked_Bones(INodeTab & nodetab);
- void Set_Bone_Selection_Mode(int mode);
-
- int Add_Bone(INode * node);
- void Add_Bones(INodeTab & nodetab);
- void Remove_Bone(INode * node);
- void Remove_Bones(INodeTab & nodetab);
- void Update_Bone_List(void);
- /*
- ** Converting between bone indexes and reference indexes
- ** The bone references are a variable number of references which are
- ** added at the end of the reference array.
- */
- int To_Bone_Index(int refidx) { return refidx - SimpleWSMObject::NumRefs(); }
- int To_Ref_Index(int boneidx) { return SimpleWSMObject::NumRefs() + boneidx; }
-
- /*
- ** External access to the bones
- */
- int Num_Bones(void) { return BoneTab.Count(); }
- INode * Get_Bone(int idx) { return BoneTab[idx]; }
- INodeTab & Get_Bone_List(void) { return BoneTab; }
- int Find_Bone(INode * node);
- int Get_Base_Pose_Frame(void) { return BasePoseFrame; }
- int Get_Base_Pose_Time(void) { return BasePoseFrame * GetTicksPerFrame(); }
- int Find_Closest_Bone(const Point3 & vertex);
- /*
- ** Saving and loading.
- */
- IOResult Save(ISave *isave);
- IOResult Load(ILoad *iload);
- /*
- ** Static UI variables. These have to be static due to the strange way
- ** that MAX behaves during creation of objects. If you create an object
- ** then delete it, EndEditParams is not called and its destructor isn't called...
- */
- static HWND SotHWND;
- static HWND SkeletonHWND;
- static HWND BoneListHWND;
- static IObjParam * InterfacePtr;
- static ICustButton * AddBonesButton;
- static ICustButton * RemoveBonesButton;
- static ISpinnerControl * BasePoseSpin;
- /*
- ** flag for whether we need to build the bones mesh for this object
- */
- BOOL MeshBuilt;
- /*
- ** Bone Selection!
- */
- enum {
- BONE_SEL_MODE_NONE = 0,
- BONE_SEL_MODE_ADD,
- BONE_SEL_MODE_REMOVE,
- BONE_SEL_MODE_ADD_MANY,
- BONE_SEL_MODE_REMOVE_MANY
- };
- int BoneSelectionMode;
- INodeTab BoneTab;
- /*
- ** Dialog controls
- */
- int BasePoseFrame;
- /*
- ** Chunk ID's
- */
- enum {
- NUM_BONES_CHUNK = 0x0001
- };
-
- /*
- ** Friend functions
- */
- friend BOOL CALLBACK _skeleton_dialog_thunk(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
- };
- /*
- ** SkinModifierClass
- */
- class SkinModifierClass : public Modifier, BonePickerUserClass
- {
- public:
- SkinModifierClass(void);
- SkinModifierClass(INode * node,SkinWSMObjectClass * skin_obj);
- #if defined W3D_MAX4 //defined as in the project (.dsp)
- ISubObjType *GetSubObjType(int i);
- int NumSubObjTypes();
- #endif
- void Default_Init(void);
- /*
- ** From Animatable
- */
- void DeleteThis() { delete this; }
- void GetClassName(TSTR& s) { s = TSTR(_T("WWSkin")); }
- TCHAR * GetObjectName() { return _T("WWSkin Binding"); }
- SClass_ID SuperClassID() { return WSM_CLASS_ID; }
- Class_ID ClassID() { return SKIN_MOD_CLASS_ID; }
- RefTargetHandle Clone(RemapDir& remap = NoRemap());
- RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message);
- void BeginEditParams(IObjParam *ip, ULONG flags,Animatable *prev);
- void EndEditParams(IObjParam *ip, ULONG flags,Animatable *next);
- CreateMouseCallBack * GetCreateMouseCallBack() { return NULL; }
- /*
- ** From Reference Maker. These three functions give access to the "virtual array" of references.
- */
- int NumRefs() { return 2; }
- RefTargetHandle GetReference(int i);
- void SetReference(int i, RefTargetHandle rtarg);
- /*
- ** Tell MAX what channels we use and what channels we change:
- ** Note that if we do not tell max that we use a channel, that channel is not
- ** guaranteed to be valid.
- */
- virtual ChannelMask ChannelsUsed() { return SELECT_CHANNEL|SUBSEL_TYPE_CHANNEL|GEOM_CHANNEL; }
- virtual ChannelMask ChannelsChanged() { return SELECT_CHANNEL|SUBSEL_TYPE_CHANNEL|GEOM_CHANNEL; }
- /*
- ** MAX tells us whenever an input changed. If we cache anything, we can use this
- ** function to dump the cached data and regenerate it.
- */
- virtual void NotifyInputChanged(Interval changeInt, PartID partID, RefMessage message, ModContext *mc) {}
- /*
- ** This is where the modifier actually modifies the object!
- */
- virtual void ModifyObject(TimeValue t, ModContext & mc, ObjectState * os, INode * node);
- /*
- ** Since our modifier will be storing information based on the vertex indices, whenever
- ** the topology of its input is changed things will no longer work correctly. Therefore,
- ** we tell max that we depend on the topology remaining the same.
- */
- virtual BOOL DependOnTopology(ModContext &mc) { return TRUE; }
- /*
- ** What types of objects can we modify: The skin modifier will only work with TRIOBJ's
- */
- virtual Class_ID InputType() { return Class_ID(TRIOBJ_CLASS_ID,0); }
- /*
- ** Saving and loading. Remember to call the base class's save and load functions as well.
- */
- IOResult Save(ISave *isave);
- IOResult Load(ILoad *iload);
- virtual IOResult LoadLocalData(ILoad *iload, LocalModData **pld);
- virtual IOResult SaveLocalData(ISave *isave, LocalModData *ld);
-
- /*
- ** For SkinModifierClass, we allow vertex sub-object selection.
- ** This function notifies an object being edited that the current sub object
- ** selection level has changed. level==0 indicates object level selection.
- ** level==1 or greater refer to the types registered by the object in the
- ** order they appeared in the list when registered. If level >= 1, the object
- ** should specify sub-object xform modes in the modes structure (defined in cmdmode.h).
- */
- void ActivateSubobjSel(int level, XFormModes& modes);
- int HitTest(TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt, ModContext* mc);
- void SelectSubComponent(HitRecord *hitRec, BOOL selected, BOOL all, BOOL invert=FALSE);
- void ClearSelection(int selLevel);//
- void SelectAll(int selLevel);
- void InvertSelection(int selLevel);
- /*
- ** An object that supports sub-object selection can choose to
- ** support named sub object selection sets. Methods in the the
- ** interface passed to objects allow them to add items to the
- ** sub-object selection set drop down.
- ** The following methods implement named sub-obj selection sets
- */
- virtual BOOL SupportsNamedSubSels() { return TRUE; }
- virtual void ActivateSubSelSet(TSTR &setName);
- virtual void NewSetFromCurSel(TSTR &setName);
- virtual void RemoveSubSelSet(TSTR &setName);
- void Create_Named_Selection_Sets(void);
- void Install_Named_Selection_Sets(void);
- WSMObject * Get_WSMObject(void) { return (WSMObject*)GetReference(OBJ_REF); }
- Interval Get_Validity(TimeValue t);
-
- /*
- ** Bone picking
- */
- virtual void User_Picked_Bone(INode * node);
- virtual void User_Picked_Bones(INodeTab & nodetab);
- /*
- ** Auto-Attach vertices to nearest bone
- */
- void Auto_Attach_Verts(BOOL all = FALSE);
-
- /*
- ** Unlink selected verts (links them to the root or origin)
- */
- void Unlink_Verts(void);
- private:
-
- /*
- ** Windows dialog management and communication functions
- */
- void Install_Bone_Influence_Dialog(void);
- void Remove_Bone_Influence_Dialog(void);
- BOOL Bone_Influence_Dialog_Proc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
-
- public:
- /*
- ** References for SkinModifierClass
- */
- enum {
- OBJ_REF = 0,
- NODE_REF = 1
- };
- SkinWSMObjectClass * WSMObjectRef;
- INode * WSMNodeRef;
- /*
- ** Sub-Object Selection variables
- */
- enum {
- OBJECT_SEL_LEVEL = 0,
- VERTEX_SEL_LEVEL = 1
- };
- int SubObjSelLevel;
- /*
- ** Bone Influence Dialog panel variables
- */
- HWND BoneInfluenceHWND;
- ICustButton * LinkButton;
- ICustButton * LinkByNameButton;
- ICustButton * AutoLinkButton;
- ICustButton * UnLinkButton;
-
- /*
- ** Cached pointers to some MAX objects
- */
- IObjParam * InterfacePtr;
- SelectModBoxCMode * SelectMode;
- /*
- ** Load/Save Chunk ID's
- */
- enum {
- SEL_LEVEL_CHUNK = 0xAA01,
- };
- /*
- ** Friend "thunking" functions for the dialog handling.
- */
- friend BOOL CALLBACK _bone_influence_dialog_thunk(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
- };
- #endif
|