MegaConformMulti.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. [System.Serializable]
  4. public class MegaConformTarget
  5. {
  6. public GameObject target;
  7. public bool children = false;
  8. }
  9. [AddComponentMenu("Modifiers/Conform Multi")]
  10. public class MegaConformMulti : MegaModifier
  11. {
  12. public List<MegaConformTarget> targets = new List<MegaConformTarget>();
  13. public List<Collider> conformColliders = new List<Collider>();
  14. public float[] offsets;
  15. public Bounds bounds;
  16. public float[] last;
  17. public Vector3[] conformedVerts;
  18. public float conformAmount = 1.0f;
  19. public float raystartoff = 0.0f;
  20. public float offset = 0.0f;
  21. public float raydist = 100.0f;
  22. public MegaAxis axis = MegaAxis.Y;
  23. Matrix4x4 loctoworld;
  24. Matrix4x4 ctm;
  25. Matrix4x4 cinvtm;
  26. Ray ray = new Ray();
  27. RaycastHit hit;
  28. public override string ModName() { return "Conform Multi"; }
  29. public override string GetHelpURL() { return "?page_id=4547"; }
  30. public void BuildColliderList()
  31. {
  32. conformColliders.Clear();
  33. for ( int i = 0; i < targets.Count; i++ )
  34. {
  35. if ( targets[i].target )
  36. {
  37. if ( targets[i].children )
  38. {
  39. Collider[] cols = (Collider[])targets[i].target.GetComponentsInChildren<Collider>();
  40. for ( int c = 0; c < cols.Length; c++ )
  41. conformColliders.Add(cols[c]);
  42. }
  43. else
  44. {
  45. Collider col = targets[i].target.GetComponent<Collider>();
  46. if ( col )
  47. conformColliders.Add(col);
  48. }
  49. }
  50. }
  51. }
  52. public override Vector3 Map(int i, Vector3 p)
  53. {
  54. return p;
  55. }
  56. bool DoRayCast(Ray ray, ref Vector3 pos, float raydist)
  57. {
  58. bool retval = false;
  59. float min = float.MaxValue;
  60. for ( int i = 0; i < conformColliders.Count; i++ )
  61. {
  62. if ( conformColliders[i].Raycast(ray, out hit, raydist) )
  63. {
  64. retval = true;
  65. if ( hit.distance < min )
  66. {
  67. min = hit.distance;
  68. pos = hit.point;
  69. }
  70. }
  71. }
  72. return retval;
  73. }
  74. public override void Modify(MegaModifiers mc)
  75. {
  76. if ( conformColliders.Count > 0 )
  77. {
  78. int ax = (int)axis;
  79. Vector3 hitpos = Vector3.zero;
  80. for ( int i = 0; i < verts.Length; i++ )
  81. {
  82. Vector3 origin = ctm.MultiplyPoint(verts[i]);
  83. origin.y += raystartoff;
  84. ray.origin = origin;
  85. ray.direction = Vector3.down;
  86. sverts[i] = verts[i];
  87. if ( DoRayCast(ray, ref hitpos, raydist) )
  88. {
  89. Vector3 lochit = cinvtm.MultiplyPoint(hitpos);
  90. sverts[i][ax] = Mathf.Lerp(verts[i][ax], lochit[ax] + offsets[i] + offset, conformAmount);
  91. last[i] = sverts[i][ax];
  92. }
  93. else
  94. {
  95. Vector3 ht = ray.origin;
  96. ht.y -= raydist;
  97. sverts[i][ax] = last[i];
  98. }
  99. }
  100. }
  101. else
  102. verts.CopyTo(sverts, 0);
  103. }
  104. public override bool ModLateUpdate(MegaModContext mc)
  105. {
  106. return Prepare(mc);
  107. }
  108. public override bool Prepare(MegaModContext mc)
  109. {
  110. if ( targets.Count > 0 )
  111. {
  112. if ( conformColliders.Count == 0 )
  113. return false;
  114. if ( conformedVerts == null || conformedVerts.Length != mc.mod.verts.Length )
  115. {
  116. conformedVerts = new Vector3[mc.mod.verts.Length];
  117. // Need to run through all the source meshes and find the vertical offset from the base
  118. offsets = new float[mc.mod.verts.Length];
  119. last = new float[mc.mod.verts.Length];
  120. for ( int i = 0; i < mc.mod.verts.Length; i++ )
  121. offsets[i] = mc.mod.verts[i][(int)axis] - mc.bbox.min[(int)axis];
  122. }
  123. loctoworld = transform.localToWorldMatrix;
  124. ctm = loctoworld;
  125. cinvtm = transform.worldToLocalMatrix; //ctm.inverse;
  126. }
  127. return true;
  128. }
  129. }