RamSpline.cs 84 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine.Rendering;
  5. #if VEGETATION_STUDIO
  6. using AwesomeTechnologies;
  7. using AwesomeTechnologies.VegetationStudio;
  8. #endif
  9. #if VEGETATION_STUDIO_PRO
  10. using AwesomeTechnologies.VegetationSystem.Biomes;
  11. #endif
  12. #if UNITY_EDITOR
  13. using UnityEditor;
  14. #endif
  15. [RequireComponent(typeof(MeshFilter))]
  16. public class RamSpline : MonoBehaviour
  17. {
  18. public SplineProfile currentProfile;
  19. public SplineProfile oldProfile;
  20. public List<RamSpline> beginnigChildSplines = new List<RamSpline>();
  21. public List<RamSpline> endingChildSplines = new List<RamSpline>();
  22. public RamSpline beginningSpline;
  23. public RamSpline endingSpline;
  24. public int beginningConnectionID;
  25. public int endingConnectionID;
  26. public float beginningMinWidth = 0.5f;
  27. public float beginningMaxWidth = 1f;
  28. public float endingMinWidth = 0.5f;
  29. public float endingMaxWidth = 1f;
  30. public int toolbarInt = 0;
  31. public bool invertUVDirection = false;
  32. public bool uvRotation = true;
  33. public MeshFilter meshfilter;
  34. public List<Vector4> controlPoints = new List<Vector4>();
  35. public List<Quaternion> controlPointsRotations = new List<Quaternion>();
  36. public List<Quaternion> controlPointsOrientation = new List<Quaternion>();
  37. public List<Vector3> controlPointsUp = new List<Vector3>();
  38. public List<Vector3> controlPointsDown = new List<Vector3>();
  39. public List<float> controlPointsSnap = new List<float>();
  40. public AnimationCurve meshCurve = new AnimationCurve(new Keyframe[] { new Keyframe(0, 0), new Keyframe(1, 0) });
  41. public List<AnimationCurve> controlPointsMeshCurves = new List<AnimationCurve>();
  42. public bool normalFromRaycast = false;
  43. public bool snapToTerrain = false;
  44. public LayerMask snapMask = 1;
  45. public List<Vector3> points = new List<Vector3>();
  46. public List<Vector3> pointsUp = new List<Vector3>();
  47. public List<Vector3> pointsDown = new List<Vector3>();
  48. public List<Vector3> points2 = new List<Vector3>();
  49. public List<Vector3> verticesBeginning = new List<Vector3>();
  50. public List<Vector3> verticesEnding = new List<Vector3>();
  51. public List<Vector3> normalsBeginning = new List<Vector3>();
  52. public List<Vector3> normalsEnding = new List<Vector3>();
  53. public List<float> widths = new List<float>();
  54. public List<float> snaps = new List<float>();
  55. public List<float> lerpValues = new List<float>();
  56. public List<Quaternion> orientations = new List<Quaternion>();
  57. public List<Vector3> tangents = new List<Vector3>();
  58. public List<Vector3> normalsList = new List<Vector3>();
  59. public Color[] colors;
  60. public List<Vector2> colorsFlowMap = new List<Vector2>();
  61. public List<Vector3> verticeDirection = new List<Vector3>();
  62. public float floatSpeed = 10;
  63. public bool generateOnStart = false;
  64. public float minVal = 0.5f;
  65. public float maxVal = 0.5f;
  66. public float width = 4;
  67. public int vertsInShape = 3;
  68. public float traingleDensity = 0.2f;
  69. public float uvScale = 3;
  70. public Material oldMaterial;
  71. public bool showVertexColors;
  72. public bool showFlowMap;
  73. public bool overrideFlowMap = false;
  74. public bool drawOnMesh = false;
  75. public bool drawOnMeshFlowMap = false;
  76. public bool uvScaleOverride = false;
  77. public bool debug = false;
  78. public Color drawColor = Color.black;
  79. public bool drawColorR = true;
  80. public bool drawColorG = true;
  81. public bool drawColorB = true;
  82. public bool drawColorA = true;
  83. public bool drawOnMultiple = false;
  84. public float flowSpeed = 1f;
  85. public float flowDirection = 0f;
  86. public AnimationCurve flowFlat = new AnimationCurve(new Keyframe[] {
  87. new Keyframe (0, 0.025f),
  88. new Keyframe (0.5f, 0.05f),
  89. new Keyframe (1, 0.025f)
  90. });
  91. public AnimationCurve flowWaterfall = new AnimationCurve(new Keyframe[] {
  92. new Keyframe (0, 0.25f),
  93. new Keyframe (1, 0.25f)
  94. });
  95. public bool noiseflowMap = false;
  96. public float noiseMultiplierflowMap = 0.1f;
  97. public float noiseSizeXflowMap = 2f;
  98. public float noiseSizeZflowMap = 2f;
  99. public float opacity = 0.1f;
  100. public float drawSize = 1f;
  101. public float length = 0;
  102. public float fulllength = 0;
  103. public float minMaxWidth;
  104. public float uvWidth;
  105. public float uvBeginning;
  106. public bool receiveShadows = false;
  107. public ShadowCastingMode shadowCastingMode = ShadowCastingMode.Off;
  108. //Part meshes
  109. public bool generateMeshParts = false;
  110. public int meshPartsCount = 3;
  111. public List<Transform> meshesPartTransforms = new List<Transform>();
  112. //Simulate mesh
  113. public float simulatedRiverLength = 100;
  114. public int simulatedRiverPoints = 10;
  115. public float simulatedMinStepSize = 1f;
  116. public bool simulatedNoUp = false;
  117. public bool simulatedBreakOnUp = true;
  118. //Terrain Change
  119. public int detailTerrain = 100;
  120. public int detailTerrainForward = 100;
  121. public float terrainAdditionalWidth = 2;
  122. public float terrainSmoothMultiplier = 5;
  123. public bool overrideRiverRender = false;
  124. public bool noiseWidth = false;
  125. public float noiseMultiplierWidth = 4f;
  126. public float noiseSizeWidth = 0.5f;
  127. public bool noiseCarve = false;
  128. public float noiseMultiplierInside = 1f;
  129. public float noiseMultiplierOutside = 0.25f;
  130. public float noiseSizeX = 0.2f;
  131. public float noiseSizeZ = 0.2f;
  132. public bool noisePaint = false;
  133. public float noiseMultiplierInsidePaint = 0.25f;
  134. public float noiseMultiplierOutsidePaint = 0.25f;
  135. public float noiseSizeXPaint = 0.2f;
  136. public float noiseSizeZPaint = 0.2f;
  137. public AnimationCurve terrainCarve = new AnimationCurve(new Keyframe[] { new Keyframe(0, 0.5f), new Keyframe(10, -4) });
  138. public float distSmooth = 5;
  139. public float distSmoothStart = 1;
  140. public AnimationCurve terrainPaintCarve = new AnimationCurve(new Keyframe[] { new Keyframe(0, 0), new Keyframe(1, 1) });
  141. public int currentSplatMap = 1;
  142. public bool mixTwoSplatMaps = false;
  143. public int secondSplatMap = 1;
  144. public bool addCliffSplatMap = false;
  145. public int cliffSplatMap = 1;
  146. public float cliffAngle = 45;
  147. public float cliffBlend = 1;
  148. public int cliffSplatMapOutside = 1;
  149. public float cliffAngleOutside = 45;
  150. public float cliffBlendOutside = 1;
  151. public float distanceClearFoliage = 1;
  152. public float distanceClearFoliageTrees = 1;
  153. #if VEGETATION_STUDIO_PRO
  154. public float biomMaskResolution = 0.5f;
  155. public float vegetationMaskSize = 3;
  156. public float vegetationBlendDistance = 1f;
  157. public BiomeMaskArea biomeMaskArea;
  158. public bool refreshMask = false;
  159. #endif
  160. #if VEGETATION_STUDIO
  161. public float vegetationMaskPerimeter = 5;
  162. public VegetationMaskArea vegetationMaskArea;
  163. #endif
  164. public GameObject meshGO;
  165. public void Start()
  166. {
  167. if (generateOnStart)
  168. GenerateSpline();
  169. }
  170. /// <summary>
  171. /// Creates spline
  172. /// </summary>
  173. /// <param name="splineMaterial">Material of the spline</param>
  174. /// <param name="positions">Positions to add to the spline</param>
  175. /// <returns></returns>
  176. public static RamSpline CreateSpline(Material splineMaterial = null, List<Vector4> positions = null, string name = "RamSpline")
  177. {
  178. GameObject gameobject = new GameObject(name);
  179. gameobject.layer = LayerMask.NameToLayer("Water");
  180. RamSpline spline = gameobject.AddComponent<RamSpline>();
  181. MeshRenderer meshRenderer = gameobject.AddComponent<MeshRenderer>();
  182. meshRenderer.receiveShadows = false;
  183. meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
  184. if (splineMaterial != null)
  185. meshRenderer.sharedMaterial = splineMaterial;
  186. if (positions != null)
  187. for (int i = 0; i < positions.Count; i++)
  188. {
  189. spline.AddPoint(positions[i]);
  190. }
  191. #if UNITY_EDITOR
  192. Undo.RegisterCreatedObjectUndo(gameobject, "Create river");
  193. #endif
  194. return spline;
  195. }
  196. /// <summary>
  197. /// Add point at end of spline
  198. /// </summary>
  199. /// <param name="position">New point position</param>
  200. public void AddPoint(Vector4 position)
  201. {
  202. if (position.w == 0)
  203. {
  204. if (controlPoints.Count > 0)
  205. position.w = controlPoints[controlPoints.Count - 1].w;
  206. else
  207. position.w = width;
  208. }
  209. controlPointsRotations.Add(Quaternion.identity);
  210. controlPoints.Add(position);
  211. controlPointsSnap.Add(0);
  212. controlPointsMeshCurves.Add(new AnimationCurve(new Keyframe[] { new Keyframe(0, 0), new Keyframe(1, 0) }));
  213. }
  214. /// <summary>
  215. /// Add point in the middle of the spline
  216. /// </summary>
  217. /// <param name="i">Point id</param>
  218. public void AddPointAfter(int i)
  219. {
  220. Vector4 position = controlPoints[i];
  221. if (i < controlPoints.Count - 1 && controlPoints.Count > i + 1)
  222. {
  223. Vector4 positionSecond = controlPoints[i + 1];
  224. if (Vector3.Distance((Vector3)positionSecond, (Vector3)position) > 0)
  225. position = (position + positionSecond) * 0.5f;
  226. else
  227. position.x += 1;
  228. }
  229. else if (controlPoints.Count > 1 && i == controlPoints.Count - 1)
  230. {
  231. Vector4 positionSecond = controlPoints[i - 1];
  232. if (Vector3.Distance((Vector3)positionSecond, (Vector3)position) > 0)
  233. position = position + (position - positionSecond);
  234. else
  235. position.x += 1;
  236. }
  237. else
  238. {
  239. position.x += 1;
  240. }
  241. controlPoints.Insert(i + 1, position);
  242. controlPointsRotations.Insert(i + 1, Quaternion.identity);
  243. controlPointsSnap.Insert(i + 1, 0);
  244. controlPointsMeshCurves.Insert(i + 1, new AnimationCurve(new Keyframe[] {
  245. new Keyframe (0, 0),
  246. new Keyframe (1, 0)
  247. }));
  248. }
  249. /// <summary>
  250. /// Changes point position, if new position doesn't have width old width will be taken
  251. /// </summary>
  252. /// <param name="i">Point id</param>
  253. /// <param name="position">New position</param>
  254. public void ChangePointPosition(int i, Vector3 position)
  255. {
  256. ChangePointPosition(i, new Vector4(position.x, position.y, position.z, 0));
  257. }
  258. /// <summary>
  259. /// Changes point position, if new position doesn't have width old width will be taken
  260. /// </summary>
  261. /// <param name="i">Point id</param>
  262. /// <param name="position">New position</param>
  263. public void ChangePointPosition(int i, Vector4 position)
  264. {
  265. Vector4 oldPos = controlPoints[i];
  266. if (position.w == 0)
  267. position.w = oldPos.w;
  268. controlPoints[i] = position;
  269. }
  270. /// <summary>
  271. /// Removes point in spline
  272. /// </summary>
  273. /// <param name="i"></param>
  274. public void RemovePoint(int i)
  275. {
  276. if (i < controlPoints.Count)
  277. {
  278. controlPoints.RemoveAt(i);
  279. controlPointsRotations.RemoveAt(i);
  280. controlPointsMeshCurves.RemoveAt(i);
  281. controlPointsSnap.RemoveAt(i);
  282. }
  283. }
  284. /// <summary>
  285. /// Removes points from point id forward
  286. /// </summary>
  287. /// <param name="fromID">Point id</param>
  288. public void RemovePoints(int fromID = -1)
  289. {
  290. int pointsCount = controlPoints.Count - 1;
  291. for (int i = pointsCount; i > fromID; i--)
  292. {
  293. RemovePoint(i);
  294. }
  295. }
  296. public void GenerateBeginningParentBased()
  297. {
  298. vertsInShape = (int)Mathf.Round((beginningSpline.vertsInShape - 1) * (beginningMaxWidth - beginningMinWidth) + 1);
  299. if (vertsInShape < 1)
  300. vertsInShape = 1;
  301. beginningConnectionID = beginningSpline.points.Count - 1;
  302. Vector4 pos = beginningSpline.controlPoints[beginningSpline.controlPoints.Count - 1];
  303. float width = pos.w;
  304. width *= beginningMaxWidth - beginningMinWidth;
  305. pos = Vector3.Lerp(beginningSpline.pointsDown[beginningConnectionID], beginningSpline.pointsUp[beginningConnectionID], beginningMinWidth + (beginningMaxWidth - beginningMinWidth) * 0.5f)
  306. + beginningSpline.transform.position - transform.position;
  307. pos.w = width;
  308. controlPoints[0] = pos;
  309. if (!uvScaleOverride)
  310. uvScale = beginningSpline.uvScale;
  311. }
  312. public void GenerateEndingParentBased()
  313. {
  314. if (beginningSpline == null)
  315. {
  316. vertsInShape = (int)Mathf.Round((endingSpline.vertsInShape - 1) * (endingMaxWidth - endingMinWidth) + 1);
  317. if (vertsInShape < 1)
  318. vertsInShape = 1;
  319. }
  320. endingConnectionID = 0;
  321. Vector4 pos = endingSpline.controlPoints[0];
  322. float width = pos.w;
  323. width *= endingMaxWidth - endingMinWidth;
  324. pos = Vector3.Lerp(endingSpline.pointsDown[endingConnectionID], endingSpline.pointsUp[endingConnectionID], endingMinWidth + (endingMaxWidth - endingMinWidth) * 0.5f) + endingSpline.transform.position - transform.position;
  325. pos.w = width;
  326. controlPoints[controlPoints.Count - 1] = pos;
  327. }
  328. public void GenerateSpline(List<RamSpline> generatedSplines = null)
  329. {
  330. generatedSplines = new List<RamSpline>();
  331. if (beginningSpline)
  332. {
  333. GenerateBeginningParentBased();
  334. }
  335. if (endingSpline)
  336. {
  337. GenerateEndingParentBased();
  338. }
  339. List<Vector4> pointsChecked = new List<Vector4>();
  340. for (int i = 0; i < controlPoints.Count; i++)
  341. {
  342. if (i > 0)
  343. {
  344. if (Vector3.Distance((Vector3)controlPoints[i], (Vector3)controlPoints[i - 1]) > 0)
  345. pointsChecked.Add(controlPoints[i]);
  346. }
  347. else
  348. pointsChecked.Add(controlPoints[i]);
  349. }
  350. Mesh mesh = new Mesh();
  351. meshfilter = GetComponent<MeshFilter>();
  352. if (pointsChecked.Count < 2)
  353. {
  354. mesh.Clear();
  355. meshfilter.mesh = mesh;
  356. return;
  357. }
  358. controlPointsOrientation = new List<Quaternion>();
  359. lerpValues.Clear();
  360. snaps.Clear();
  361. points.Clear();
  362. pointsUp.Clear();
  363. pointsDown.Clear();
  364. orientations.Clear();
  365. tangents.Clear();
  366. normalsList.Clear();
  367. widths.Clear();
  368. controlPointsUp.Clear();
  369. controlPointsDown.Clear();
  370. verticesBeginning.Clear();
  371. verticesEnding.Clear();
  372. normalsBeginning.Clear();
  373. normalsEnding.Clear();
  374. if (beginningSpline != null && beginningSpline.controlPointsRotations.Count > 0)
  375. controlPointsRotations[0] = Quaternion.identity;
  376. if (endingSpline != null && endingSpline.controlPointsRotations.Count > 0)
  377. controlPointsRotations[controlPointsRotations.Count - 1] = Quaternion.identity;
  378. for (int i = 0; i < pointsChecked.Count; i++)
  379. {
  380. if (i > pointsChecked.Count - 2)
  381. {
  382. continue;
  383. }
  384. CalculateCatmullRomSideSplines(pointsChecked, i);
  385. }
  386. if (beginningSpline != null && beginningSpline.controlPointsRotations.Count > 0)
  387. controlPointsRotations[0] = Quaternion.Inverse(controlPointsOrientation[0]) * (beginningSpline.controlPointsOrientation[beginningSpline.controlPointsOrientation.Count - 1]);
  388. if (endingSpline != null && endingSpline.controlPointsRotations.Count > 0)
  389. controlPointsRotations[controlPointsRotations.Count - 1] = Quaternion.Inverse(controlPointsOrientation[controlPointsOrientation.Count - 1]) * (endingSpline.controlPointsOrientation[0]);// * endingSpline.controlPointsRotations [0]);
  390. controlPointsOrientation = new List<Quaternion>();
  391. controlPointsUp.Clear();
  392. controlPointsDown.Clear();
  393. for (int i = 0; i < pointsChecked.Count; i++)
  394. {
  395. if (i > pointsChecked.Count - 2)
  396. {
  397. continue;
  398. }
  399. CalculateCatmullRomSideSplines(pointsChecked, i);
  400. }
  401. for (int i = 0; i < pointsChecked.Count; i++)
  402. {
  403. if (i > pointsChecked.Count - 2)
  404. {
  405. continue;
  406. }
  407. CalculateCatmullRomSplineParameters(pointsChecked, i);
  408. }
  409. for (int i = 0; i < controlPointsUp.Count; i++)
  410. {
  411. if (i > controlPointsUp.Count - 2)
  412. {
  413. continue;
  414. }
  415. CalculateCatmullRomSpline(controlPointsUp, i, ref pointsUp);
  416. }
  417. for (int i = 0; i < controlPointsDown.Count; i++)
  418. {
  419. if (i > controlPointsDown.Count - 2)
  420. {
  421. continue;
  422. }
  423. CalculateCatmullRomSpline(controlPointsDown, i, ref pointsDown);
  424. }
  425. GenerateMesh(ref mesh);
  426. if (generatedSplines != null)
  427. {
  428. generatedSplines.Add(this);
  429. foreach (var item in beginnigChildSplines)
  430. {
  431. if (item != null && !generatedSplines.Contains(item))
  432. {
  433. if (item.beginningSpline == this || item.endingSpline == this)
  434. {
  435. item.GenerateSpline(generatedSplines);
  436. }
  437. }
  438. }
  439. foreach (var item in endingChildSplines)
  440. {
  441. if (item != null && !generatedSplines.Contains(item))
  442. {
  443. if (item.beginningSpline == this || item.endingSpline == this)
  444. {
  445. item.GenerateSpline(generatedSplines);
  446. }
  447. }
  448. }
  449. }
  450. }
  451. void CalculateCatmullRomSideSplines(List<Vector4> controlPoints, int pos)
  452. {
  453. Vector3 p0 = controlPoints[pos];
  454. Vector3 p1 = controlPoints[pos];
  455. Vector3 p2 = controlPoints[ClampListPos(pos + 1)];
  456. Vector3 p3 = controlPoints[ClampListPos(pos + 1)];
  457. if (pos > 0)
  458. p0 = controlPoints[ClampListPos(pos - 1)];
  459. if (pos < controlPoints.Count - 2)
  460. p3 = controlPoints[ClampListPos(pos + 2)];
  461. int tValueMax = 0;
  462. if (pos == controlPoints.Count - 2)
  463. {
  464. tValueMax = 1;
  465. }
  466. for (int tValue = 0; tValue <= tValueMax; tValue++)
  467. {
  468. Vector3 newPos = GetCatmullRomPosition(tValue, p0, p1, p2, p3);
  469. Vector3 tangent = GetCatmullRomTangent(tValue, p0, p1, p2, p3).normalized;
  470. Vector3 normal = CalculateNormal(tangent, Vector3.up).normalized;
  471. Quaternion orientation;
  472. if (normal == tangent && normal == Vector3.zero)
  473. orientation = Quaternion.identity;
  474. else
  475. orientation = Quaternion.LookRotation(tangent, normal);
  476. orientation *= Quaternion.Lerp(controlPointsRotations[pos], controlPointsRotations[ClampListPos(pos + 1)], tValue);
  477. // if (beginningSpline && pos == 0) {
  478. //
  479. // int lastId = beginningSpline.controlPointsOrientation.Count - 1;
  480. // //orientation = beginningSpline.controlPointsOrientation [lastId];
  481. //
  482. // }
  483. //
  484. // if (endingSpline && pos == controlPoints.Count - 2 && tValue == 1) {
  485. //
  486. // //orientation = endingSpline.controlPointsOrientation [0];
  487. //
  488. // }
  489. controlPointsOrientation.Add(orientation);
  490. Vector3 posUp = newPos + orientation * (0.5f * controlPoints[pos + tValue].w * Vector3.right);
  491. Vector3 posDown = newPos + orientation * (0.5f * controlPoints[pos + tValue].w * Vector3.left);
  492. controlPointsUp.Add(posUp);
  493. controlPointsDown.Add(posDown);
  494. }
  495. }
  496. void CalculateCatmullRomSplineParameters(List<Vector4> controlPoints, int pos, bool initialPoints = false)
  497. {
  498. Vector3 p0 = controlPoints[pos];
  499. Vector3 p1 = controlPoints[pos];
  500. Vector3 p2 = controlPoints[ClampListPos(pos + 1)];
  501. Vector3 p3 = controlPoints[ClampListPos(pos + 1)];
  502. if (pos > 0)
  503. p0 = controlPoints[ClampListPos(pos - 1)];
  504. if (pos < controlPoints.Count - 2)
  505. p3 = controlPoints[ClampListPos(pos + 2)];
  506. int loops = Mathf.FloorToInt(1f / traingleDensity);
  507. float i = 1;
  508. float start = 0;
  509. if (pos > 0)
  510. start = 1;
  511. for (i = start; i <= loops; i++)
  512. {
  513. float t = i * traingleDensity;
  514. CalculatePointParameters(controlPoints, pos, p0, p1, p2, p3, t);
  515. }
  516. if (i < loops)
  517. {
  518. i = loops;
  519. float t = i * traingleDensity;
  520. CalculatePointParameters(controlPoints, pos, p0, p1, p2, p3, t);
  521. }
  522. }
  523. void CalculateCatmullRomSpline(List<Vector3> controlPoints, int pos, ref List<Vector3> points)
  524. {
  525. Vector3 p0 = controlPoints[pos];
  526. Vector3 p1 = controlPoints[pos];
  527. Vector3 p2 = controlPoints[ClampListPos(pos + 1)];
  528. Vector3 p3 = controlPoints[ClampListPos(pos + 1)];
  529. if (pos > 0)
  530. p0 = controlPoints[ClampListPos(pos - 1)];
  531. if (pos < controlPoints.Count - 2)
  532. p3 = controlPoints[ClampListPos(pos + 2)];
  533. int loops = Mathf.FloorToInt(1f / traingleDensity);
  534. float i = 1;
  535. float start = 0;
  536. if (pos > 0)
  537. start = 1;
  538. for (i = start; i <= loops; i++)
  539. {
  540. float t = i * traingleDensity;
  541. CalculatePointPosition(controlPoints, pos, p0, p1, p2, p3, t, ref points);
  542. }
  543. if (i < loops)
  544. {
  545. i = loops;
  546. float t = i * traingleDensity;
  547. CalculatePointPosition(controlPoints, pos, p0, p1, p2, p3, t, ref points);
  548. }
  549. }
  550. void CalculatePointPosition(List<Vector3> controlPoints, int pos, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t, ref List<Vector3> points)
  551. {
  552. Vector3 newPos = GetCatmullRomPosition(t, p0, p1, p2, p3);
  553. points.Add(newPos);
  554. Vector3 tangent = GetCatmullRomTangent(t, p0, p1, p2, p3).normalized;
  555. Vector3 normal = CalculateNormal(tangent, Vector3.up).normalized;
  556. }
  557. void CalculatePointParameters(List<Vector4> controlPoints, int pos, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
  558. {
  559. Vector3 newPos = GetCatmullRomPosition(t, p0, p1, p2, p3);
  560. widths.Add(Mathf.Lerp(controlPoints[pos].w, controlPoints[ClampListPos(pos + 1)].w, t));
  561. if (controlPointsSnap.Count > pos + 1)
  562. snaps.Add(Mathf.Lerp(controlPointsSnap[pos], controlPointsSnap[ClampListPos(pos + 1)], t));
  563. else
  564. snaps.Add(0);
  565. lerpValues.Add(pos + t);
  566. points.Add(newPos);
  567. Vector3 tangent = GetCatmullRomTangent(t, p0, p1, p2, p3).normalized;
  568. Vector3 normal = CalculateNormal(tangent, Vector3.up).normalized;
  569. // Debug.Log(tangent + " CalculatePointParameters: " + normal);
  570. Quaternion orientation;
  571. if (normal == tangent && normal == Vector3.zero)
  572. orientation = Quaternion.identity;
  573. else
  574. orientation = Quaternion.LookRotation(tangent, normal);
  575. orientation *= Quaternion.Lerp(controlPointsRotations[pos], controlPointsRotations[ClampListPos(pos + 1)], t);
  576. orientations.Add(orientation);
  577. tangents.Add(tangent);
  578. if (normalsList.Count > 0 && Vector3.Angle(normalsList[normalsList.Count - 1], normal) > 90)
  579. {
  580. normal *= -1;
  581. }
  582. normalsList.Add(normal);
  583. }
  584. int ClampListPos(int pos)
  585. {
  586. if (pos < 0)
  587. {
  588. pos = controlPoints.Count - 1;
  589. }
  590. if (pos > controlPoints.Count)
  591. {
  592. pos = 1;
  593. }
  594. else if (pos > controlPoints.Count - 1)
  595. {
  596. pos = 0;
  597. }
  598. return pos;
  599. }
  600. Vector3 GetCatmullRomPosition(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
  601. {
  602. Vector3 a = 2f * p1;
  603. Vector3 b = p2 - p0;
  604. Vector3 c = 2f * p0 - 5f * p1 + 4f * p2 - p3;
  605. Vector3 d = -p0 + 3f * p1 - 3f * p2 + p3;
  606. Vector3 pos = 0.5f * (a + (b * t) + (c * t * t) + (d * t * t * t));
  607. return pos;
  608. }
  609. Vector3 GetCatmullRomTangent(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
  610. {
  611. return 0.5f * ((-p0 + p2) + 2f * (2f * p0 - 5f * p1 + 4f * p2 - p3) * t + 3f * (-p0 + 3f * p1 - 3f * p2 + p3) * t * t);
  612. }
  613. Vector3 CalculateNormal(Vector3 tangent, Vector3 up)
  614. {
  615. Vector3 binormal = Vector3.Cross(up, tangent);
  616. return Vector3.Cross(tangent, binormal);
  617. }
  618. void GenerateMesh(ref Mesh mesh)
  619. {
  620. MeshRenderer meshRenderer = gameObject.GetComponent<MeshRenderer>();
  621. if (meshRenderer != null)
  622. {
  623. meshRenderer.receiveShadows = receiveShadows;
  624. meshRenderer.shadowCastingMode = shadowCastingMode;
  625. }
  626. foreach (var item in meshesPartTransforms)
  627. {
  628. if (item != null)
  629. {
  630. #if UNITY_EDITOR
  631. if (EditorApplication.isPlaying)
  632. Destroy(item.gameObject);
  633. else
  634. DestroyImmediate(item.gameObject);
  635. #else
  636. Destroy(item.gameObject);
  637. #endif
  638. }
  639. }
  640. int segments = points.Count - 1;
  641. int edgeLoops = points.Count;
  642. int vertCount = vertsInShape * edgeLoops;
  643. List<int> triangleIndices = new List<int>();
  644. Vector3[] vertices = new Vector3[vertCount];
  645. Vector3[] normals = new Vector3[vertCount];
  646. Vector2[] uvs = new Vector2[vertCount];
  647. Vector2[] uvs3 = new Vector2[vertCount];
  648. Vector2[] uvs4 = new Vector2[vertCount];
  649. if (colors == null || colors.Length != vertCount)
  650. {
  651. colors = new Color[vertCount];
  652. for (int i = 0; i < colors.Length; i++)
  653. {
  654. colors[i] = Color.black;
  655. }
  656. }
  657. if (colorsFlowMap.Count != vertCount)
  658. colorsFlowMap.Clear();
  659. length = 0;
  660. fulllength = 0;
  661. if (beginningSpline != null)
  662. length = beginningSpline.length;
  663. minMaxWidth = 1;
  664. uvWidth = 1;
  665. uvBeginning = 0;
  666. if (beginningSpline != null)
  667. {
  668. minMaxWidth = beginningMaxWidth - beginningMinWidth;
  669. uvWidth = minMaxWidth * beginningSpline.uvWidth;
  670. uvBeginning = beginningSpline.uvWidth * beginningMinWidth + beginningSpline.uvBeginning;
  671. }
  672. else if (endingSpline != null)
  673. {
  674. minMaxWidth = endingMaxWidth - endingMinWidth;
  675. uvWidth = minMaxWidth * endingSpline.uvWidth;
  676. uvBeginning = endingSpline.uvWidth * endingMinWidth + endingSpline.uvBeginning;
  677. }
  678. for (int i = 0; i < pointsDown.Count; i++)
  679. {
  680. float width = widths[i];
  681. if (i > 0)
  682. fulllength += uvWidth * Vector3.Distance(pointsDown[i], pointsDown[i - 1]) / (float)(uvScale * width);
  683. }
  684. float roundEnding = Mathf.Round(fulllength);
  685. for (int i = 0; i < pointsDown.Count; i++)
  686. {
  687. float width = widths[i];
  688. int offset = i * vertsInShape;
  689. if (i > 0)
  690. {
  691. length += (uvWidth * Vector3.Distance(pointsDown[i], pointsDown[i - 1]) / (float)(uvScale * width)) / fulllength * roundEnding;
  692. }
  693. float u = 0;
  694. float u3 = 0;
  695. for (int j = 0; j < vertsInShape; j++)
  696. {
  697. int id = offset + j;
  698. //VERTICES
  699. float pos = j / (float)(vertsInShape - 1);
  700. if (pos < 0.5f)
  701. pos *= minVal * 2;
  702. else
  703. pos = ((pos - 0.5f) * (1 - maxVal) + 0.5f * maxVal) * 2;
  704. if (i == 0 && beginningSpline != null && beginningSpline.verticesEnding != null && beginningSpline.normalsEnding != null)
  705. {
  706. int pos2 = (int)(beginningSpline.vertsInShape * beginningMinWidth);
  707. vertices[id] = beginningSpline.verticesEnding[Mathf.Clamp(j + pos2, 0, beginningSpline.verticesEnding.Count - 1)] + beginningSpline.transform.position - transform.position;
  708. //if (beginningSpline.normalsEnding.Count > 0)
  709. // normals [id] = beginningSpline.normalsEnding [Mathf.Clamp (j + pos2, 0, beginningSpline.normalsEnding.Count - 1)];
  710. }
  711. else if (i == pointsDown.Count - 1 && endingSpline != null && endingSpline.verticesBeginning != null && endingSpline.verticesBeginning.Count > 0 && endingSpline.normalsBeginning != null)
  712. {
  713. int pos2 = (int)(endingSpline.vertsInShape * endingMinWidth);
  714. vertices[id] = endingSpline.verticesBeginning[Mathf.Clamp(j + pos2, 0, endingSpline.verticesBeginning.Count - 1)] + endingSpline.transform.position - transform.position;
  715. //if (endingSpline.normalsBeginning.Count > 0)
  716. // normals [id] = endingSpline.normalsBeginning [Mathf.Clamp (j + pos2, 0, endingSpline.normalsBeginning.Count - 1)];
  717. }
  718. else
  719. {
  720. vertices[id] = Vector3.Lerp(pointsDown[i], pointsUp[i], pos);
  721. RaycastHit hit;
  722. if (Physics.Raycast(vertices[id] + transform.position + Vector3.up * 5, Vector3.down, out hit, 1000, snapMask.value))
  723. {
  724. vertices[id] = Vector3.Lerp(vertices[id], hit.point - transform.position + new Vector3(0, 0.1f, 0), (Mathf.Sin(Mathf.PI * snaps[i] - Mathf.PI * 0.5f) + 1) * 0.5f);
  725. }
  726. if (normalFromRaycast)
  727. {
  728. RaycastHit hit2;
  729. if (Physics.Raycast(points[i] + transform.position + Vector3.up * 5, Vector3.down, out hit2, 1000, snapMask.value))
  730. {
  731. normals[id] = hit2.normal;
  732. }
  733. }
  734. vertices[id].y += Mathf.Lerp(controlPointsMeshCurves[Mathf.FloorToInt(lerpValues[i])].Evaluate(pos),
  735. controlPointsMeshCurves[Mathf.CeilToInt(lerpValues[i])].Evaluate(pos),
  736. lerpValues[i] - Mathf.Floor(lerpValues[i]));
  737. }
  738. if (i > 0 && i < 5 && beginningSpline != null && beginningSpline.verticesEnding != null)
  739. {
  740. vertices[id].y = (vertices[id].y + vertices[id - vertsInShape].y) * 0.5f;
  741. }
  742. if (i == pointsDown.Count - 1 && endingSpline != null && endingSpline.verticesBeginning != null)
  743. {
  744. for (int k = 1; k < 5; k++)
  745. {
  746. vertices[id - vertsInShape * k].y = (vertices[id - vertsInShape * (k - 1)].y + vertices[id - vertsInShape * k].y) * 0.5f;
  747. }
  748. }
  749. if (i == 0)
  750. verticesBeginning.Add(vertices[id]);
  751. if (i == pointsDown.Count - 1)
  752. verticesEnding.Add(vertices[id]);
  753. //NORMALS
  754. if (!normalFromRaycast)
  755. // if ((i > 0 || beginningSpline == null) && (i < pointsDown.Count - 1 || endingSpline == null))
  756. normals[id] = orientations[i] * Vector3.up;
  757. //if (beginningSpline != null && i == 1)
  758. // normals [id] = (normals [id] + normals [id - vertsInShape]) * 0.5f;
  759. //
  760. //if (i == pointsDown.Count - 2 && endingSpline != null && endingSpline.normalsBeginning != null && endingSpline.normalsBeginning.Count > 0) {
  761. //
  762. // int pos2 = (int)(endingSpline.vertsInShape * endingMinWidth);
  763. // normals [id] = (normals [id] + endingSpline.normalsBeginning [Mathf.Clamp (j + pos2, 0, endingSpline.normalsBeginning.Count - 1)]) * 0.5f;
  764. //
  765. //}
  766. if (i == 0)
  767. normalsBeginning.Add(normals[id]);
  768. if (i == pointsDown.Count - 1)
  769. normalsEnding.Add(normals[id]);
  770. //UVS
  771. if (j > 0)
  772. {
  773. u = (pos) * uvWidth;
  774. u3 = pos;
  775. }
  776. if (beginningSpline != null || endingSpline != null)
  777. {
  778. u += uvBeginning;
  779. }
  780. u = u / uvScale;
  781. float uv4u = FlowCalculate(u3, normals[id].y, vertices[id]);
  782. int lerpDistance = 10;
  783. if (beginnigChildSplines.Count > 0 && i <= lerpDistance)
  784. {
  785. float lerpUv4u = 0;
  786. foreach (var item in beginnigChildSplines)
  787. {
  788. if (item == null)
  789. continue;
  790. if (Mathf.CeilToInt(item.endingMaxWidth * (vertsInShape - 1)) >= j && j >= Mathf.CeilToInt(item.endingMinWidth * (vertsInShape - 1)))
  791. {
  792. lerpUv4u = (j - Mathf.CeilToInt(item.endingMinWidth * (vertsInShape - 1)))
  793. / (float)(Mathf.CeilToInt(item.endingMaxWidth * (vertsInShape - 1)) - Mathf.CeilToInt(item.endingMinWidth * (vertsInShape - 1)));
  794. lerpUv4u = FlowCalculate(lerpUv4u, normals[id].y, vertices[id]);
  795. }
  796. }
  797. if (i > 0)
  798. uv4u = Mathf.Lerp(uv4u, lerpUv4u, 1 - (i / (float)lerpDistance));
  799. else
  800. uv4u = lerpUv4u;
  801. }
  802. if (i >= pointsDown.Count - lerpDistance - 1 && endingChildSplines.Count > 0)
  803. {
  804. float lerpUv4u = 0;
  805. foreach (var item in endingChildSplines)
  806. {
  807. if (item == null)
  808. continue;
  809. if (Mathf.CeilToInt(item.beginningMaxWidth * (vertsInShape - 1)) >= j && j >= Mathf.CeilToInt(item.beginningMinWidth * (vertsInShape - 1)))
  810. {
  811. lerpUv4u = (j - Mathf.CeilToInt(item.beginningMinWidth * (vertsInShape - 1)))
  812. / (float)(Mathf.CeilToInt(item.beginningMaxWidth * (vertsInShape - 1)) - Mathf.CeilToInt(item.beginningMinWidth * (vertsInShape - 1)));
  813. lerpUv4u = FlowCalculate(lerpUv4u, normals[id].y, vertices[id]);
  814. }
  815. }
  816. if (i < pointsDown.Count - 1)
  817. uv4u = Mathf.Lerp(uv4u, lerpUv4u, (i - (pointsDown.Count - lerpDistance - 1)) / (float)lerpDistance);
  818. else
  819. uv4u = lerpUv4u;
  820. }
  821. float uv4v = -(u3 - 0.5f) * 0.01f;
  822. if (uvRotation)
  823. {
  824. if (!invertUVDirection)
  825. {
  826. uvs[id] = new Vector2(1 - length, u);
  827. uvs3[id] = new Vector2(1 - length / (float)fulllength, u3);
  828. uvs4[id] = new Vector2(uv4u, uv4v);
  829. }
  830. else
  831. {
  832. uvs[id] = new Vector2(1 + length, u);
  833. uvs3[id] = new Vector2(1 + length / (float)fulllength, u3);
  834. uvs4[id] = new Vector2(uv4u, uv4v);
  835. }
  836. }
  837. else
  838. {
  839. if (!invertUVDirection)
  840. {
  841. uvs[id] = new Vector2(u, 1 - length);
  842. uvs3[id] = new Vector2(u3, 1 - length / (float)fulllength);
  843. uvs4[id] = new Vector2(uv4v, uv4u);
  844. }
  845. else
  846. {
  847. uvs[id] = new Vector2(u, 1 + length);
  848. uvs3[id] = new Vector2(u3, 1 + length / (float)fulllength);
  849. uvs4[id] = new Vector2(uv4v, uv4u);
  850. }
  851. }
  852. float tempRound = (int)(uvs4[id].x * 100);
  853. uvs4[id].x = tempRound * 0.01f;
  854. tempRound = (int)(uvs4[id].y * 100);
  855. uvs4[id].y = tempRound * 0.01f;
  856. if (colorsFlowMap.Count <= id)
  857. colorsFlowMap.Add(uvs4[id]);
  858. else if (!overrideFlowMap)
  859. colorsFlowMap[id] = uvs4[id];
  860. }
  861. }
  862. //TRIANGLES
  863. for (int i = 0; i < segments; i++)
  864. {
  865. int offset = i * vertsInShape;
  866. for (int l = 0; l < vertsInShape - 1; l += 1)
  867. {
  868. int a = offset + l;
  869. int b = offset + l + vertsInShape;
  870. int c = offset + l + 1 + vertsInShape;
  871. int d = offset + l + 1;
  872. triangleIndices.Add(a);
  873. triangleIndices.Add(b);
  874. triangleIndices.Add(c);
  875. triangleIndices.Add(c);
  876. triangleIndices.Add(d);
  877. triangleIndices.Add(a);
  878. }
  879. }
  880. verticeDirection.Clear();
  881. for (int i = 0; i < vertices.Length - vertsInShape; i++)
  882. {
  883. Vector3 dir = (vertices[i + vertsInShape] - vertices[i]).normalized;
  884. if (uvRotation)
  885. dir = new Vector3(dir.z, 0, -dir.x);
  886. verticeDirection.Add(dir);
  887. }
  888. for (int i = vertices.Length - vertsInShape; i < vertices.Length; i++)
  889. {
  890. Vector3 dir = (vertices[i] - vertices[i - vertsInShape]).normalized;
  891. if (uvRotation)
  892. dir = new Vector3(dir.z, 0, -dir.x);
  893. verticeDirection.Add(dir);
  894. }
  895. mesh = new Mesh();
  896. mesh.Clear();
  897. mesh.vertices = vertices;
  898. mesh.normals = normals;
  899. mesh.uv = uvs;
  900. mesh.uv3 = uvs3;
  901. mesh.uv4 = colorsFlowMap.ToArray();
  902. mesh.triangles = triangleIndices.ToArray();
  903. mesh.colors = colors;
  904. mesh.RecalculateTangents();
  905. meshfilter.mesh = mesh;
  906. GetComponent<MeshRenderer>().enabled = true;
  907. if (generateMeshParts)
  908. GenerateMeshParts(mesh);
  909. }
  910. public void GenerateMeshParts(Mesh baseMesh)
  911. {
  912. foreach (var item in meshesPartTransforms)
  913. {
  914. if (item != null)
  915. DestroyImmediate(item.gameObject);
  916. }
  917. Vector3[] vertices = baseMesh.vertices;
  918. Vector3[] normals = baseMesh.normals;
  919. Vector2[] uvs = baseMesh.uv;
  920. Vector2[] uvs3 = baseMesh.uv3;
  921. GetComponent<MeshRenderer>().enabled = false;
  922. int verticesLinesPart = Mathf.RoundToInt((vertices.Length / vertsInShape) / (float)meshPartsCount);
  923. int verticesInPart = verticesLinesPart * vertsInShape;
  924. for (int i = 0; i < meshPartsCount; i++)
  925. {
  926. GameObject go = new GameObject(gameObject.name + "- Mesh part " + i);
  927. go.transform.SetParent(gameObject.transform, false);
  928. go.transform.localPosition = Vector3.zero;
  929. go.transform.localEulerAngles = Vector3.zero;
  930. go.transform.localScale = Vector3.one;
  931. meshesPartTransforms.Add(go.transform);
  932. MeshRenderer meshRendererPart = go.AddComponent<MeshRenderer>();
  933. meshRendererPart.sharedMaterial = GetComponent<MeshRenderer>().sharedMaterial;
  934. meshRendererPart.receiveShadows = receiveShadows;
  935. meshRendererPart.shadowCastingMode = shadowCastingMode;
  936. MeshFilter mf = go.AddComponent<MeshFilter>();
  937. Mesh meshPart = new Mesh();
  938. meshPart.Clear();
  939. List<Vector3> verticesPart = new List<Vector3>();
  940. List<Vector3> normalsPart = new List<Vector3>();
  941. List<Vector2> uvPart = new List<Vector2>();
  942. List<Vector2> uv3Part = new List<Vector2>();
  943. List<Vector2> uv4Part = new List<Vector2>();
  944. List<Color> colorsPart = new List<Color>();
  945. List<int> trianglesPart = new List<int>();
  946. for (int j = verticesInPart * i + (i > 0 ? -vertsInShape : 0); (j < verticesInPart * (i + 1) && j < vertices.Length) || (i == meshPartsCount - 1 && j < vertices.Length); j++)
  947. {
  948. verticesPart.Add(vertices[j]);
  949. normalsPart.Add(normals[j]);
  950. uvPart.Add(uvs[j]);
  951. uv3Part.Add(uvs3[j]);
  952. uv4Part.Add(colorsFlowMap[j]);
  953. colorsPart.Add(colors[j]);
  954. }
  955. if (verticesPart.Count > 0)
  956. {
  957. Vector3 pivotChange = verticesPart[0];
  958. for (int j = 0; j < verticesPart.Count; j++)
  959. {
  960. verticesPart[j] = verticesPart[j] - pivotChange;
  961. }
  962. for (int k = 0; k < verticesPart.Count / vertsInShape - 1; k++)
  963. {
  964. int offset = k * vertsInShape;
  965. for (int l = 0; l < vertsInShape - 1; l += 1)
  966. {
  967. int a = offset + l;
  968. int b = offset + l + vertsInShape;
  969. int c = offset + l + 1 + vertsInShape;
  970. int d = offset + l + 1;
  971. trianglesPart.Add(a);
  972. trianglesPart.Add(b);
  973. trianglesPart.Add(c);
  974. trianglesPart.Add(c);
  975. trianglesPart.Add(d);
  976. trianglesPart.Add(a);
  977. }
  978. }
  979. go.transform.position += pivotChange;
  980. meshPart.vertices = verticesPart.ToArray();
  981. meshPart.triangles = trianglesPart.ToArray();
  982. meshPart.normals = normalsPart.ToArray();
  983. meshPart.uv = uvPart.ToArray();
  984. meshPart.uv3 = uv3Part.ToArray();
  985. meshPart.uv4 = uv4Part.ToArray();
  986. meshPart.colors = colorsPart.ToArray();
  987. meshPart.RecalculateTangents();
  988. mf.mesh = meshPart;
  989. //MeshCollider meshCollider = go.AddComponent<MeshCollider>();
  990. //meshCollider.cookingOptions = MeshColliderCookingOptions.InflateConvexMesh | MeshColliderCookingOptions.CookForFasterSimulation | MeshColliderCookingOptions.EnableMeshCleaning | MeshColliderCookingOptions.WeldColocatedVertices;
  991. //meshCollider.skinWidth = 0.1f;
  992. //meshCollider.convex = true;
  993. //meshCollider.isTrigger = true;
  994. }
  995. }
  996. }
  997. public void AddNoiseToWidths()
  998. {
  999. for (int i = 0; i < controlPoints.Count; i++)
  1000. {
  1001. Vector4 controlPoint = controlPoints[i];
  1002. controlPoint.w = controlPoint.w + (noiseWidth ? noiseMultiplierWidth * (Mathf.PerlinNoise(noiseSizeWidth * i, 0) - 0.5f) : 0);
  1003. if (controlPoint.w < 0)
  1004. {
  1005. controlPoint.w = 0;
  1006. }
  1007. controlPoints[i] = controlPoint;
  1008. }
  1009. }
  1010. public void SimulateRiver(bool generate = true)
  1011. {
  1012. if (meshGO != null)
  1013. {
  1014. if (Application.isEditor)
  1015. DestroyImmediate(meshGO);
  1016. else
  1017. Destroy(meshGO);
  1018. }
  1019. if (controlPoints.Count == 0)
  1020. {
  1021. Debug.Log("Add one point to start Simulating River");
  1022. return;
  1023. }
  1024. Ray ray = new Ray();
  1025. RaycastHit hit;
  1026. Vector3 lastPosition = transform.TransformPoint((Vector3)controlPoints[controlPoints.Count - 1]);
  1027. List<Vector3> positionsGenerated = new List<Vector3>();
  1028. if (controlPoints.Count > 1)
  1029. {
  1030. positionsGenerated.Add(transform.TransformPoint((Vector3)controlPoints[controlPoints.Count - 2]));
  1031. positionsGenerated.Add(lastPosition);
  1032. }
  1033. List<Vector3> samplePositionsGenerated = new List<Vector3>();
  1034. samplePositionsGenerated.Add(lastPosition);
  1035. //Debug.DrawRay(lastPosition + new Vector3(0, 3, 0), Vector3.down * 20, Color.white, 3);
  1036. float length = 0;
  1037. int i = -1;
  1038. int added = 0;
  1039. bool end = false;
  1040. float widthNew = 0;
  1041. if (controlPoints.Count > 0)
  1042. widthNew = controlPoints[controlPoints.Count - 1].w;
  1043. else
  1044. widthNew = width;
  1045. do
  1046. {
  1047. i++;
  1048. if (i > 0)
  1049. {
  1050. Vector3 maxPosition = Vector3.zero;
  1051. float max = float.MinValue;
  1052. bool foundNextPositon = false;
  1053. for (float j = simulatedMinStepSize; j < 10; j += 0.1f)
  1054. {
  1055. for (int angle = 0; angle < 36; angle++)
  1056. {
  1057. float x = j * Mathf.Cos(angle);
  1058. float z = j * Mathf.Sin(angle);
  1059. ray.origin = lastPosition + new Vector3(0, 1000, 0) + new Vector3(x, 0, z);
  1060. ray.direction = Vector3.down;
  1061. if (Physics.Raycast(ray, out hit, 10000))
  1062. {
  1063. if (hit.distance > max)
  1064. {
  1065. bool goodPoint = true;
  1066. foreach (var item in positionsGenerated)
  1067. {
  1068. if (Vector3.Distance(item, lastPosition) > Vector3.Distance(item, hit.point) + 0.5f)
  1069. {
  1070. goodPoint = false;
  1071. break;
  1072. }
  1073. }
  1074. if (goodPoint)
  1075. {
  1076. foundNextPositon = true;
  1077. max = hit.distance;
  1078. maxPosition = hit.point;
  1079. }
  1080. }
  1081. //else
  1082. // Debug.DrawRay(ray.origin, ray.direction * 10000, Color.red, 3);
  1083. }
  1084. }
  1085. if (foundNextPositon)
  1086. break;
  1087. }
  1088. if (!foundNextPositon)
  1089. break;
  1090. if (maxPosition.y > lastPosition.y)
  1091. {
  1092. if (simulatedNoUp)
  1093. maxPosition.y = lastPosition.y;
  1094. if (simulatedBreakOnUp)
  1095. end = true;
  1096. //Debug.DrawRay(maxPosition + new Vector3(0, 5, 0), ray.direction * 10, Color.red, 3);
  1097. }
  1098. // else
  1099. // Debug.DrawRay(maxPosition + new Vector3(0, 5, 0), ray.direction * 10, Color.blue, 3);
  1100. length += Vector3.Distance(maxPosition, lastPosition);
  1101. if (i % simulatedRiverPoints == 0 || simulatedRiverLength <= length || end)
  1102. {
  1103. //Debug.DrawRay(maxPosition + new Vector3(0, 5, 0), ray.direction * 20, Color.white, 3);
  1104. samplePositionsGenerated.Add(maxPosition);
  1105. if (generate)
  1106. {
  1107. added++;
  1108. Vector4 newPosition = maxPosition - transform.position;
  1109. newPosition.w = widthNew + (noiseWidth ? noiseMultiplierWidth * (Mathf.PerlinNoise(noiseSizeWidth * added, 0) - 0.5f) : 0);
  1110. controlPointsRotations.Add(Quaternion.identity);
  1111. controlPoints.Add(newPosition);
  1112. controlPointsSnap.Add(0);
  1113. controlPointsMeshCurves.Add(new AnimationCurve(meshCurve.keys));
  1114. }
  1115. }
  1116. else
  1117. {
  1118. //samplePositionsGenerated.Add(maxPosition);
  1119. //Debug.DrawRay(maxPosition + new Vector3(0, 3, 0), ray.direction * 20, Color.Lerp(Color.red, Color.green, i / (float)spline.simulatedRiverLength), 3);
  1120. }
  1121. positionsGenerated.Add(lastPosition);
  1122. lastPosition = maxPosition;
  1123. }
  1124. } while (simulatedRiverLength > length && !end);
  1125. if (!generate)
  1126. {
  1127. if (controlPoints.Count > 0)
  1128. widthNew = controlPoints[controlPoints.Count - 1].w;
  1129. else
  1130. widthNew = width;
  1131. float widthNoise = 0;
  1132. List<List<Vector4>> positionArray = new List<List<Vector4>>();
  1133. Vector3 v1 = new Vector3();
  1134. for (i = 0; i < samplePositionsGenerated.Count - 1; i++)
  1135. {
  1136. widthNoise = widthNew + (noiseWidth ? noiseMultiplierWidth * (Mathf.PerlinNoise(noiseSizeWidth * i, 0) - 0.5f) : 0);
  1137. //Debug.DrawLine(samplePositionsGenerated[i], samplePositionsGenerated[i + 1], Color.white, 3);
  1138. v1 = Vector3.Cross(samplePositionsGenerated[i + 1] - samplePositionsGenerated[i], Vector3.up).normalized;
  1139. if (i > 0)
  1140. {
  1141. Vector3 v2 = Vector3.Cross(samplePositionsGenerated[i] - samplePositionsGenerated[i - 1], Vector3.up).normalized;
  1142. v1 = (v1 + v2).normalized;
  1143. }
  1144. //Vector3 v2 = Vector3.Cross(samplePositionsGenerated[i + 1] - samplePositionsGenerated[i], v1).normalized;
  1145. //Debug.DrawLine(samplePositionsGenerated[i] - v1 * widthNew * 0.5f, samplePositionsGenerated[i] + v1 * widthNew * 0.5f, Color.blue, 3);
  1146. List<Vector4> positionRow = new List<Vector4>();
  1147. positionRow.Add(samplePositionsGenerated[i] + v1 * widthNoise * 0.5f);
  1148. positionRow.Add(samplePositionsGenerated[i] - v1 * widthNoise * 0.5f);
  1149. positionArray.Add(positionRow);
  1150. }
  1151. widthNoise = widthNew + (noiseWidth ? noiseMultiplierWidth * (Mathf.PerlinNoise(noiseSizeWidth * i, 0) - 0.5f) : 0);
  1152. List<Vector4> positionRowLast = new List<Vector4>();
  1153. positionRowLast.Add(samplePositionsGenerated[i] + v1 * widthNoise * 0.5f);
  1154. positionRowLast.Add(samplePositionsGenerated[i] - v1 * widthNoise * 0.5f);
  1155. positionArray.Add(positionRowLast);
  1156. Mesh meshTerrain = new Mesh();
  1157. meshTerrain.indexFormat = IndexFormat.UInt32;
  1158. List<Vector3> vertices = new List<Vector3>();
  1159. List<int> triangles = new List<int>();
  1160. // List<Vector2> uv = new List<Vector2>();
  1161. foreach (var positionRow in positionArray)
  1162. {
  1163. foreach (var vert in positionRow)
  1164. {
  1165. vertices.Add(vert);
  1166. }
  1167. }
  1168. for (i = 0; i < positionArray.Count - 1; i++)
  1169. {
  1170. int count = positionArray[i].Count;
  1171. for (int j = 0; j < count - 1; j++)
  1172. {
  1173. triangles.Add(j + i * count);
  1174. triangles.Add(j + (i + 1) * count);
  1175. triangles.Add((j + 1) + i * count);
  1176. triangles.Add((j + 1) + i * count);
  1177. triangles.Add(j + (i + 1) * count);
  1178. triangles.Add((j + 1) + (i + 1) * count);
  1179. }
  1180. }
  1181. meshTerrain.SetVertices(vertices);
  1182. meshTerrain.SetTriangles(triangles, 0);
  1183. // meshTerrain.SetUVs(0, uv);
  1184. meshTerrain.RecalculateNormals();
  1185. meshTerrain.RecalculateTangents();
  1186. meshTerrain.RecalculateBounds();
  1187. meshGO = new GameObject("TerrainMesh");
  1188. meshGO.hideFlags = HideFlags.HideAndDontSave;
  1189. meshGO.AddComponent<MeshFilter>();
  1190. MeshRenderer meshRenderer = meshGO.AddComponent<MeshRenderer>();
  1191. meshRenderer.sharedMaterial = new Material(Shader.Find("Debug Terrain Carve"));
  1192. meshRenderer.sharedMaterial.color = new Color(0, 0.5f, 0);
  1193. meshGO.transform.position = Vector3.zero;
  1194. meshGO.GetComponent<MeshFilter>().sharedMesh = meshTerrain;
  1195. }
  1196. }
  1197. #region Terrain
  1198. public void ShowTerrainCarve(float differentSize = 0)
  1199. {
  1200. if (Application.isEditor && meshGO == null)
  1201. {
  1202. Transform meshGoTrans = transform.Find("TerrainMesh");
  1203. if (meshGoTrans != null)
  1204. meshGO = meshGoTrans.gameObject;
  1205. }
  1206. if (meshGO != null)
  1207. {
  1208. if (Application.isEditor)
  1209. DestroyImmediate(meshGO);
  1210. else
  1211. Destroy(meshGO);
  1212. }
  1213. Mesh mesh = meshfilter.sharedMesh;
  1214. RaycastHit hit;
  1215. Vector3 rayPointDown;
  1216. Vector3 rayPointUp;
  1217. Vector3 point;
  1218. detailTerrainForward = 2;
  1219. detailTerrain = 10;
  1220. if (differentSize == 0)
  1221. terrainAdditionalWidth = distSmooth + distSmoothStart;
  1222. else
  1223. terrainAdditionalWidth = differentSize;
  1224. List<List<Vector4>> positionArray = new List<List<Vector4>>();
  1225. float noise = 0;
  1226. for (int i = 0; i < pointsDown.Count - 1; i++)
  1227. {
  1228. for (int tf = 0; tf <= detailTerrainForward; tf++)
  1229. {
  1230. List<Vector4> positionArrayRow = new List<Vector4>();
  1231. rayPointDown = Vector3.Lerp(pointsDown[i], pointsDown[i + 1], tf / (float)detailTerrainForward);
  1232. rayPointUp = Vector3.Lerp(pointsUp[i], pointsUp[i + 1], tf / (float)detailTerrainForward);
  1233. Vector3 diff = rayPointDown - rayPointUp;
  1234. float diffMagintude = diff.magnitude;
  1235. rayPointDown += diff * 0.05f;
  1236. rayPointUp -= diff * 0.05f;
  1237. diff.Normalize();
  1238. Vector3 rayPointDownNew = rayPointDown + diff * terrainAdditionalWidth * 0.5f;
  1239. Vector3 rayPointUpNew = rayPointUp - diff * terrainAdditionalWidth * 0.5f;
  1240. if (terrainAdditionalWidth > 0)
  1241. {
  1242. for (int t = 0; t < detailTerrain; t++)
  1243. {
  1244. point = Vector3.Lerp(rayPointDownNew, rayPointDown, t / (float)detailTerrain) + transform.position;
  1245. if (Physics.Raycast(point + Vector3.up * 500, Vector3.down, out hit))
  1246. {
  1247. if (noiseCarve)
  1248. noise = Mathf.PerlinNoise(point.x * noiseSizeX, point.z * noiseSizeZ) * noiseMultiplierOutside - noiseMultiplierOutside * 0.5f;
  1249. else
  1250. noise = 0;
  1251. float evaluate = 1 - t / (float)detailTerrain;
  1252. evaluate *= terrainAdditionalWidth;
  1253. float height = point.y + terrainCarve.Evaluate(-evaluate) + terrainCarve.Evaluate(-evaluate) * noise;
  1254. float smoothValue = t / (float)detailTerrain;
  1255. smoothValue = Mathf.Pow(smoothValue, terrainSmoothMultiplier);
  1256. height = Mathf.Lerp(hit.point.y, height, smoothValue);
  1257. Vector4 newPos = new Vector4(hit.point.x, height, hit.point.z, -evaluate);
  1258. positionArrayRow.Add(newPos);
  1259. }
  1260. else
  1261. positionArrayRow.Add(point);
  1262. }
  1263. }
  1264. for (int t = 0; t <= detailTerrain; t++)
  1265. {
  1266. point = Vector3.Lerp(rayPointDown, rayPointUp, t / (float)detailTerrain) + transform.position;
  1267. if (Physics.Raycast(point + Vector3.up * 500, Vector3.down, out hit))
  1268. {
  1269. if (noiseCarve)
  1270. noise = Mathf.PerlinNoise(point.x * noiseSizeX, point.z * noiseSizeZ) * noiseMultiplierInside - noiseMultiplierInside * 0.5f;
  1271. else
  1272. noise = 0;
  1273. float evaluate = diffMagintude * (0.5f - Mathf.Abs(0.5f - t / (float)detailTerrain));
  1274. float height = point.y + terrainCarve.Evaluate(evaluate) + terrainCarve.Evaluate(evaluate) * noise;
  1275. float smoothValue = 1 - 2 * Mathf.Abs(t / (float)detailTerrain - 0.5f);
  1276. smoothValue = Mathf.Pow(smoothValue, terrainSmoothMultiplier);
  1277. height = Mathf.Lerp(hit.point.y, height, 1);
  1278. Vector4 newPos = new Vector4(hit.point.x, height, hit.point.z, evaluate);
  1279. positionArrayRow.Add(newPos);
  1280. }
  1281. else
  1282. positionArrayRow.Add(point);
  1283. }
  1284. if (terrainAdditionalWidth > 0)
  1285. {
  1286. for (int t = 1; t <= detailTerrain; t++)
  1287. {
  1288. point = Vector3.Lerp(rayPointUp, rayPointUpNew, t / (float)detailTerrain) + transform.position;
  1289. if (Physics.Raycast(point + Vector3.up * 50, Vector3.down, out hit))
  1290. {
  1291. if (noiseCarve)
  1292. noise = Mathf.PerlinNoise(point.x * noiseSizeX, point.z * noiseSizeZ) * noiseMultiplierOutside - noiseMultiplierOutside * 0.5f;
  1293. else
  1294. noise = 0;
  1295. float evaluate = t / (float)detailTerrain;
  1296. evaluate *= terrainAdditionalWidth;
  1297. float height = point.y + terrainCarve.Evaluate(-evaluate) + terrainCarve.Evaluate(-evaluate) * noise;
  1298. float smoothValue = 1 - t / (float)detailTerrain;
  1299. smoothValue = Mathf.Pow(smoothValue, terrainSmoothMultiplier);
  1300. height = Mathf.Lerp(hit.point.y, height, smoothValue);
  1301. Vector4 newPos = new Vector4(hit.point.x, height, hit.point.z, -evaluate);
  1302. positionArrayRow.Add(newPos);
  1303. }
  1304. else
  1305. positionArrayRow.Add(point);
  1306. }
  1307. }
  1308. positionArray.Add(positionArrayRow);
  1309. }
  1310. }
  1311. Mesh meshTerrain = new Mesh();
  1312. meshTerrain.indexFormat = IndexFormat.UInt32;
  1313. List<Vector3> vertices = new List<Vector3>();
  1314. List<int> triangles = new List<int>();
  1315. List<Vector2> uv = new List<Vector2>();
  1316. foreach (var positionRow in positionArray)
  1317. {
  1318. foreach (var vert in positionRow)
  1319. {
  1320. vertices.Add(vert);
  1321. }
  1322. }
  1323. for (int i = 0; i < positionArray.Count - 1; i++)
  1324. {
  1325. int count = positionArray[i].Count;
  1326. for (int j = 0; j < count - 1; j++)
  1327. {
  1328. triangles.Add(j + i * count);
  1329. triangles.Add(j + (i + 1) * count);
  1330. triangles.Add((j + 1) + i * count);
  1331. triangles.Add((j + 1) + i * count);
  1332. triangles.Add(j + (i + 1) * count);
  1333. triangles.Add((j + 1) + (i + 1) * count);
  1334. }
  1335. }
  1336. foreach (var positionRow in positionArray)
  1337. {
  1338. foreach (var vert in positionRow)
  1339. {
  1340. uv.Add(new Vector2(vert.w, 0));
  1341. }
  1342. }
  1343. meshTerrain.SetVertices(vertices);
  1344. meshTerrain.SetTriangles(triangles, 0);
  1345. meshTerrain.SetUVs(0, uv);
  1346. meshTerrain.RecalculateNormals();
  1347. meshTerrain.RecalculateTangents();
  1348. meshTerrain.RecalculateBounds();
  1349. //if (meshGO == null)
  1350. //{
  1351. meshGO = new GameObject("TerrainMesh");
  1352. meshGO.transform.parent = transform;
  1353. meshGO.hideFlags = HideFlags.HideAndDontSave;
  1354. meshGO.AddComponent<MeshFilter>();
  1355. MeshRenderer meshRenderer = meshGO.AddComponent<MeshRenderer>();
  1356. meshRenderer.sharedMaterial = new Material(Shader.Find("Debug Terrain Carve"));
  1357. meshRenderer.sharedMaterial.color = new Color(0, 0.5f, 0);
  1358. // }
  1359. meshGO.transform.position = Vector3.zero;
  1360. meshGO.GetComponent<MeshFilter>().sharedMesh = meshTerrain;
  1361. if (overrideRiverRender)
  1362. meshGO.GetComponent<MeshRenderer>().sharedMaterial.renderQueue = 5000;
  1363. else
  1364. meshGO.GetComponent<MeshRenderer>().sharedMaterial.renderQueue = 2980;
  1365. }
  1366. public void TerrainCarve()
  1367. {
  1368. bool debugLines = false;
  1369. Physics.autoSyncTransforms = false;
  1370. foreach (Terrain terrain in Terrain.activeTerrains)
  1371. {
  1372. TerrainData terrainData = terrain.terrainData;
  1373. float posY = terrain.transform.position.y;
  1374. float sizeX = terrain.terrainData.size.x;
  1375. float sizeY = terrain.terrainData.size.y;
  1376. float sizeZ = terrain.terrainData.size.z;
  1377. float terrainTowidth = (1 / (float)sizeZ * (terrainData.heightmapResolution - 1));
  1378. float terrainToheight = (1 / (float)sizeX * (terrainData.heightmapResolution - 1));
  1379. float minX;
  1380. float maxX;
  1381. float minZ;
  1382. float maxZ;
  1383. #if UNITY_EDITOR
  1384. Undo.RegisterCompleteObjectUndo(terrainData, "River curve");
  1385. #endif
  1386. MeshCollider meshCollider = meshGO.gameObject.AddComponent<MeshCollider>();
  1387. List<Vector3> transformPointUp = new List<Vector3>();
  1388. List<Vector3> transformPointDown = new List<Vector3>();
  1389. int pointsCount = 5;
  1390. int pointsStart = 0;//pointsUp.Count
  1391. //List<Vector2> done = new List<Vector2>();
  1392. //List<Vector3> positionArray = new List<Vector3>();
  1393. Vector3 pointOne = Vector3.zero;
  1394. Vector3 pointTwo = Vector3.zero;
  1395. for (pointsStart = 0; pointsStart < pointsUp.Count; pointsStart = Mathf.Clamp(pointsStart + pointsCount - 1, 0, pointsUp.Count))
  1396. {
  1397. int end = Mathf.Min(pointsStart + pointsCount, pointsUp.Count);
  1398. //int currentCount = Mathf.Min(pointsCount, pointsUp.Count - pointsStart);
  1399. transformPointUp.Clear();
  1400. transformPointDown.Clear();
  1401. for (int i = pointsStart; i < end; i++)
  1402. {
  1403. transformPointUp.Add(transform.TransformPoint(pointsUp[i]));
  1404. transformPointDown.Add(transform.TransformPoint(pointsDown[i]));
  1405. }
  1406. minX = float.MaxValue;
  1407. maxX = float.MinValue;
  1408. minZ = float.MaxValue;
  1409. maxZ = float.MinValue;
  1410. for (int i = 0; i < transformPointUp.Count; i++)
  1411. {
  1412. Vector3 point = transformPointUp[i];
  1413. if (minX > point.x)
  1414. minX = point.x;
  1415. if (maxX < point.x)
  1416. maxX = point.x;
  1417. if (minZ > point.z)
  1418. minZ = point.z;
  1419. if (maxZ < point.z)
  1420. maxZ = point.z;
  1421. }
  1422. for (int i = 0; i < transformPointDown.Count; i++)
  1423. {
  1424. Vector3 point = transformPointDown[i];
  1425. if (minX > point.x)
  1426. minX = point.x;
  1427. if (maxX < point.x)
  1428. maxX = point.x;
  1429. if (minZ > point.z)
  1430. minZ = point.z;
  1431. if (maxZ < point.z)
  1432. maxZ = point.z;
  1433. }
  1434. minX -= terrain.transform.position.x + distSmooth;
  1435. maxX -= terrain.transform.position.x - distSmooth;
  1436. minZ -= terrain.transform.position.z + distSmooth;
  1437. maxZ -= terrain.transform.position.z - distSmooth;
  1438. minX = minX * terrainToheight;
  1439. maxX = maxX * terrainToheight;
  1440. minZ = minZ * terrainTowidth;
  1441. maxZ = maxZ * terrainTowidth;
  1442. maxX = Mathf.Ceil(Mathf.Clamp(maxX + 1, 0, (terrainData.heightmapResolution)));
  1443. minZ = Mathf.Floor(Mathf.Clamp(minZ, 0, (terrainData.heightmapResolution)));
  1444. maxZ = Mathf.Ceil(Mathf.Clamp(maxZ + 1, 0, (terrainData.heightmapResolution)));
  1445. minX = Mathf.Floor(Mathf.Clamp(minX, 0, (terrainData.heightmapResolution)));
  1446. float[,] heightmapData = terrainData.GetHeights((int)minX, (int)minZ, (int)(maxX - minX), (int)(maxZ - minZ));
  1447. Vector3 position = Vector3.zero;
  1448. Vector3 pointMin = Vector3.zero;
  1449. for (int x = 0; x < heightmapData.GetLength(0); x++)
  1450. {
  1451. for (int z = 0; z < heightmapData.GetLength(1); z++)
  1452. {
  1453. position.x = (z + minX) / (float)terrainToheight + terrain.transform.position.x;
  1454. position.z = (x + minZ) / (float)terrainTowidth + terrain.transform.position.z;
  1455. Ray ray = new Ray(position + Vector3.up * 3000, Vector3.down);
  1456. RaycastHit hit;
  1457. if (meshCollider.Raycast(ray, out hit, 10000))
  1458. {
  1459. float height = hit.point.y - posY;
  1460. heightmapData[x, z] = height / (float)sizeY;
  1461. if (debugLines)
  1462. {
  1463. Debug.DrawLine(hit.point, hit.point + Vector3.up * 0.5f, Color.magenta, 10);
  1464. }
  1465. }
  1466. }
  1467. }
  1468. terrainData.SetHeights((int)minX, (int)minZ, heightmapData);
  1469. }
  1470. DestroyImmediate(meshCollider);
  1471. terrain.Flush();
  1472. }
  1473. Physics.autoSyncTransforms = true;
  1474. if (meshGO != null)
  1475. DestroyImmediate(meshGO);
  1476. }
  1477. public void TerrainPaintMeshBased()
  1478. {
  1479. Physics.autoSyncTransforms = false;
  1480. foreach (Terrain terrain in Terrain.activeTerrains)
  1481. {
  1482. TerrainData terrainData = terrain.terrainData;
  1483. float sizeX = terrain.terrainData.size.x;
  1484. float sizeY = terrain.terrainData.size.y;
  1485. float sizeZ = terrain.terrainData.size.z;
  1486. float terrainTowidth = (1 / (float)sizeZ * (terrainData.alphamapWidth - 1));
  1487. float terrainToheight = (1 / (float)sizeX * (terrainData.alphamapHeight - 1));
  1488. #if UNITY_EDITOR
  1489. Undo.RegisterCompleteObjectUndo(terrainData, "Paint river");
  1490. Undo.RegisterCompleteObjectUndo(terrain, "Terrain draw texture");
  1491. Undo.RegisterCompleteObjectUndo(terrainData.alphamapTextures, "alpha");
  1492. #endif
  1493. float minX;
  1494. float maxX;
  1495. float minZ;
  1496. float maxZ;
  1497. MeshCollider meshCollider = meshGO.gameObject.AddComponent<MeshCollider>();
  1498. List<Vector3> transformPointUp = new List<Vector3>();
  1499. List<Vector3> transformPointDown = new List<Vector3>();
  1500. int pointsCount = 5;
  1501. int pointsStart = 0;//pointsUp.Count
  1502. //List<Vector2> done = new List<Vector2>();
  1503. //List<Vector3> positionArray = new List<Vector3>();
  1504. Vector3 pointOne = Vector3.zero;
  1505. Vector3 pointTwo = Vector3.zero;
  1506. for (pointsStart = 0; pointsStart < pointsUp.Count; pointsStart = Mathf.Clamp(pointsStart + pointsCount - 1, 0, pointsUp.Count))
  1507. {
  1508. int end = Mathf.Min(pointsStart + pointsCount, pointsUp.Count);
  1509. //int currentCount = Mathf.Min(pointsCount, pointsUp.Count - pointsStart);
  1510. transformPointUp.Clear();
  1511. transformPointDown.Clear();
  1512. for (int i = pointsStart; i < end; i++)
  1513. {
  1514. transformPointUp.Add(transform.TransformPoint(pointsUp[i]));
  1515. transformPointDown.Add(transform.TransformPoint(pointsDown[i]));
  1516. }
  1517. minX = float.MaxValue;
  1518. maxX = float.MinValue;
  1519. minZ = float.MaxValue;
  1520. maxZ = float.MinValue;
  1521. for (int i = 0; i < transformPointUp.Count; i++)
  1522. {
  1523. Vector3 point = transformPointUp[i];
  1524. if (minX > point.x)
  1525. minX = point.x;
  1526. if (maxX < point.x)
  1527. maxX = point.x;
  1528. if (minZ > point.z)
  1529. minZ = point.z;
  1530. if (maxZ < point.z)
  1531. maxZ = point.z;
  1532. }
  1533. for (int i = 0; i < transformPointDown.Count; i++)
  1534. {
  1535. Vector3 point = transformPointDown[i];
  1536. if (minX > point.x)
  1537. minX = point.x;
  1538. if (maxX < point.x)
  1539. maxX = point.x;
  1540. if (minZ > point.z)
  1541. minZ = point.z;
  1542. if (maxZ < point.z)
  1543. maxZ = point.z;
  1544. }
  1545. minX -= terrain.transform.position.x + distSmooth;
  1546. maxX -= terrain.transform.position.x - distSmooth;
  1547. minZ -= terrain.transform.position.z + distSmooth;
  1548. maxZ -= terrain.transform.position.z - distSmooth;
  1549. minX = minX * terrainToheight;
  1550. maxX = maxX * terrainToheight;
  1551. minZ = minZ * terrainTowidth;
  1552. maxZ = maxZ * terrainTowidth;
  1553. minX = Mathf.Floor(Mathf.Clamp(minX, 0, (terrainData.alphamapWidth)));
  1554. maxX = Mathf.Ceil(Mathf.Clamp(maxX + 1, 0, (terrainData.alphamapWidth)));
  1555. minZ = Mathf.Floor(Mathf.Clamp(minZ, 0, (terrainData.alphamapHeight)));
  1556. maxZ = Mathf.Ceil(Mathf.Clamp(maxZ + 1, 0, (terrainData.alphamapHeight)));
  1557. float[,,] alphamapData = terrainData.GetAlphamaps((int)minX, (int)minZ, (int)(maxX - minX), (int)(maxZ - minZ));
  1558. Vector3 position = Vector3.zero;
  1559. Vector3 pointMin = Vector3.zero;
  1560. float noise = 0;
  1561. for (int x = 0; x < alphamapData.GetLength(0); x++)
  1562. {
  1563. for (int z = 0; z < alphamapData.GetLength(1); z++)
  1564. {
  1565. position.x = (z + minX) / (float)terrainToheight + terrain.transform.position.x;
  1566. position.z = (x + minZ) / (float)terrainTowidth + terrain.transform.position.z;
  1567. Ray ray = new Ray(position + Vector3.up * 3000, Vector3.down);
  1568. RaycastHit hit;
  1569. if (meshCollider.Raycast(ray, out hit, 10000))
  1570. {
  1571. float minDist = hit.textureCoord.x;
  1572. if (!mixTwoSplatMaps)
  1573. {
  1574. if (noisePaint)
  1575. {
  1576. if (minDist >= 0)
  1577. noise = Mathf.PerlinNoise(hit.point.x * noiseSizeXPaint, hit.point.z * noiseSizeZPaint) * noiseMultiplierInsidePaint - noiseMultiplierInsidePaint * 0.5f;
  1578. else
  1579. noise = Mathf.PerlinNoise(hit.point.x * noiseSizeXPaint, hit.point.z * noiseSizeZPaint) * noiseMultiplierOutsidePaint - noiseMultiplierOutsidePaint * 0.5f;
  1580. }
  1581. else
  1582. noise = 0;
  1583. float oldValue = alphamapData[x, z, currentSplatMap];
  1584. alphamapData[x, z, currentSplatMap] = Mathf.Clamp01(Mathf.Lerp(alphamapData[x, z, currentSplatMap], 1, terrainPaintCarve.Evaluate(minDist) + terrainPaintCarve.Evaluate(minDist) * noise));
  1585. for (int l = 0; l < terrainData.terrainLayers.Length; l++)
  1586. {
  1587. if (l != currentSplatMap)
  1588. {
  1589. alphamapData[x, z, l] = oldValue == 1 ? 0 : Mathf.Clamp01(alphamapData[x, z, l] * ((1 - alphamapData[x, z, currentSplatMap]) / (1 - oldValue)));
  1590. }
  1591. }
  1592. }
  1593. else
  1594. {
  1595. if (minDist >= 0)
  1596. noise = Mathf.PerlinNoise(hit.point.x * noiseSizeXPaint, hit.point.z * noiseSizeZPaint) * noiseMultiplierInsidePaint - noiseMultiplierInsidePaint * 0.5f;
  1597. else
  1598. noise = Mathf.PerlinNoise(hit.point.x * noiseSizeXPaint, hit.point.z * noiseSizeZPaint) * noiseMultiplierOutsidePaint - noiseMultiplierOutsidePaint * 0.5f;
  1599. float oldValue = alphamapData[x, z, currentSplatMap];
  1600. alphamapData[x, z, currentSplatMap] = Mathf.Clamp01(Mathf.Lerp(alphamapData[x, z, currentSplatMap], 1, terrainPaintCarve.Evaluate(minDist)));
  1601. for (int l = 0; l < terrainData.terrainLayers.Length; l++)
  1602. {
  1603. if (l != currentSplatMap)
  1604. {
  1605. alphamapData[x, z, l] = oldValue == 1 ? 0 : Mathf.Clamp01(alphamapData[x, z, l] * ((1 - alphamapData[x, z, currentSplatMap]) / (1 - oldValue)));
  1606. }
  1607. }
  1608. if (noise > 0)
  1609. {
  1610. oldValue = alphamapData[x, z, secondSplatMap];
  1611. alphamapData[x, z, secondSplatMap] = Mathf.Clamp01(Mathf.Lerp(alphamapData[x, z, secondSplatMap], 1, noise));
  1612. for (int l = 0; l < terrainData.terrainLayers.Length; l++)
  1613. {
  1614. if (l != secondSplatMap)
  1615. {
  1616. alphamapData[x, z, l] = oldValue == 1 ? 0 : Mathf.Clamp01(alphamapData[x, z, l] * ((1 - alphamapData[x, z, secondSplatMap]) / (1 - oldValue)));
  1617. }
  1618. }
  1619. }
  1620. }
  1621. if (addCliffSplatMap)
  1622. {
  1623. if (minDist >= 0)
  1624. {
  1625. float angle = Vector3.Angle(hit.normal, Vector3.up);
  1626. if (angle > cliffAngle)
  1627. {
  1628. float oldValue = alphamapData[x, z, cliffSplatMap];
  1629. alphamapData[x, z, cliffSplatMap] = cliffBlend;
  1630. for (int l = 0; l < terrainData.terrainLayers.Length; l++)
  1631. {
  1632. if (l != cliffSplatMap)
  1633. {
  1634. alphamapData[x, z, l] = oldValue == 1 ? 0 : Mathf.Clamp01(alphamapData[x, z, l] * ((1 - alphamapData[x, z, cliffSplatMap]) / (1 - oldValue)));
  1635. }
  1636. }
  1637. }
  1638. }
  1639. else
  1640. {
  1641. float angle = Vector3.Angle(hit.normal, Vector3.up);
  1642. if (angle > cliffAngleOutside)
  1643. {
  1644. float oldValue = alphamapData[x, z, cliffSplatMapOutside];
  1645. alphamapData[x, z, cliffSplatMapOutside] = cliffBlendOutside;
  1646. for (int l = 0; l < terrainData.terrainLayers.Length; l++)
  1647. {
  1648. if (l != cliffSplatMapOutside)
  1649. {
  1650. alphamapData[x, z, l] = oldValue == 1 ? 0 : Mathf.Clamp01(alphamapData[x, z, l] * ((1 - alphamapData[x, z, cliffSplatMapOutside]) / (1 - oldValue)));
  1651. }
  1652. }
  1653. }
  1654. }
  1655. }
  1656. }
  1657. }
  1658. }
  1659. terrainData.SetAlphamaps((int)minX, (int)minZ, alphamapData);
  1660. }
  1661. DestroyImmediate(meshCollider);
  1662. terrain.Flush();
  1663. }
  1664. Physics.autoSyncTransforms = true;
  1665. if (meshGO != null)
  1666. DestroyImmediate(meshGO);
  1667. }
  1668. public void TerrainClearFoliage(bool details = true)
  1669. {
  1670. Physics.autoSyncTransforms = false;
  1671. foreach (Terrain terrain in Terrain.activeTerrains)
  1672. {
  1673. TerrainData terrainData = terrain.terrainData;
  1674. Transform transformTerrain = terrain.transform;
  1675. float posY = terrain.transform.position.y;
  1676. float sizeX = terrain.terrainData.size.x;
  1677. float sizeY = terrain.terrainData.size.y;
  1678. float sizeZ = terrain.terrainData.size.z;
  1679. float terrainTowidth = (1 / (float)sizeX * (terrainData.detailWidth - 1));
  1680. float terrainToheight = (1 / (float)sizeZ * (terrainData.detailHeight - 1));
  1681. #if UNITY_EDITOR
  1682. Undo.RegisterCompleteObjectUndo(terrainData, "Paint river");
  1683. Undo.RegisterCompleteObjectUndo(terrain, "Terrain draw texture");
  1684. #endif
  1685. float minX;
  1686. float maxX;
  1687. float minZ;
  1688. float maxZ;
  1689. MeshCollider meshCollider = meshGO.gameObject.AddComponent<MeshCollider>();
  1690. List<Vector3> transformPointUp = new List<Vector3>();
  1691. List<Vector3> transformPointDown = new List<Vector3>();
  1692. int pointsCount = 5;
  1693. int pointsStart = 0;//pointsUp.Count
  1694. //List<Vector2> done = new List<Vector2>();
  1695. //List<Vector3> positionArray = new List<Vector3>();
  1696. Vector3 pointOne = Vector3.zero;
  1697. Vector3 pointTwo = Vector3.zero;
  1698. Vector3 position = Vector3.zero;
  1699. if (details)
  1700. {
  1701. for (pointsStart = 0; pointsStart < pointsUp.Count; pointsStart = Mathf.Clamp(pointsStart + pointsCount - 1, 0, pointsUp.Count))
  1702. {
  1703. int end = Mathf.Min(pointsStart + pointsCount, pointsUp.Count);
  1704. //int currentCount = Mathf.Min(pointsCount, pointsUp.Count - pointsStart);
  1705. transformPointUp.Clear();
  1706. transformPointDown.Clear();
  1707. for (int i = pointsStart; i < end; i++)
  1708. {
  1709. transformPointUp.Add(transform.TransformPoint(pointsUp[i]));
  1710. transformPointDown.Add(transform.TransformPoint(pointsDown[i]));
  1711. }
  1712. minX = float.MaxValue;
  1713. maxX = float.MinValue;
  1714. minZ = float.MaxValue;
  1715. maxZ = float.MinValue;
  1716. for (int i = 0; i < transformPointUp.Count; i++)
  1717. {
  1718. Vector3 point = transformPointUp[i];
  1719. if (minX > point.x)
  1720. minX = point.x;
  1721. if (maxX < point.x)
  1722. maxX = point.x;
  1723. if (minZ > point.z)
  1724. minZ = point.z;
  1725. if (maxZ < point.z)
  1726. maxZ = point.z;
  1727. }
  1728. for (int i = 0; i < transformPointDown.Count; i++)
  1729. {
  1730. Vector3 point = transformPointDown[i];
  1731. if (minX > point.x)
  1732. minX = point.x;
  1733. if (maxX < point.x)
  1734. maxX = point.x;
  1735. if (minZ > point.z)
  1736. minZ = point.z;
  1737. if (maxZ < point.z)
  1738. maxZ = point.z;
  1739. }
  1740. minX -= terrain.transform.position.x + distSmooth;
  1741. maxX -= terrain.transform.position.x - distSmooth;
  1742. minZ -= terrain.transform.position.z + distSmooth;
  1743. maxZ -= terrain.transform.position.z - distSmooth;
  1744. minX = minX * terrainToheight;
  1745. maxX = maxX * terrainToheight;
  1746. minZ = minZ * terrainTowidth;
  1747. maxZ = maxZ * terrainTowidth;
  1748. minX = Mathf.Floor(Mathf.Clamp(minX, 0, (terrainData.alphamapWidth)));
  1749. maxX = Mathf.Ceil(Mathf.Clamp(maxX + 1, 0, (terrainData.alphamapWidth)));
  1750. minZ = Mathf.Floor(Mathf.Clamp(minZ, 0, (terrainData.alphamapHeight)));
  1751. maxZ = Mathf.Ceil(Mathf.Clamp(maxZ + 1, 0, (terrainData.alphamapHeight)));
  1752. int[,] detailLayer;// = terrainData.GetAlphamaps((int)minX, (int)minZ, (int)(maxX - minX), (int)(maxZ - minZ));
  1753. for (int l = 0; l < terrainData.detailPrototypes.Length; l++)
  1754. {
  1755. detailLayer = terrainData.GetDetailLayer((int)minX, (int)minZ, (int)(maxX - minX), (int)(maxZ - minZ), l);
  1756. for (int x = 0; x < detailLayer.GetLength(0); x++)
  1757. {
  1758. for (int z = 0; z < detailLayer.GetLength(1); z++)
  1759. {
  1760. position.x = (z + minX) / (float)terrainToheight + terrain.transform.position.x;
  1761. position.z = (x + minZ) / (float)terrainTowidth + terrain.transform.position.z;
  1762. Ray ray = new Ray(position + Vector3.up * 3000, Vector3.down);
  1763. RaycastHit hit;
  1764. if (meshCollider.Raycast(ray, out hit, 10000))
  1765. {
  1766. detailLayer[x, z] = 0;
  1767. }
  1768. }
  1769. }
  1770. terrainData.SetDetailLayer((int)minX, (int)minZ, l, detailLayer);
  1771. }
  1772. }
  1773. }
  1774. else
  1775. {
  1776. List<TreeInstance> newTrees = new List<TreeInstance>();
  1777. TreeInstance[] oldTrees = terrainData.treeInstances;
  1778. foreach (var tree in oldTrees)
  1779. {
  1780. //Debug.DrawRay(new Vector3(, 0, tree.position.z * sizeZ) + terrain.transform.position, Vector3.up * 5, Color.red, 3);
  1781. position.x = tree.position.x * sizeX + transformTerrain.position.x;//, polygonHeight
  1782. position.z = tree.position.z * sizeZ + transformTerrain.position.z;
  1783. Ray ray = new Ray(position + Vector3.up * 3000, Vector3.down);
  1784. RaycastHit hit;
  1785. if (!meshCollider.Raycast(ray, out hit, 10000))
  1786. {
  1787. newTrees.Add(tree);
  1788. }
  1789. }
  1790. terrainData.treeInstances = newTrees.ToArray();
  1791. }
  1792. DestroyImmediate(meshCollider);
  1793. terrain.Flush();
  1794. }
  1795. Physics.autoSyncTransforms = true;
  1796. if (meshGO != null)
  1797. DestroyImmediate(meshGO);
  1798. }
  1799. #endregion
  1800. float FlowCalculate(float u, float normalY, Vector3 vertice)
  1801. {
  1802. float noise = (noiseflowMap ? Mathf.PerlinNoise(vertice.x * noiseSizeXflowMap, vertice.z * noiseSizeZflowMap) * noiseMultiplierflowMap - noiseMultiplierflowMap * 0.5f : 0) * Mathf.Pow(Mathf.Clamp(normalY, 0, 1), 5);
  1803. return Mathf.Lerp(flowWaterfall.Evaluate(u), flowFlat.Evaluate(u) + noise, Mathf.Clamp(normalY, 0, 1));
  1804. }
  1805. }