MegaMultiVolSelect.cs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. public enum MegaVolumeType
  4. {
  5. Box,
  6. Sphere,
  7. }
  8. [System.Serializable]
  9. public class MegaVolume
  10. {
  11. public MegaVolume()
  12. {
  13. falloff = 1.0f;
  14. enabled = true;
  15. weight = 1.0f;
  16. name = "None";
  17. uselimits = false;
  18. inverse = false;
  19. }
  20. public bool enabled = true;
  21. public float weight = 1.0f;
  22. public string name = "None";
  23. public Color regcol = Color.yellow;
  24. public Vector3 origin = Vector3.zero;
  25. public Vector3 boxsize = Vector3.one;
  26. // need type ie box or sphere
  27. public float falloff = 1.0f;
  28. public MegaVolumeType volType = MegaVolumeType.Sphere;
  29. public float radius = 1.0f;
  30. public bool uselimits = false;
  31. public Vector3 size = Vector3.zero;
  32. public Transform target;
  33. public bool inverse = false;
  34. static public MegaVolume Create()
  35. {
  36. MegaVolume vol = new MegaVolume();
  37. return vol;
  38. }
  39. }
  40. [AddComponentMenu("Modifiers/Selection/Multi Volume")]
  41. public class MegaMultiVolSelect : MegaSelectionMod
  42. {
  43. public override MegaModChannel ChannelsReq() { return MegaModChannel.Col | MegaModChannel.Verts; }
  44. public override string ModName() { return "Multi Vol Select"; }
  45. public override string GetHelpURL() { return "?page_id=3904"; }
  46. float[] modselection;
  47. public float[] GetSel() { return modselection; }
  48. public Color gizCol = new Color(0.5f, 0.5f, 0.5f, 0.25f);
  49. public float gizSize = 0.01f;
  50. public bool useCurrentVerts = true;
  51. public bool displayWeights = true;
  52. public bool freezeSelection = false;
  53. public List<MegaVolume> volumes = new List<MegaVolume>();
  54. float GetDistBox(MegaVolume vol, Vector3 p)
  55. {
  56. // Work in the box's coordinate system.
  57. Vector3 diff = p - vol.origin;
  58. // Compute squared distance and closest point on box.
  59. float sqrDistance = 0.0f;
  60. float delta;
  61. Vector3 closest = diff;
  62. if ( closest.x < -vol.boxsize.x )
  63. {
  64. delta = closest.x + vol.boxsize.x;
  65. sqrDistance += delta * delta;
  66. closest.x = -vol.boxsize.x;
  67. }
  68. else
  69. {
  70. if ( closest.x > vol.boxsize.x )
  71. {
  72. delta = closest.x - vol.boxsize.x;
  73. sqrDistance += delta * delta;
  74. closest.x = vol.boxsize.x;
  75. }
  76. }
  77. if ( closest.y < -vol.boxsize.y )
  78. {
  79. delta = closest.y + vol.boxsize.y;
  80. sqrDistance += delta * delta;
  81. closest.y = -vol.boxsize.y;
  82. }
  83. else
  84. {
  85. if ( closest.y > vol.boxsize.y )
  86. {
  87. delta = closest.y - vol.boxsize.y;
  88. sqrDistance += delta * delta;
  89. closest.y = vol.boxsize.y;
  90. }
  91. }
  92. if ( closest.z < -vol.boxsize.z )
  93. {
  94. delta = closest.z + vol.boxsize.z;
  95. sqrDistance += delta * delta;
  96. closest.z = -vol.boxsize.z;
  97. }
  98. else
  99. {
  100. if ( closest.z > vol.boxsize.z )
  101. {
  102. delta = closest.z - vol.boxsize.z;
  103. sqrDistance += delta * delta;
  104. closest.z = vol.boxsize.z;
  105. }
  106. }
  107. return Mathf.Sqrt(sqrDistance); // * 0.5f;
  108. }
  109. public override void GetSelection(MegaModifiers mc)
  110. {
  111. if ( modselection == null || modselection.Length != mc.verts.Length )
  112. modselection = new float[mc.verts.Length];
  113. int volcount = 0;
  114. if ( !freezeSelection )
  115. {
  116. if ( volumes != null && volumes.Count > 0 )
  117. {
  118. for ( int v = 0; v < volumes.Count; v++ )
  119. {
  120. MegaVolume vol = volumes[v];
  121. if ( vol.enabled )
  122. {
  123. Vector3 origin = Vector3.zero;
  124. if ( vol.target )
  125. origin = transform.worldToLocalMatrix.MultiplyPoint(vol.target.position);
  126. else
  127. origin = vol.origin;
  128. vol.origin = origin;
  129. if ( volcount == 0 )
  130. {
  131. if ( vol.volType == MegaVolumeType.Sphere )
  132. {
  133. if ( useCurrentVerts )
  134. {
  135. for ( int i = 0; i < verts.Length; i++ )
  136. {
  137. float d = Vector3.Distance(origin, verts[i]) - vol.radius;
  138. if ( d < 0.0f )
  139. modselection[i] = vol.weight;
  140. else
  141. {
  142. float w = Mathf.Exp(-vol.falloff * Mathf.Abs(d));
  143. modselection[i] = w * vol.weight; //mc.cols[i][c];
  144. }
  145. if ( vol.inverse )
  146. modselection[i] = 1.0f - modselection[i];
  147. }
  148. }
  149. else
  150. {
  151. for ( int i = 0; i < verts.Length; i++ )
  152. {
  153. float d = Vector3.Distance(origin, verts[i]) - vol.radius;
  154. if ( d < 0.0f )
  155. modselection[i] = vol.weight;
  156. else
  157. {
  158. float w = Mathf.Exp(-vol.falloff * Mathf.Abs(d));
  159. modselection[i] = w * vol.weight; //mc.cols[i][c];
  160. }
  161. if ( vol.inverse )
  162. modselection[i] = 1.0f - modselection[i];
  163. }
  164. }
  165. }
  166. else
  167. {
  168. if ( useCurrentVerts )
  169. {
  170. for ( int i = 0; i < verts.Length; i++ )
  171. {
  172. float d = GetDistBox(vol, verts[i]);
  173. //if ( d < 0.0f )
  174. //modselection[i] = vol.weight;
  175. //else
  176. //{
  177. float w = Mathf.Exp(-vol.falloff * Mathf.Abs(d));
  178. if ( w > 1.0f )
  179. w = 1.0f;
  180. modselection[i] = w * vol.weight; //mc.cols[i][c];
  181. //}
  182. if ( vol.inverse )
  183. modselection[i] = 1.0f - modselection[i];
  184. }
  185. }
  186. else
  187. {
  188. for ( int i = 0; i < verts.Length; i++ )
  189. {
  190. float d = GetDistBox(vol, verts[i]);
  191. //if ( d < 0.0f )
  192. //modselection[i] = vol.weight;
  193. //else
  194. //{
  195. float w = Mathf.Exp(-vol.falloff * Mathf.Abs(d));
  196. if ( w > 1.0f )
  197. w = 1.0f;
  198. modselection[i] = w * vol.weight; //mc.cols[i][c];
  199. //}
  200. if ( vol.inverse )
  201. modselection[i] = 1.0f - modselection[i];
  202. }
  203. }
  204. }
  205. }
  206. else
  207. {
  208. if ( vol.volType == MegaVolumeType.Box )
  209. {
  210. if ( useCurrentVerts )
  211. {
  212. for ( int i = 0; i < verts.Length; i++ )
  213. {
  214. float d = GetDistBox(vol, verts[i]);
  215. float wg = modselection[i];
  216. //if ( d < 0.0f )
  217. //wg += vol.weight;
  218. //else
  219. //{
  220. float w = Mathf.Exp(-vol.falloff * Mathf.Abs(d));
  221. wg += w * vol.weight; //mc.cols[i][c];
  222. //}
  223. if ( wg > 1.0f )
  224. modselection[i] = 1.0f;
  225. else
  226. modselection[i] = wg;
  227. if ( vol.inverse )
  228. modselection[i] = 1.0f - modselection[i];
  229. }
  230. }
  231. else
  232. {
  233. for ( int i = 0; i < verts.Length; i++ )
  234. {
  235. float d = GetDistBox(vol, verts[i]);
  236. float wg = modselection[i];
  237. //if ( d < 0.0f )
  238. //wg += vol.weight;
  239. //else
  240. //{
  241. float w = Mathf.Exp(-vol.falloff * Mathf.Abs(d));
  242. wg += w * vol.weight; //mc.cols[i][c];
  243. //}
  244. if ( wg > 1.0f )
  245. modselection[i] = 1.0f;
  246. else
  247. modselection[i] = wg;
  248. if ( vol.inverse )
  249. modselection[i] = 1.0f - modselection[i];
  250. }
  251. }
  252. }
  253. else
  254. {
  255. if ( useCurrentVerts )
  256. {
  257. for ( int i = 0; i < verts.Length; i++ )
  258. {
  259. float d = Vector3.Distance(origin, verts[i]) - vol.radius;
  260. float wg = modselection[i];
  261. if ( d < 0.0f )
  262. wg += vol.weight;
  263. else
  264. {
  265. float w = Mathf.Exp(-vol.falloff * Mathf.Abs(d));
  266. wg += w * vol.weight; //mc.cols[i][c];
  267. }
  268. if ( wg > 1.0f )
  269. modselection[i] = 1.0f;
  270. else
  271. modselection[i] = wg;
  272. if ( vol.inverse )
  273. modselection[i] = 1.0f - modselection[i];
  274. }
  275. }
  276. else
  277. {
  278. for ( int i = 0; i < verts.Length; i++ )
  279. {
  280. float d = Vector3.Distance(origin, verts[i]) - vol.radius;
  281. float wg = modselection[i];
  282. if ( d < 0.0f )
  283. wg += vol.weight;
  284. else
  285. {
  286. float w = Mathf.Exp(-vol.falloff * Mathf.Abs(d));
  287. wg += w * vol.weight; //mc.cols[i][c];
  288. }
  289. if ( wg > 1.0f )
  290. modselection[i] = 1.0f;
  291. else
  292. modselection[i] = wg;
  293. if ( vol.inverse )
  294. modselection[i] = 1.0f - modselection[i];
  295. }
  296. }
  297. }
  298. }
  299. volcount++;
  300. }
  301. }
  302. }
  303. if ( volcount == 0 )
  304. {
  305. for ( int i = 0; i < verts.Length; i++ )
  306. modselection[i] = 0.0f;
  307. }
  308. }
  309. if ( (mc.dirtyChannels & MegaModChannel.Verts) == 0 )
  310. mc.InitVertSource();
  311. mc.selection = modselection;
  312. }
  313. public override void DrawGizmo(MegaModContext context)
  314. {
  315. if ( ModEnabled )
  316. {
  317. base.DrawGizmo(context);
  318. Matrix4x4 tm = gameObject.transform.localToWorldMatrix;
  319. Gizmos.matrix = tm;
  320. for ( int i = 0; i < volumes.Count; i++ )
  321. {
  322. if ( volumes[i].enabled && volumes[i].volType == MegaVolumeType.Box )
  323. {
  324. Gizmos.color = volumes[i].regcol; //Color.yellow;
  325. Gizmos.DrawWireCube(volumes[i].origin, volumes[i].boxsize * 2.0f); // * 0.5f);
  326. }
  327. if ( volumes[i].enabled && volumes[i].volType == MegaVolumeType.Sphere )
  328. {
  329. Gizmos.color = volumes[i].regcol; //Color.yellow;
  330. Gizmos.DrawWireSphere(volumes[i].origin, volumes[i].radius); // * 0.5f);
  331. }
  332. }
  333. Gizmos.matrix = Matrix4x4.identity;
  334. }
  335. }
  336. }