MegaConformMod.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. using UnityEngine;
  2. [AddComponentMenu("Modifiers/Conform")]
  3. public class MegaConformMod : MegaModifier
  4. {
  5. // Will have multiple in the end or layer
  6. public GameObject target;
  7. public float[] offsets;
  8. public Collider conformCollider;
  9. public Bounds bounds;
  10. public float[] last;
  11. public Vector3[] last1;
  12. public Vector3[] conformedVerts;
  13. public float conformAmount = 1.0f;
  14. public float raystartoff = 0.0f;
  15. public float offset = 0.0f;
  16. public float raydist = 100.0f;
  17. public MegaAxis axis = MegaAxis.Y;
  18. Matrix4x4 loctoworld;
  19. Matrix4x4 ctm;
  20. Matrix4x4 cinvtm;
  21. Ray ray = new Ray();
  22. RaycastHit hit;
  23. public bool useLocalDown = false;
  24. public bool flipDown = true;
  25. public MegaAxis downAxis = MegaAxis.Y;
  26. public override string ModName() { return "Conform"; }
  27. public override string GetHelpURL() { return "?page_id=4547"; }
  28. public void SetTarget(GameObject targ)
  29. {
  30. target = targ;
  31. if ( target )
  32. conformCollider = target.GetComponent<Collider>();
  33. }
  34. public override Vector3 Map(int i, Vector3 p)
  35. {
  36. return p;
  37. }
  38. public override void Modify(MegaModifiers mc)
  39. {
  40. if ( conformCollider )
  41. {
  42. if ( useLocalDown )
  43. {
  44. Vector3 down = Vector3.down;
  45. switch ( downAxis )
  46. {
  47. case MegaAxis.X: down = transform.right; break;
  48. case MegaAxis.Y: down = transform.up; break;
  49. case MegaAxis.Z: down = transform.forward; break;
  50. }
  51. if ( flipDown )
  52. down = -down;
  53. ray.direction = down;
  54. Vector3 rso = -down * raystartoff;
  55. Vector3 dir = ray.direction;
  56. Vector3 ldir = -transform.InverseTransformDirection(dir);
  57. for ( int i = 0; i < verts.Length; i++ )
  58. {
  59. Vector3 origin = ctm.MultiplyPoint(verts[i]) - rso;
  60. ray.origin = origin;
  61. sverts[i] = verts[i];
  62. if ( conformCollider.Raycast(ray, out hit, raydist) )
  63. {
  64. Vector3 lochit = cinvtm.MultiplyPoint(hit.point);
  65. sverts[i] = Vector3.Lerp(verts[i], lochit + (ldir * (offsets[i] + offset)), conformAmount);
  66. last1[i] = sverts[i];
  67. }
  68. else
  69. sverts[i] = last1[i];
  70. }
  71. }
  72. else
  73. {
  74. int ax = (int)axis;
  75. for ( int i = 0; i < verts.Length; i++ )
  76. {
  77. Vector3 origin = ctm.MultiplyPoint(verts[i]);
  78. origin.y += raystartoff;
  79. ray.origin = origin;
  80. ray.direction = Vector3.down;
  81. sverts[i] = verts[i];
  82. if ( conformCollider.Raycast(ray, out hit, raydist) )
  83. {
  84. Vector3 lochit = cinvtm.MultiplyPoint(hit.point);
  85. sverts[i][ax] = Mathf.Lerp(verts[i][ax], lochit[ax] + offsets[i] + offset, conformAmount);
  86. last[i] = sverts[i][ax];
  87. }
  88. else
  89. sverts[i][ax] = last[i];
  90. }
  91. }
  92. }
  93. else
  94. verts.CopyTo(sverts, 0);
  95. }
  96. public override bool ModLateUpdate(MegaModContext mc)
  97. {
  98. return Prepare(mc);
  99. }
  100. public override bool Prepare(MegaModContext mc)
  101. {
  102. if ( target )
  103. {
  104. if ( conformCollider != target.GetComponent<Collider>() )
  105. conformCollider = target.GetComponent<Collider>();
  106. if ( conformCollider == null )
  107. return false;
  108. if ( conformedVerts == null || conformedVerts.Length != mc.mod.verts.Length )
  109. {
  110. conformedVerts = new Vector3[mc.mod.verts.Length];
  111. // Need to run through all the source meshes and find the vertical offset from the base
  112. offsets = new float[mc.mod.verts.Length];
  113. last = new float[mc.mod.verts.Length];
  114. for ( int i = 0; i < mc.mod.verts.Length; i++ )
  115. offsets[i] = mc.mod.verts[i][(int)axis] - mc.bbox.min[(int)axis];
  116. }
  117. if ( useLocalDown && (last1 == null || last1.Length != last.Length) )
  118. {
  119. last1 = new Vector3[last.Length];
  120. }
  121. loctoworld = transform.localToWorldMatrix;
  122. ctm = loctoworld;
  123. cinvtm = transform.worldToLocalMatrix; //ctm.inverse;
  124. return true;
  125. }
  126. else
  127. conformCollider = null;
  128. return true; //false;
  129. }
  130. public void ChangeAxis()
  131. {
  132. MegaModifyObject mod = GetComponent<MegaModifyObject>();
  133. if ( mod )
  134. {
  135. for ( int i = 0; i < mod.verts.Length; i++ )
  136. offsets[i] = mod.verts[i][(int)axis] - mod.bbox.min[(int)axis];
  137. }
  138. }
  139. }