skin.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** 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 ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Commando Tools - WWSkin *
  23. * *
  24. * $Archive:: /Commando/Code/Tools/max2w3d/skin.h $*
  25. * *
  26. * $Author:: Moumine_ballo $*
  27. * *
  28. * $Modtime:: 2/21/02 4:41p $*
  29. * *
  30. * $Revision:: 9 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #ifndef SKIN_H
  36. #define SKIN_H
  37. #include <Max.h>
  38. #include "simpmod.h"
  39. #include "simpobj.h"
  40. #include "bpick.h"
  41. #include "namedsel.h"
  42. #include "w3d_file.h"
  43. #define SKIN_OBJ_CLASS_ID Class_ID(0x32b37e0c, 0x5a9612e4)
  44. #define SKIN_MOD_CLASS_ID Class_ID(0x6bad4898, 0x0d1d6ced)
  45. extern ClassDesc * Get_Skin_Obj_Desc();
  46. extern ClassDesc * Get_Skin_Mod_Desc();
  47. /*
  48. Writing a space warp plug-in involves creating instances of two key classes.
  49. One is derived from class WSMObject. (WSMObject stands for Word Space Modifier Object,
  50. just another name for Space Warp Object). The other class is subclassed off Modifier.
  51. These two classes work together. The space warp object handles the display and management
  52. of its user interface parameters, the display of the space warp node in the scene, and
  53. provides a world space orientation. The space warp modifier handles the actual deformation
  54. of the geometry of nodes bound to the space warp. Each node bound to the space warp
  55. will have a ModContext which we will store data in.
  56. The following class is the WSMObject for the westwood skin modifier.
  57. */
  58. class SkinWSMObjectClass : public SimpleWSMObject, BonePickerUserClass
  59. {
  60. public:
  61. SkinWSMObjectClass();
  62. virtual ~SkinWSMObjectClass();
  63. /*
  64. ** From Animatable
  65. */
  66. void DeleteThis() { OutputDebugString("Deleting SkinWSMObjectClass");delete this; }
  67. void BeginEditParams(IObjParam *ip, ULONG flags,Animatable *prev);
  68. void EndEditParams(IObjParam *ip, ULONG flags,Animatable *next);
  69. TCHAR * GetObjectName() { return _T("WWSkin"); }
  70. Class_ID ClassID() { return SKIN_OBJ_CLASS_ID; }
  71. /*
  72. ** From ReferenceTarget
  73. */
  74. RefTargetHandle Clone(RemapDir& remap = NoRemap());
  75. /*
  76. ** From Reference Maker. These three functions give access to the "virtual array" of references.
  77. ** For SkinWSMObjectClass, we have to remember that SimpleWSMObject already has a reference
  78. ** so we are taking ours on after
  79. */
  80. virtual int NumRefs() { return SimpleWSMObject::NumRefs() + Num_Bones();}
  81. virtual RefTargetHandle GetReference(int i);
  82. virtual void SetReference(int i, RefTargetHandle rtarg);
  83. RefResult NotifyRefChanged(Interval changeInt,RefTargetHandle hTarget,PartID& partID, RefMessage message);
  84. /*
  85. ** From Object
  86. */
  87. int DoOwnSelectHilite() { return TRUE; }
  88. CreateMouseCallBack * GetCreateMouseCallBack();
  89. /*
  90. ** From WSMObject
  91. */
  92. Modifier *CreateWSMMod(INode *node);
  93. /*
  94. ** From SimpleWSMObject
  95. */
  96. void BuildMesh(TimeValue t);
  97. /*
  98. ** Setup a triangle
  99. */
  100. void Build_Tri(Face * f, int a, int b, int c);
  101. /*
  102. ** Dialog box message processing
  103. */
  104. BOOL SkinWSMObjectClass::Skeleton_Dialog_Proc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
  105. /*
  106. ** Bone picking.
  107. */
  108. virtual void User_Picked_Bone(INode * node);
  109. virtual void User_Picked_Bones(INodeTab & nodetab);
  110. void Set_Bone_Selection_Mode(int mode);
  111. int Add_Bone(INode * node);
  112. void Add_Bones(INodeTab & nodetab);
  113. void Remove_Bone(INode * node);
  114. void Remove_Bones(INodeTab & nodetab);
  115. void Update_Bone_List(void);
  116. /*
  117. ** Converting between bone indexes and reference indexes
  118. ** The bone references are a variable number of references which are
  119. ** added at the end of the reference array.
  120. */
  121. int To_Bone_Index(int refidx) { return refidx - SimpleWSMObject::NumRefs(); }
  122. int To_Ref_Index(int boneidx) { return SimpleWSMObject::NumRefs() + boneidx; }
  123. /*
  124. ** External access to the bones
  125. */
  126. int Num_Bones(void) { return BoneTab.Count(); }
  127. INode * Get_Bone(int idx) { return BoneTab[idx]; }
  128. INodeTab & Get_Bone_List(void) { return BoneTab; }
  129. int Find_Bone(INode * node);
  130. int Get_Base_Pose_Frame(void) { return BasePoseFrame; }
  131. int Get_Base_Pose_Time(void) { return BasePoseFrame * GetTicksPerFrame(); }
  132. int Find_Closest_Bone(const Point3 & vertex);
  133. /*
  134. ** Saving and loading.
  135. */
  136. IOResult Save(ISave *isave);
  137. IOResult Load(ILoad *iload);
  138. /*
  139. ** Static UI variables. These have to be static due to the strange way
  140. ** that MAX behaves during creation of objects. If you create an object
  141. ** then delete it, EndEditParams is not called and its destructor isn't called...
  142. */
  143. static HWND SotHWND;
  144. static HWND SkeletonHWND;
  145. static HWND BoneListHWND;
  146. static IObjParam * InterfacePtr;
  147. static ICustButton * AddBonesButton;
  148. static ICustButton * RemoveBonesButton;
  149. static ISpinnerControl * BasePoseSpin;
  150. /*
  151. ** flag for whether we need to build the bones mesh for this object
  152. */
  153. BOOL MeshBuilt;
  154. /*
  155. ** Bone Selection!
  156. */
  157. enum {
  158. BONE_SEL_MODE_NONE = 0,
  159. BONE_SEL_MODE_ADD,
  160. BONE_SEL_MODE_REMOVE,
  161. BONE_SEL_MODE_ADD_MANY,
  162. BONE_SEL_MODE_REMOVE_MANY
  163. };
  164. int BoneSelectionMode;
  165. INodeTab BoneTab;
  166. /*
  167. ** Dialog controls
  168. */
  169. int BasePoseFrame;
  170. /*
  171. ** Chunk ID's
  172. */
  173. enum {
  174. NUM_BONES_CHUNK = 0x0001
  175. };
  176. /*
  177. ** Friend functions
  178. */
  179. friend BOOL CALLBACK _skeleton_dialog_thunk(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
  180. };
  181. /*
  182. ** SkinModifierClass
  183. */
  184. class SkinModifierClass : public Modifier, BonePickerUserClass
  185. {
  186. public:
  187. SkinModifierClass(void);
  188. SkinModifierClass(INode * node,SkinWSMObjectClass * skin_obj);
  189. #if defined W3D_MAX4 //defined as in the project (.dsp)
  190. ISubObjType *GetSubObjType(int i);
  191. int NumSubObjTypes();
  192. #endif
  193. void Default_Init(void);
  194. /*
  195. ** From Animatable
  196. */
  197. void DeleteThis() { delete this; }
  198. void GetClassName(TSTR& s) { s = TSTR(_T("WWSkin")); }
  199. TCHAR * GetObjectName() { return _T("WWSkin Binding"); }
  200. SClass_ID SuperClassID() { return WSM_CLASS_ID; }
  201. Class_ID ClassID() { return SKIN_MOD_CLASS_ID; }
  202. RefTargetHandle Clone(RemapDir& remap = NoRemap());
  203. RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message);
  204. void BeginEditParams(IObjParam *ip, ULONG flags,Animatable *prev);
  205. void EndEditParams(IObjParam *ip, ULONG flags,Animatable *next);
  206. CreateMouseCallBack * GetCreateMouseCallBack() { return NULL; }
  207. /*
  208. ** From Reference Maker. These three functions give access to the "virtual array" of references.
  209. */
  210. int NumRefs() { return 2; }
  211. RefTargetHandle GetReference(int i);
  212. void SetReference(int i, RefTargetHandle rtarg);
  213. /*
  214. ** Tell MAX what channels we use and what channels we change:
  215. ** Note that if we do not tell max that we use a channel, that channel is not
  216. ** guaranteed to be valid.
  217. */
  218. virtual ChannelMask ChannelsUsed() { return SELECT_CHANNEL|SUBSEL_TYPE_CHANNEL|GEOM_CHANNEL; }
  219. virtual ChannelMask ChannelsChanged() { return SELECT_CHANNEL|SUBSEL_TYPE_CHANNEL|GEOM_CHANNEL; }
  220. /*
  221. ** MAX tells us whenever an input changed. If we cache anything, we can use this
  222. ** function to dump the cached data and regenerate it.
  223. */
  224. virtual void NotifyInputChanged(Interval changeInt, PartID partID, RefMessage message, ModContext *mc) {}
  225. /*
  226. ** This is where the modifier actually modifies the object!
  227. */
  228. virtual void ModifyObject(TimeValue t, ModContext & mc, ObjectState * os, INode * node);
  229. /*
  230. ** Since our modifier will be storing information based on the vertex indices, whenever
  231. ** the topology of its input is changed things will no longer work correctly. Therefore,
  232. ** we tell max that we depend on the topology remaining the same.
  233. */
  234. virtual BOOL DependOnTopology(ModContext &mc) { return TRUE; }
  235. /*
  236. ** What types of objects can we modify: The skin modifier will only work with TRIOBJ's
  237. */
  238. virtual Class_ID InputType() { return Class_ID(TRIOBJ_CLASS_ID,0); }
  239. /*
  240. ** Saving and loading. Remember to call the base class's save and load functions as well.
  241. */
  242. IOResult Save(ISave *isave);
  243. IOResult Load(ILoad *iload);
  244. virtual IOResult LoadLocalData(ILoad *iload, LocalModData **pld);
  245. virtual IOResult SaveLocalData(ISave *isave, LocalModData *ld);
  246. /*
  247. ** For SkinModifierClass, we allow vertex sub-object selection.
  248. ** This function notifies an object being edited that the current sub object
  249. ** selection level has changed. level==0 indicates object level selection.
  250. ** level==1 or greater refer to the types registered by the object in the
  251. ** order they appeared in the list when registered. If level >= 1, the object
  252. ** should specify sub-object xform modes in the modes structure (defined in cmdmode.h).
  253. */
  254. void ActivateSubobjSel(int level, XFormModes& modes);
  255. int HitTest(TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt, ModContext* mc);
  256. void SelectSubComponent(HitRecord *hitRec, BOOL selected, BOOL all, BOOL invert=FALSE);
  257. void ClearSelection(int selLevel);//
  258. void SelectAll(int selLevel);
  259. void InvertSelection(int selLevel);
  260. /*
  261. ** An object that supports sub-object selection can choose to
  262. ** support named sub object selection sets. Methods in the the
  263. ** interface passed to objects allow them to add items to the
  264. ** sub-object selection set drop down.
  265. ** The following methods implement named sub-obj selection sets
  266. */
  267. virtual BOOL SupportsNamedSubSels() { return TRUE; }
  268. virtual void ActivateSubSelSet(TSTR &setName);
  269. virtual void NewSetFromCurSel(TSTR &setName);
  270. virtual void RemoveSubSelSet(TSTR &setName);
  271. void Create_Named_Selection_Sets(void);
  272. void Install_Named_Selection_Sets(void);
  273. WSMObject * Get_WSMObject(void) { return (WSMObject*)GetReference(OBJ_REF); }
  274. Interval Get_Validity(TimeValue t);
  275. /*
  276. ** Bone picking
  277. */
  278. virtual void User_Picked_Bone(INode * node);
  279. virtual void User_Picked_Bones(INodeTab & nodetab);
  280. /*
  281. ** Auto-Attach vertices to nearest bone
  282. */
  283. void Auto_Attach_Verts(BOOL all = FALSE);
  284. /*
  285. ** Unlink selected verts (links them to the root or origin)
  286. */
  287. void Unlink_Verts(void);
  288. private:
  289. /*
  290. ** Windows dialog management and communication functions
  291. */
  292. void Install_Bone_Influence_Dialog(void);
  293. void Remove_Bone_Influence_Dialog(void);
  294. BOOL Bone_Influence_Dialog_Proc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
  295. public:
  296. /*
  297. ** References for SkinModifierClass
  298. */
  299. enum {
  300. OBJ_REF = 0,
  301. NODE_REF = 1
  302. };
  303. SkinWSMObjectClass * WSMObjectRef;
  304. INode * WSMNodeRef;
  305. /*
  306. ** Sub-Object Selection variables
  307. */
  308. enum {
  309. OBJECT_SEL_LEVEL = 0,
  310. VERTEX_SEL_LEVEL = 1
  311. };
  312. int SubObjSelLevel;
  313. /*
  314. ** Bone Influence Dialog panel variables
  315. */
  316. HWND BoneInfluenceHWND;
  317. ICustButton * LinkButton;
  318. ICustButton * LinkByNameButton;
  319. ICustButton * AutoLinkButton;
  320. ICustButton * UnLinkButton;
  321. /*
  322. ** Cached pointers to some MAX objects
  323. */
  324. IObjParam * InterfacePtr;
  325. SelectModBoxCMode * SelectMode;
  326. /*
  327. ** Load/Save Chunk ID's
  328. */
  329. enum {
  330. SEL_LEVEL_CHUNK = 0xAA01,
  331. };
  332. /*
  333. ** Friend "thunking" functions for the dialog handling.
  334. */
  335. friend BOOL CALLBACK _bone_influence_dialog_thunk(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam);
  336. };
  337. #endif