MegaCurveSculptLayered.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. using System.Threading;
  4. public enum MegaAlter
  5. {
  6. Offset,
  7. Scale,
  8. Both,
  9. }
  10. public enum MegaAffect
  11. {
  12. X,
  13. Y,
  14. Z,
  15. XY,
  16. XZ,
  17. YZ,
  18. XYZ,
  19. None,
  20. }
  21. // TODO: define box for effect, origin and sizes, and a falloff
  22. [System.Serializable]
  23. public class MegaSculptCurve
  24. {
  25. public MegaSculptCurve()
  26. {
  27. curve = new AnimationCurve(new Keyframe(0.0f, 0.0f), new Keyframe(1.0f, 0.0f));
  28. offamount = Vector3.one;
  29. sclamount = Vector3.one;
  30. axis = MegaAxis.X;
  31. affectOffset = MegaAffect.Y;
  32. affectScale = MegaAffect.None;
  33. enabled = true;
  34. weight = 1.0f;
  35. name = "None";
  36. uselimits = false;
  37. }
  38. public AnimationCurve curve = new AnimationCurve(new Keyframe(0.0f, 0.0f), new Keyframe(1.0f, 0.0f));
  39. public Vector3 offamount = Vector3.one;
  40. public Vector3 sclamount = Vector3.one;
  41. public MegaAxis axis = MegaAxis.X;
  42. public MegaAffect affectOffset = MegaAffect.Y;
  43. public MegaAffect affectScale = MegaAffect.None;
  44. public bool enabled = true;
  45. public float weight = 1.0f;
  46. public string name = "None";
  47. public Color regcol = Color.yellow;
  48. public Vector3 origin = Vector3.zero;
  49. public Vector3 boxsize = Vector3.one;
  50. public bool uselimits = false;
  51. public Vector3 size = Vector3.zero;
  52. static public MegaSculptCurve Create()
  53. {
  54. MegaSculptCurve crv = new MegaSculptCurve();
  55. return crv;
  56. }
  57. }
  58. [AddComponentMenu("Modifiers/Curve Sculpt Layered")]
  59. public class MegaCurveSculptLayered : MegaModifier
  60. {
  61. public List<MegaSculptCurve> curves = new List<MegaSculptCurve>();
  62. Vector3 size = Vector3.zero;
  63. public override string ModName() { return "CurveSculpLayered"; }
  64. public override string GetHelpURL() { return "?page_id=2411"; }
  65. static object resourceLock = new object();
  66. public override void DoWork(MegaModifiers mc, int index, int start, int end, int cores)
  67. {
  68. if ( selection != null )
  69. {
  70. DoWorkWeighted(mc, index, start, end, cores);
  71. return;
  72. }
  73. for ( int i = start; i < end; i++ )
  74. sverts[i] = MapMT(i, verts[i]);
  75. }
  76. public override void DoWorkWeighted(MegaModifiers mc, int index, int start, int end, int cores)
  77. {
  78. for ( int i = start; i < end; i++ )
  79. {
  80. Vector3 p = verts[i];
  81. float w = selection[i]; //[(int)weightChannel];
  82. if ( w > 0.001f )
  83. {
  84. Vector3 mp = MapMT(i, verts[i]);
  85. sverts[i].x = p.x + (mp.x - p.x) * w;
  86. sverts[i].y = p.y + (mp.y - p.y) * w;
  87. sverts[i].z = p.z + (mp.z - p.z) * w;
  88. }
  89. else
  90. sverts[i] = p; //verts[i];
  91. }
  92. }
  93. public Vector3 MapMT(int i, Vector3 p)
  94. {
  95. p = tm.MultiplyPoint3x4(p);
  96. for ( int c = 0; c < curves.Count; c++ )
  97. {
  98. MegaSculptCurve crv = curves[c];
  99. if ( crv.enabled )
  100. {
  101. int ax = (int)crv.axis;
  102. if ( crv.uselimits )
  103. {
  104. // Is the point in the box
  105. Vector3 bp = p - crv.origin;
  106. if ( Mathf.Abs(bp.x) < crv.size.x && Mathf.Abs(bp.y) < crv.size.y && Mathf.Abs(bp.z) < crv.size.z )
  107. {
  108. float alpha = 0.5f + ((bp[ax] / crv.size[ax]) * 0.5f);
  109. if ( alpha >= 0.0f && alpha <= 1.0f )
  110. {
  111. Monitor.Enter(resourceLock);
  112. float a = crv.curve.Evaluate(alpha) * crv.weight;
  113. Monitor.Exit(resourceLock);
  114. switch ( crv.affectScale )
  115. {
  116. case MegaAffect.X:
  117. p.x += bp.x * (a * crv.sclamount.x);
  118. break;
  119. case MegaAffect.Y:
  120. p.y += bp.y * (a * crv.sclamount.y);
  121. break;
  122. case MegaAffect.Z:
  123. p.z += bp.z * (a * crv.sclamount.z);
  124. break;
  125. case MegaAffect.XY:
  126. p.x += bp.x * (a * crv.sclamount.x);
  127. p.y += bp.y * (a * crv.sclamount.y);
  128. break;
  129. case MegaAffect.XZ:
  130. p.x += bp.x * (a * crv.sclamount.x);
  131. p.z += bp.z * (a * crv.sclamount.z);
  132. break;
  133. case MegaAffect.YZ:
  134. p.y += bp.y * (a * crv.sclamount.y);
  135. p.z += bp.z * (a * crv.sclamount.z);
  136. break;
  137. case MegaAffect.XYZ:
  138. p.x += bp.x * (a * crv.sclamount.x);
  139. p.y += bp.y * (a * crv.sclamount.y);
  140. p.z += bp.z * (a * crv.sclamount.z);
  141. break;
  142. }
  143. switch ( crv.affectOffset )
  144. {
  145. case MegaAffect.X:
  146. p.x += a * crv.offamount.x;
  147. break;
  148. case MegaAffect.Y:
  149. p.y += a * crv.offamount.y;
  150. break;
  151. case MegaAffect.Z:
  152. p.z += a * crv.offamount.z;
  153. break;
  154. case MegaAffect.XY:
  155. p.x += a * crv.offamount.x;
  156. p.y += a * crv.offamount.y;
  157. break;
  158. case MegaAffect.XZ:
  159. p.x += a * crv.offamount.x;
  160. p.z += a * crv.offamount.z;
  161. break;
  162. case MegaAffect.YZ:
  163. p.y += a * crv.offamount.y;
  164. p.z += a * crv.offamount.z;
  165. break;
  166. case MegaAffect.XYZ:
  167. p.x += a * crv.offamount.x;
  168. p.y += a * crv.offamount.y;
  169. p.z += a * crv.offamount.z;
  170. break;
  171. }
  172. }
  173. }
  174. }
  175. else
  176. {
  177. float alpha = (p[ax] - bbox.min[ax]) / size[ax];
  178. Monitor.Enter(resourceLock);
  179. float a = crv.curve.Evaluate(alpha) * crv.weight;
  180. Monitor.Exit(resourceLock);
  181. switch ( crv.affectScale )
  182. {
  183. case MegaAffect.X:
  184. p.x *= 1.0f + (a * crv.sclamount.y);
  185. break;
  186. case MegaAffect.Y:
  187. p.y *= 1.0f + (a * crv.sclamount.y);
  188. break;
  189. case MegaAffect.Z:
  190. p.z *= 1.0f + (a * crv.sclamount.z);
  191. break;
  192. case MegaAffect.XY:
  193. p.x *= 1.0f + (a * crv.sclamount.y);
  194. p.y *= 1.0f + (a * crv.sclamount.y);
  195. break;
  196. case MegaAffect.XZ:
  197. p.x *= 1.0f + (a * crv.sclamount.y);
  198. p.z *= 1.0f + (a * crv.sclamount.z);
  199. break;
  200. case MegaAffect.YZ:
  201. p.y *= 1.0f + (a * crv.sclamount.y);
  202. p.z *= 1.0f + (a * crv.sclamount.z);
  203. break;
  204. case MegaAffect.XYZ:
  205. p.x *= 1.0f + (a * crv.sclamount.y);
  206. p.y *= 1.0f + (a * crv.sclamount.y);
  207. p.z *= 1.0f + (a * crv.sclamount.z);
  208. break;
  209. }
  210. switch ( crv.affectOffset )
  211. {
  212. case MegaAffect.X:
  213. p.x += a * crv.offamount.x;
  214. break;
  215. case MegaAffect.Y:
  216. p.y += a * crv.offamount.y;
  217. break;
  218. case MegaAffect.Z:
  219. p.z += a * crv.offamount.z;
  220. break;
  221. case MegaAffect.XY:
  222. p.x += a * crv.offamount.x;
  223. p.y += a * crv.offamount.y;
  224. break;
  225. case MegaAffect.XZ:
  226. p.x += a * crv.offamount.x;
  227. p.z += a * crv.offamount.z;
  228. break;
  229. case MegaAffect.YZ:
  230. p.y += a * crv.offamount.y;
  231. p.z += a * crv.offamount.z;
  232. break;
  233. case MegaAffect.XYZ:
  234. p.x += a * crv.offamount.x;
  235. p.y += a * crv.offamount.y;
  236. p.z += a * crv.offamount.z;
  237. break;
  238. }
  239. }
  240. }
  241. }
  242. return invtm.MultiplyPoint3x4(p);
  243. }
  244. public override Vector3 Map(int i, Vector3 p)
  245. {
  246. p = tm.MultiplyPoint3x4(p);
  247. for ( int c = 0; c < curves.Count; c++ )
  248. {
  249. MegaSculptCurve crv = curves[c];
  250. if ( crv.enabled )
  251. {
  252. int ax = (int)crv.axis;
  253. if ( crv.uselimits )
  254. {
  255. // Is the point in the box
  256. Vector3 bp = p - crv.origin;
  257. if ( Mathf.Abs(bp.x) < crv.size.x && Mathf.Abs(bp.y) < crv.size.y && Mathf.Abs(bp.z) < crv.size.z )
  258. {
  259. float alpha = 0.5f + ((bp[ax] / crv.size[ax]) * 0.5f);
  260. if ( alpha >= 0.0f && alpha <= 1.0f )
  261. {
  262. float a = crv.curve.Evaluate(alpha) * crv.weight;
  263. switch ( crv.affectScale )
  264. {
  265. case MegaAffect.X:
  266. p.x += bp.x * (a * crv.sclamount.x);
  267. break;
  268. case MegaAffect.Y:
  269. p.y += bp.y * (a * crv.sclamount.y);
  270. break;
  271. case MegaAffect.Z:
  272. p.z += bp.z * (a * crv.sclamount.z);
  273. break;
  274. case MegaAffect.XY:
  275. p.x += bp.x * (a * crv.sclamount.x);
  276. p.y += bp.y * (a * crv.sclamount.y);
  277. break;
  278. case MegaAffect.XZ:
  279. p.x += bp.x * (a * crv.sclamount.x);
  280. p.z += bp.z * (a * crv.sclamount.z);
  281. break;
  282. case MegaAffect.YZ:
  283. p.y += bp.y * (a * crv.sclamount.y);
  284. p.z += bp.z * (a * crv.sclamount.z);
  285. break;
  286. case MegaAffect.XYZ:
  287. p.x += bp.x * (a * crv.sclamount.x);
  288. p.y += bp.y * (a * crv.sclamount.y);
  289. p.z += bp.z * (a * crv.sclamount.z);
  290. break;
  291. }
  292. switch ( crv.affectOffset )
  293. {
  294. case MegaAffect.X:
  295. p.x += a * crv.offamount.x;
  296. break;
  297. case MegaAffect.Y:
  298. p.y += a * crv.offamount.y;
  299. break;
  300. case MegaAffect.Z:
  301. p.z += a * crv.offamount.z;
  302. break;
  303. case MegaAffect.XY:
  304. p.x += a * crv.offamount.x;
  305. p.y += a * crv.offamount.y;
  306. break;
  307. case MegaAffect.XZ:
  308. p.x += a * crv.offamount.x;
  309. p.z += a * crv.offamount.z;
  310. break;
  311. case MegaAffect.YZ:
  312. p.y += a * crv.offamount.y;
  313. p.z += a * crv.offamount.z;
  314. break;
  315. case MegaAffect.XYZ:
  316. p.x += a * crv.offamount.x;
  317. p.y += a * crv.offamount.y;
  318. p.z += a * crv.offamount.z;
  319. break;
  320. }
  321. }
  322. }
  323. }
  324. else
  325. {
  326. float alpha = (p[ax] - bbox.min[ax]) / size[ax];
  327. float a = crv.curve.Evaluate(alpha) * crv.weight;
  328. switch ( crv.affectScale )
  329. {
  330. case MegaAffect.X:
  331. p.x *= 1.0f + (a * crv.sclamount.y);
  332. break;
  333. case MegaAffect.Y:
  334. p.y *= 1.0f + (a * crv.sclamount.y);
  335. break;
  336. case MegaAffect.Z:
  337. p.z *= 1.0f + (a * crv.sclamount.z);
  338. break;
  339. case MegaAffect.XY:
  340. p.x *= 1.0f + (a * crv.sclamount.y);
  341. p.y *= 1.0f + (a * crv.sclamount.y);
  342. break;
  343. case MegaAffect.XZ:
  344. p.x *= 1.0f + (a * crv.sclamount.y);
  345. p.z *= 1.0f + (a * crv.sclamount.z);
  346. break;
  347. case MegaAffect.YZ:
  348. p.y *= 1.0f + (a * crv.sclamount.y);
  349. p.z *= 1.0f + (a * crv.sclamount.z);
  350. break;
  351. case MegaAffect.XYZ:
  352. p.x *= 1.0f + (a * crv.sclamount.y);
  353. p.y *= 1.0f + (a * crv.sclamount.y);
  354. p.z *= 1.0f + (a * crv.sclamount.z);
  355. break;
  356. }
  357. switch ( crv.affectOffset )
  358. {
  359. case MegaAffect.X:
  360. p.x += a * crv.offamount.x;
  361. break;
  362. case MegaAffect.Y:
  363. p.y += a * crv.offamount.y;
  364. break;
  365. case MegaAffect.Z:
  366. p.z += a * crv.offamount.z;
  367. break;
  368. case MegaAffect.XY:
  369. p.x += a * crv.offamount.x;
  370. p.y += a * crv.offamount.y;
  371. break;
  372. case MegaAffect.XZ:
  373. p.x += a * crv.offamount.x;
  374. p.z += a * crv.offamount.z;
  375. break;
  376. case MegaAffect.YZ:
  377. p.y += a * crv.offamount.y;
  378. p.z += a * crv.offamount.z;
  379. break;
  380. case MegaAffect.XYZ:
  381. p.x += a * crv.offamount.x;
  382. p.y += a * crv.offamount.y;
  383. p.z += a * crv.offamount.z;
  384. break;
  385. }
  386. }
  387. }
  388. }
  389. return invtm.MultiplyPoint3x4(p);
  390. }
  391. public override bool ModLateUpdate(MegaModContext mc)
  392. {
  393. return Prepare(mc);
  394. }
  395. public override bool Prepare(MegaModContext mc)
  396. {
  397. size = bbox.max - bbox.min;
  398. for ( int i = 0; i < curves.Count; i++ )
  399. {
  400. curves[i].size = curves[i].boxsize * 0.5f; //Vector3.Scale(size, curves[i].boxsize);
  401. }
  402. return true;
  403. }
  404. public override void DrawGizmo(MegaModContext context)
  405. {
  406. base.DrawGizmo(context);
  407. for ( int i = 0; i < curves.Count; i++ )
  408. {
  409. if ( curves[i].enabled && curves[i].uselimits )
  410. {
  411. Gizmos.color = curves[i].regcol; //Color.yellow;
  412. Gizmos.DrawWireCube(curves[i].origin, curves[i].boxsize); // * 0.5f);
  413. }
  414. }
  415. }
  416. }