gridsnapmodifier.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. /*
  2. ** Command & Conquer Generals(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 : Max2W3d *
  23. * *
  24. * $Archive:: /Commando/Code/Tools/max2w3d/gridsnapmodifier.cpp $*
  25. * *
  26. * Original Author:: Greg Hjelstrom *
  27. * *
  28. * $Author:: Greg_h $*
  29. * *
  30. * $Modtime:: 5/01/01 8:29p $*
  31. * *
  32. * $Revision:: 1 $*
  33. * *
  34. *---------------------------------------------------------------------------------------------*
  35. * Functions: *
  36. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  37. #include "Max.h"
  38. #include "resource.h"
  39. #include "simpmod.h"
  40. #include "dllmain.h"
  41. #include "iparamb2.h"
  42. /*
  43. WARNING WARNING WARNING PLEASE READ - This modifier was an experiment to see if we could
  44. solve cracks in adjacent meshes by snapping to a world-space grid. It didn't work for a
  45. few reasons:
  46. - I couldn't implement the world space snapping; the SimpleMod code seems to always force
  47. you to work relative to each object.
  48. - Snapping to a grid won't always snap vertices to the same grid. The probability that
  49. it will work is a function of the distance between the points and the grid spacing
  50. */
  51. #define GRIDSNAPMOD_CLASSID Class_ID(0x7a2d399b, 0x1e3d2004)
  52. /**
  53. ** GridSnapModifierClass
  54. ** This modifier will snap all vertices in the geometry being modified to a grid. Its motivation is to
  55. ** try to help solve the problem of cracks between adjacent meshes in Renegade levels. This will work
  56. ** a lot better if the objects have reset-transforms prior to being processed by this modifier.
  57. */
  58. class GridSnapModifierClass : public SimpleMod2
  59. {
  60. public:
  61. GridSnapModifierClass();
  62. // From Animatable
  63. void DeleteThis() { delete this; }
  64. void GetClassName(TSTR& s) { s = Get_String(IDS_GRIDSNAPMODIFIER); }
  65. virtual Class_ID ClassID() { return GRIDSNAPMOD_CLASSID; }
  66. void BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev);
  67. void EndEditParams( IObjParam *ip,ULONG flags,Animatable *next);
  68. RefTargetHandle Clone(RemapDir& remap = NoRemap());
  69. TCHAR *GetObjectName() { return Get_String(IDS_GRIDSNAPMODIFIER);}
  70. IOResult Load(ILoad *iload);
  71. // Direct paramblock access
  72. int NumParamBlocks() { return 1; }
  73. IParamBlock2* GetParamBlock(int i) { return pblock2; }
  74. IParamBlock2* GetParamBlockByID(BlockID id) { return (pblock2->ID() == id) ? pblock2 : NULL; }
  75. // From simple mod
  76. Deformer& GetDeformer(TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat);
  77. Interval GetValidity(TimeValue t);
  78. //RefTargetHandle GetReference(int i)
  79. //void SetReference(int i,RefTargetHandle rtar)
  80. //Animatable * SubAnim(int i)
  81. };
  82. /**
  83. ** GridSnapDeformerClass
  84. ** This is the callback object used by GridSnapModifierClass to implement the actual geometry changes. This
  85. ** architecture is required by the SimpleMod base-class. This Deformer simply snaps vertex positions
  86. ** to the grid defined by its parameters.
  87. */
  88. class GridSnapDeformerClass : public Deformer
  89. {
  90. public:
  91. GridSnapDeformerClass(void) : GridDimension(0.001f) {}
  92. void Set_Grid_Dimension(float grid_dim) { GridDimension = grid_dim; }
  93. float Get_Grid_Dimension(void) { return GridDimension; }
  94. void Set_Matrices(const Matrix3 & tm,const Matrix3 & invtm) { Transform = tm; InvTransform = invtm; }
  95. virtual Point3 Map(int i,Point3 p)
  96. {
  97. p = p*Transform;
  98. p.x = floor(p.x / GridDimension) * GridDimension;
  99. p.y = floor(p.y / GridDimension) * GridDimension;
  100. p.z = floor(p.z / GridDimension) * GridDimension;
  101. p = p*InvTransform;
  102. return p;
  103. }
  104. private:
  105. float GridDimension;
  106. Matrix3 Transform;
  107. Matrix3 InvTransform;
  108. };
  109. /**
  110. ** GridSnapModifier Class Descriptor
  111. ** This object "links" the plugin into Max's plugin system. It links the Class-ID to a virtual construction
  112. ** method. The function Get_Grid_Snap_Modifier_Desc is the only hook to external code.
  113. */
  114. class GridSnapModifierClassDesc:public ClassDesc2
  115. {
  116. public:
  117. int IsPublic() { return 1; }
  118. void * Create(BOOL loading = FALSE) { return new GridSnapModifierClass; }
  119. const TCHAR * ClassName() { return _T("Grid Snap Modifier"); }
  120. SClass_ID SuperClassID() { return OSM_CLASS_ID; }
  121. Class_ID ClassID() { return GRIDSNAPMOD_CLASSID; }
  122. const TCHAR* Category() { return _T("Westwood Modifiers");}
  123. HINSTANCE HInstance() { return AppInstance; }
  124. const TCHAR * InternalName() { return _T("Westwood GridSnap"); }
  125. };
  126. static GridSnapModifierClassDesc _GridSnapModifierDesc;
  127. ClassDesc* Get_Grid_Snap_Modifier_Desc(void)
  128. {
  129. return &_GridSnapModifierDesc;
  130. }
  131. /*
  132. ** ParamBlock2 Setup
  133. */
  134. enum
  135. {
  136. GSM_PARAMS = 0,
  137. };
  138. enum
  139. {
  140. GSM_PARAM_GRIDDIMENSION = 0,
  141. };
  142. static ParamBlockDesc2 _GridSnapParamBlockDesc
  143. (
  144. // parameter block settings
  145. GSM_PARAMS,_T("GridSnap Parameters"), 0, &_GridSnapModifierDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, SIMPMOD_PBLOCKREF,
  146. // dialog box
  147. IDD_GRIDSNAP_PARAMS, IDS_GRIDSNAP_TITLE, 0, 0, NULL,
  148. // parameters
  149. GSM_PARAM_GRIDDIMENSION, _T("Grid Dimension"), TYPE_FLOAT, P_RESET_DEFAULT, IDS_GRID_DIMENSION,
  150. p_default, 0.001f,
  151. p_range, 0.0001f, 10.0f,
  152. p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_GRIDDIM_EDIT, IDC_GRIDDIM_SPIN, 0.0001f,
  153. end,
  154. end
  155. );
  156. /********************************************************************************************
  157. **
  158. ** GridSnapModifierClass Implementation
  159. **
  160. ********************************************************************************************/
  161. GridSnapModifierClass::GridSnapModifierClass()
  162. {
  163. // create the parameter block, storing in the base-class's pblock variable
  164. _GridSnapModifierDesc.MakeAutoParamBlocks(this);
  165. assert(pblock2);
  166. }
  167. void GridSnapModifierClass::BeginEditParams( IObjParam *ip, ULONG flags,Animatable *prev)
  168. {
  169. this->ip = ip;
  170. SimpleMod2::BeginEditParams(ip,flags,prev);
  171. _GridSnapModifierDesc.BeginEditParams(ip, this, flags, prev);
  172. }
  173. void GridSnapModifierClass::EndEditParams( IObjParam *ip,ULONG flags,Animatable *next)
  174. {
  175. SimpleMod2::EndEditParams(ip,flags,next);
  176. _GridSnapModifierDesc.EndEditParams(ip, this, flags, next);
  177. this->ip = NULL;
  178. }
  179. RefTargetHandle GridSnapModifierClass::Clone(RemapDir& remap)
  180. {
  181. GridSnapModifierClass * newmod = new GridSnapModifierClass();
  182. newmod->ReplaceReference(SIMPMOD_PBLOCKREF,pblock2->Clone(remap));
  183. newmod->SimpleModClone(this);
  184. return(newmod);
  185. }
  186. IOResult GridSnapModifierClass::Load(ILoad *iload)
  187. {
  188. Modifier::Load(iload);
  189. return IO_OK;
  190. }
  191. Deformer& GridSnapModifierClass::GetDeformer(TimeValue t,ModContext &mc,Matrix3& mat,Matrix3& invmat)
  192. {
  193. float dimension = 0.0f; Interval valid = FOREVER;
  194. pblock2->GetValue(GSM_PARAM_GRIDDIMENSION, t, dimension, FOREVER);
  195. static GridSnapDeformerClass deformer;
  196. deformer.Set_Grid_Dimension(dimension);
  197. deformer.Set_Matrices(mat,invmat);
  198. return deformer;
  199. }
  200. Interval GridSnapModifierClass::GetValidity(TimeValue t)
  201. {
  202. float f;
  203. Interval valid = FOREVER;
  204. pblock2->GetValue(GSM_PARAM_GRIDDIMENSION, t, f, valid);
  205. return valid;
  206. }
  207. RefTargetHandle SimpleMod2::GetReference(int i)
  208. {
  209. switch (i) {
  210. case 0: return tmControl;
  211. case 1: return posControl;
  212. case 2: return pblock2;
  213. default: return NULL;
  214. }
  215. }
  216. void SimpleMod2::SetReference(int i,RefTargetHandle rtarg)
  217. {
  218. switch (i) {
  219. case 0: tmControl = (Control*)rtarg; break;
  220. case 1: posControl = (Control*)rtarg; break;
  221. case 2: pblock2 = (IParamBlock2*)rtarg; break;
  222. }
  223. }
  224. Animatable * SimpleMod2::SubAnim(int i)
  225. {
  226. switch (i) {
  227. case 0: return posControl;
  228. case 1: return tmControl;
  229. case 2: return pblock2;
  230. default: return NULL;
  231. }
  232. }