| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497 |
- using UnityEngine;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine.Rendering;
- #if VEGETATION_STUDIO
- using AwesomeTechnologies;
- using AwesomeTechnologies.VegetationStudio;
- #endif
- #if VEGETATION_STUDIO_PRO
- using AwesomeTechnologies.VegetationSystem.Biomes;
- #endif
- #if UNITY_EDITOR
- using UnityEditor;
- #endif
- [RequireComponent(typeof(MeshFilter))]
- public class RamSpline : MonoBehaviour
- {
- public SplineProfile currentProfile;
- public SplineProfile oldProfile;
- public List<RamSpline> beginnigChildSplines = new List<RamSpline>();
- public List<RamSpline> endingChildSplines = new List<RamSpline>();
- public RamSpline beginningSpline;
- public RamSpline endingSpline;
- public int beginningConnectionID;
- public int endingConnectionID;
- public float beginningMinWidth = 0.5f;
- public float beginningMaxWidth = 1f;
- public float endingMinWidth = 0.5f;
- public float endingMaxWidth = 1f;
- public int toolbarInt = 0;
- public bool invertUVDirection = false;
- public bool uvRotation = true;
- public MeshFilter meshfilter;
- public List<Vector4> controlPoints = new List<Vector4>();
- public List<Quaternion> controlPointsRotations = new List<Quaternion>();
- public List<Quaternion> controlPointsOrientation = new List<Quaternion>();
- public List<Vector3> controlPointsUp = new List<Vector3>();
- public List<Vector3> controlPointsDown = new List<Vector3>();
- public List<float> controlPointsSnap = new List<float>();
- public AnimationCurve meshCurve = new AnimationCurve(new Keyframe[] { new Keyframe(0, 0), new Keyframe(1, 0) });
- public List<AnimationCurve> controlPointsMeshCurves = new List<AnimationCurve>();
- public bool normalFromRaycast = false;
- public bool snapToTerrain = false;
- public LayerMask snapMask = 1;
- public List<Vector3> points = new List<Vector3>();
- public List<Vector3> pointsUp = new List<Vector3>();
- public List<Vector3> pointsDown = new List<Vector3>();
- public List<Vector3> points2 = new List<Vector3>();
- public List<Vector3> verticesBeginning = new List<Vector3>();
- public List<Vector3> verticesEnding = new List<Vector3>();
- public List<Vector3> normalsBeginning = new List<Vector3>();
- public List<Vector3> normalsEnding = new List<Vector3>();
- public List<float> widths = new List<float>();
- public List<float> snaps = new List<float>();
- public List<float> lerpValues = new List<float>();
- public List<Quaternion> orientations = new List<Quaternion>();
- public List<Vector3> tangents = new List<Vector3>();
- public List<Vector3> normalsList = new List<Vector3>();
- public Color[] colors;
- public List<Vector2> colorsFlowMap = new List<Vector2>();
- public List<Vector3> verticeDirection = new List<Vector3>();
- public float floatSpeed = 10;
- public bool generateOnStart = false;
- public float minVal = 0.5f;
- public float maxVal = 0.5f;
- public float width = 4;
- public int vertsInShape = 3;
- public float traingleDensity = 0.2f;
- public float uvScale = 3;
- public Material oldMaterial;
- public bool showVertexColors;
- public bool showFlowMap;
- public bool overrideFlowMap = false;
- public bool drawOnMesh = false;
- public bool drawOnMeshFlowMap = false;
- public bool uvScaleOverride = false;
- public bool debug = false;
- public Color drawColor = Color.black;
- public bool drawColorR = true;
- public bool drawColorG = true;
- public bool drawColorB = true;
- public bool drawColorA = true;
- public bool drawOnMultiple = false;
- public float flowSpeed = 1f;
- public float flowDirection = 0f;
- public AnimationCurve flowFlat = new AnimationCurve(new Keyframe[] {
- new Keyframe (0, 0.025f),
- new Keyframe (0.5f, 0.05f),
- new Keyframe (1, 0.025f)
- });
- public AnimationCurve flowWaterfall = new AnimationCurve(new Keyframe[] {
- new Keyframe (0, 0.25f),
- new Keyframe (1, 0.25f)
- });
- public bool noiseflowMap = false;
- public float noiseMultiplierflowMap = 0.1f;
- public float noiseSizeXflowMap = 2f;
- public float noiseSizeZflowMap = 2f;
- public float opacity = 0.1f;
- public float drawSize = 1f;
- public float length = 0;
- public float fulllength = 0;
- public float minMaxWidth;
- public float uvWidth;
- public float uvBeginning;
- public bool receiveShadows = false;
- public ShadowCastingMode shadowCastingMode = ShadowCastingMode.Off;
- //Part meshes
- public bool generateMeshParts = false;
- public int meshPartsCount = 3;
- public List<Transform> meshesPartTransforms = new List<Transform>();
- //Simulate mesh
- public float simulatedRiverLength = 100;
- public int simulatedRiverPoints = 10;
- public float simulatedMinStepSize = 1f;
- public bool simulatedNoUp = false;
- public bool simulatedBreakOnUp = true;
- //Terrain Change
- public int detailTerrain = 100;
- public int detailTerrainForward = 100;
- public float terrainAdditionalWidth = 2;
- public float terrainSmoothMultiplier = 5;
- public bool overrideRiverRender = false;
- public bool noiseWidth = false;
- public float noiseMultiplierWidth = 4f;
- public float noiseSizeWidth = 0.5f;
- public bool noiseCarve = false;
- public float noiseMultiplierInside = 1f;
- public float noiseMultiplierOutside = 0.25f;
- public float noiseSizeX = 0.2f;
- public float noiseSizeZ = 0.2f;
- public bool noisePaint = false;
- public float noiseMultiplierInsidePaint = 0.25f;
- public float noiseMultiplierOutsidePaint = 0.25f;
- public float noiseSizeXPaint = 0.2f;
- public float noiseSizeZPaint = 0.2f;
- public AnimationCurve terrainCarve = new AnimationCurve(new Keyframe[] { new Keyframe(0, 0.5f), new Keyframe(10, -4) });
- public float distSmooth = 5;
- public float distSmoothStart = 1;
- public AnimationCurve terrainPaintCarve = new AnimationCurve(new Keyframe[] { new Keyframe(0, 0), new Keyframe(1, 1) });
- public int currentSplatMap = 1;
- public bool mixTwoSplatMaps = false;
- public int secondSplatMap = 1;
- public bool addCliffSplatMap = false;
- public int cliffSplatMap = 1;
- public float cliffAngle = 45;
- public float cliffBlend = 1;
- public int cliffSplatMapOutside = 1;
- public float cliffAngleOutside = 45;
- public float cliffBlendOutside = 1;
- public float distanceClearFoliage = 1;
- public float distanceClearFoliageTrees = 1;
- #if VEGETATION_STUDIO_PRO
- public float biomMaskResolution = 0.5f;
- public float vegetationMaskSize = 3;
- public float vegetationBlendDistance = 1f;
- public BiomeMaskArea biomeMaskArea;
- public bool refreshMask = false;
- #endif
- #if VEGETATION_STUDIO
- public float vegetationMaskPerimeter = 5;
- public VegetationMaskArea vegetationMaskArea;
- #endif
- public GameObject meshGO;
- public void Start()
- {
- if (generateOnStart)
- GenerateSpline();
- }
- /// <summary>
- /// Creates spline
- /// </summary>
- /// <param name="splineMaterial">Material of the spline</param>
- /// <param name="positions">Positions to add to the spline</param>
- /// <returns></returns>
- public static RamSpline CreateSpline(Material splineMaterial = null, List<Vector4> positions = null, string name = "RamSpline")
- {
- GameObject gameobject = new GameObject(name);
- gameobject.layer = LayerMask.NameToLayer("Water");
- RamSpline spline = gameobject.AddComponent<RamSpline>();
- MeshRenderer meshRenderer = gameobject.AddComponent<MeshRenderer>();
- meshRenderer.receiveShadows = false;
- meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
- if (splineMaterial != null)
- meshRenderer.sharedMaterial = splineMaterial;
- if (positions != null)
- for (int i = 0; i < positions.Count; i++)
- {
- spline.AddPoint(positions[i]);
- }
- #if UNITY_EDITOR
- Undo.RegisterCreatedObjectUndo(gameobject, "Create river");
- #endif
- return spline;
- }
- /// <summary>
- /// Add point at end of spline
- /// </summary>
- /// <param name="position">New point position</param>
- public void AddPoint(Vector4 position)
- {
- if (position.w == 0)
- {
- if (controlPoints.Count > 0)
- position.w = controlPoints[controlPoints.Count - 1].w;
- else
- position.w = width;
- }
- controlPointsRotations.Add(Quaternion.identity);
- controlPoints.Add(position);
- controlPointsSnap.Add(0);
- controlPointsMeshCurves.Add(new AnimationCurve(new Keyframe[] { new Keyframe(0, 0), new Keyframe(1, 0) }));
- }
- /// <summary>
- /// Add point in the middle of the spline
- /// </summary>
- /// <param name="i">Point id</param>
- public void AddPointAfter(int i)
- {
- Vector4 position = controlPoints[i];
- if (i < controlPoints.Count - 1 && controlPoints.Count > i + 1)
- {
- Vector4 positionSecond = controlPoints[i + 1];
- if (Vector3.Distance((Vector3)positionSecond, (Vector3)position) > 0)
- position = (position + positionSecond) * 0.5f;
- else
- position.x += 1;
- }
- else if (controlPoints.Count > 1 && i == controlPoints.Count - 1)
- {
- Vector4 positionSecond = controlPoints[i - 1];
- if (Vector3.Distance((Vector3)positionSecond, (Vector3)position) > 0)
- position = position + (position - positionSecond);
- else
- position.x += 1;
- }
- else
- {
- position.x += 1;
- }
- controlPoints.Insert(i + 1, position);
- controlPointsRotations.Insert(i + 1, Quaternion.identity);
- controlPointsSnap.Insert(i + 1, 0);
- controlPointsMeshCurves.Insert(i + 1, new AnimationCurve(new Keyframe[] {
- new Keyframe (0, 0),
- new Keyframe (1, 0)
- }));
- }
- /// <summary>
- /// Changes point position, if new position doesn't have width old width will be taken
- /// </summary>
- /// <param name="i">Point id</param>
- /// <param name="position">New position</param>
- public void ChangePointPosition(int i, Vector3 position)
- {
- ChangePointPosition(i, new Vector4(position.x, position.y, position.z, 0));
- }
- /// <summary>
- /// Changes point position, if new position doesn't have width old width will be taken
- /// </summary>
- /// <param name="i">Point id</param>
- /// <param name="position">New position</param>
- public void ChangePointPosition(int i, Vector4 position)
- {
- Vector4 oldPos = controlPoints[i];
- if (position.w == 0)
- position.w = oldPos.w;
- controlPoints[i] = position;
- }
- /// <summary>
- /// Removes point in spline
- /// </summary>
- /// <param name="i"></param>
- public void RemovePoint(int i)
- {
- if (i < controlPoints.Count)
- {
- controlPoints.RemoveAt(i);
- controlPointsRotations.RemoveAt(i);
- controlPointsMeshCurves.RemoveAt(i);
- controlPointsSnap.RemoveAt(i);
- }
- }
- /// <summary>
- /// Removes points from point id forward
- /// </summary>
- /// <param name="fromID">Point id</param>
- public void RemovePoints(int fromID = -1)
- {
- int pointsCount = controlPoints.Count - 1;
- for (int i = pointsCount; i > fromID; i--)
- {
- RemovePoint(i);
- }
- }
- public void GenerateBeginningParentBased()
- {
- vertsInShape = (int)Mathf.Round((beginningSpline.vertsInShape - 1) * (beginningMaxWidth - beginningMinWidth) + 1);
- if (vertsInShape < 1)
- vertsInShape = 1;
- beginningConnectionID = beginningSpline.points.Count - 1;
- Vector4 pos = beginningSpline.controlPoints[beginningSpline.controlPoints.Count - 1];
- float width = pos.w;
- width *= beginningMaxWidth - beginningMinWidth;
- pos = Vector3.Lerp(beginningSpline.pointsDown[beginningConnectionID], beginningSpline.pointsUp[beginningConnectionID], beginningMinWidth + (beginningMaxWidth - beginningMinWidth) * 0.5f)
- + beginningSpline.transform.position - transform.position;
- pos.w = width;
- controlPoints[0] = pos;
- if (!uvScaleOverride)
- uvScale = beginningSpline.uvScale;
- }
- public void GenerateEndingParentBased()
- {
- if (beginningSpline == null)
- {
- vertsInShape = (int)Mathf.Round((endingSpline.vertsInShape - 1) * (endingMaxWidth - endingMinWidth) + 1);
- if (vertsInShape < 1)
- vertsInShape = 1;
- }
- endingConnectionID = 0;
- Vector4 pos = endingSpline.controlPoints[0];
- float width = pos.w;
- width *= endingMaxWidth - endingMinWidth;
- pos = Vector3.Lerp(endingSpline.pointsDown[endingConnectionID], endingSpline.pointsUp[endingConnectionID], endingMinWidth + (endingMaxWidth - endingMinWidth) * 0.5f) + endingSpline.transform.position - transform.position;
- pos.w = width;
- controlPoints[controlPoints.Count - 1] = pos;
- }
- public void GenerateSpline(List<RamSpline> generatedSplines = null)
- {
- generatedSplines = new List<RamSpline>();
- if (beginningSpline)
- {
- GenerateBeginningParentBased();
- }
- if (endingSpline)
- {
- GenerateEndingParentBased();
- }
- List<Vector4> pointsChecked = new List<Vector4>();
- for (int i = 0; i < controlPoints.Count; i++)
- {
- if (i > 0)
- {
- if (Vector3.Distance((Vector3)controlPoints[i], (Vector3)controlPoints[i - 1]) > 0)
- pointsChecked.Add(controlPoints[i]);
- }
- else
- pointsChecked.Add(controlPoints[i]);
- }
- Mesh mesh = new Mesh();
- meshfilter = GetComponent<MeshFilter>();
- if (pointsChecked.Count < 2)
- {
- mesh.Clear();
- meshfilter.mesh = mesh;
- return;
- }
- controlPointsOrientation = new List<Quaternion>();
- lerpValues.Clear();
- snaps.Clear();
- points.Clear();
- pointsUp.Clear();
- pointsDown.Clear();
- orientations.Clear();
- tangents.Clear();
- normalsList.Clear();
- widths.Clear();
- controlPointsUp.Clear();
- controlPointsDown.Clear();
- verticesBeginning.Clear();
- verticesEnding.Clear();
- normalsBeginning.Clear();
- normalsEnding.Clear();
- if (beginningSpline != null && beginningSpline.controlPointsRotations.Count > 0)
- controlPointsRotations[0] = Quaternion.identity;
- if (endingSpline != null && endingSpline.controlPointsRotations.Count > 0)
- controlPointsRotations[controlPointsRotations.Count - 1] = Quaternion.identity;
- for (int i = 0; i < pointsChecked.Count; i++)
- {
- if (i > pointsChecked.Count - 2)
- {
- continue;
- }
- CalculateCatmullRomSideSplines(pointsChecked, i);
- }
- if (beginningSpline != null && beginningSpline.controlPointsRotations.Count > 0)
- controlPointsRotations[0] = Quaternion.Inverse(controlPointsOrientation[0]) * (beginningSpline.controlPointsOrientation[beginningSpline.controlPointsOrientation.Count - 1]);
- if (endingSpline != null && endingSpline.controlPointsRotations.Count > 0)
- controlPointsRotations[controlPointsRotations.Count - 1] = Quaternion.Inverse(controlPointsOrientation[controlPointsOrientation.Count - 1]) * (endingSpline.controlPointsOrientation[0]);// * endingSpline.controlPointsRotations [0]);
- controlPointsOrientation = new List<Quaternion>();
- controlPointsUp.Clear();
- controlPointsDown.Clear();
- for (int i = 0; i < pointsChecked.Count; i++)
- {
- if (i > pointsChecked.Count - 2)
- {
- continue;
- }
- CalculateCatmullRomSideSplines(pointsChecked, i);
- }
- for (int i = 0; i < pointsChecked.Count; i++)
- {
- if (i > pointsChecked.Count - 2)
- {
- continue;
- }
- CalculateCatmullRomSplineParameters(pointsChecked, i);
- }
- for (int i = 0; i < controlPointsUp.Count; i++)
- {
- if (i > controlPointsUp.Count - 2)
- {
- continue;
- }
- CalculateCatmullRomSpline(controlPointsUp, i, ref pointsUp);
- }
- for (int i = 0; i < controlPointsDown.Count; i++)
- {
- if (i > controlPointsDown.Count - 2)
- {
- continue;
- }
- CalculateCatmullRomSpline(controlPointsDown, i, ref pointsDown);
- }
- GenerateMesh(ref mesh);
- if (generatedSplines != null)
- {
- generatedSplines.Add(this);
- foreach (var item in beginnigChildSplines)
- {
- if (item != null && !generatedSplines.Contains(item))
- {
- if (item.beginningSpline == this || item.endingSpline == this)
- {
- item.GenerateSpline(generatedSplines);
- }
- }
- }
- foreach (var item in endingChildSplines)
- {
- if (item != null && !generatedSplines.Contains(item))
- {
- if (item.beginningSpline == this || item.endingSpline == this)
- {
- item.GenerateSpline(generatedSplines);
- }
- }
- }
- }
- }
- void CalculateCatmullRomSideSplines(List<Vector4> controlPoints, int pos)
- {
- Vector3 p0 = controlPoints[pos];
- Vector3 p1 = controlPoints[pos];
- Vector3 p2 = controlPoints[ClampListPos(pos + 1)];
- Vector3 p3 = controlPoints[ClampListPos(pos + 1)];
- if (pos > 0)
- p0 = controlPoints[ClampListPos(pos - 1)];
- if (pos < controlPoints.Count - 2)
- p3 = controlPoints[ClampListPos(pos + 2)];
- int tValueMax = 0;
- if (pos == controlPoints.Count - 2)
- {
- tValueMax = 1;
- }
- for (int tValue = 0; tValue <= tValueMax; tValue++)
- {
- Vector3 newPos = GetCatmullRomPosition(tValue, p0, p1, p2, p3);
- Vector3 tangent = GetCatmullRomTangent(tValue, p0, p1, p2, p3).normalized;
- Vector3 normal = CalculateNormal(tangent, Vector3.up).normalized;
- Quaternion orientation;
- if (normal == tangent && normal == Vector3.zero)
- orientation = Quaternion.identity;
- else
- orientation = Quaternion.LookRotation(tangent, normal);
- orientation *= Quaternion.Lerp(controlPointsRotations[pos], controlPointsRotations[ClampListPos(pos + 1)], tValue);
- // if (beginningSpline && pos == 0) {
- //
- // int lastId = beginningSpline.controlPointsOrientation.Count - 1;
- // //orientation = beginningSpline.controlPointsOrientation [lastId];
- //
- // }
- //
- // if (endingSpline && pos == controlPoints.Count - 2 && tValue == 1) {
- //
- // //orientation = endingSpline.controlPointsOrientation [0];
- //
- // }
- controlPointsOrientation.Add(orientation);
- Vector3 posUp = newPos + orientation * (0.5f * controlPoints[pos + tValue].w * Vector3.right);
- Vector3 posDown = newPos + orientation * (0.5f * controlPoints[pos + tValue].w * Vector3.left);
- controlPointsUp.Add(posUp);
- controlPointsDown.Add(posDown);
- }
- }
- void CalculateCatmullRomSplineParameters(List<Vector4> controlPoints, int pos, bool initialPoints = false)
- {
- Vector3 p0 = controlPoints[pos];
- Vector3 p1 = controlPoints[pos];
- Vector3 p2 = controlPoints[ClampListPos(pos + 1)];
- Vector3 p3 = controlPoints[ClampListPos(pos + 1)];
- if (pos > 0)
- p0 = controlPoints[ClampListPos(pos - 1)];
- if (pos < controlPoints.Count - 2)
- p3 = controlPoints[ClampListPos(pos + 2)];
- int loops = Mathf.FloorToInt(1f / traingleDensity);
- float i = 1;
- float start = 0;
- if (pos > 0)
- start = 1;
- for (i = start; i <= loops; i++)
- {
- float t = i * traingleDensity;
- CalculatePointParameters(controlPoints, pos, p0, p1, p2, p3, t);
- }
- if (i < loops)
- {
- i = loops;
- float t = i * traingleDensity;
- CalculatePointParameters(controlPoints, pos, p0, p1, p2, p3, t);
- }
- }
- void CalculateCatmullRomSpline(List<Vector3> controlPoints, int pos, ref List<Vector3> points)
- {
- Vector3 p0 = controlPoints[pos];
- Vector3 p1 = controlPoints[pos];
- Vector3 p2 = controlPoints[ClampListPos(pos + 1)];
- Vector3 p3 = controlPoints[ClampListPos(pos + 1)];
- if (pos > 0)
- p0 = controlPoints[ClampListPos(pos - 1)];
- if (pos < controlPoints.Count - 2)
- p3 = controlPoints[ClampListPos(pos + 2)];
- int loops = Mathf.FloorToInt(1f / traingleDensity);
- float i = 1;
- float start = 0;
- if (pos > 0)
- start = 1;
- for (i = start; i <= loops; i++)
- {
- float t = i * traingleDensity;
- CalculatePointPosition(controlPoints, pos, p0, p1, p2, p3, t, ref points);
- }
- if (i < loops)
- {
- i = loops;
- float t = i * traingleDensity;
- CalculatePointPosition(controlPoints, pos, p0, p1, p2, p3, t, ref points);
- }
- }
- void CalculatePointPosition(List<Vector3> controlPoints, int pos, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t, ref List<Vector3> points)
- {
- Vector3 newPos = GetCatmullRomPosition(t, p0, p1, p2, p3);
- points.Add(newPos);
- Vector3 tangent = GetCatmullRomTangent(t, p0, p1, p2, p3).normalized;
- Vector3 normal = CalculateNormal(tangent, Vector3.up).normalized;
- }
- void CalculatePointParameters(List<Vector4> controlPoints, int pos, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
- {
- Vector3 newPos = GetCatmullRomPosition(t, p0, p1, p2, p3);
- widths.Add(Mathf.Lerp(controlPoints[pos].w, controlPoints[ClampListPos(pos + 1)].w, t));
- if (controlPointsSnap.Count > pos + 1)
- snaps.Add(Mathf.Lerp(controlPointsSnap[pos], controlPointsSnap[ClampListPos(pos + 1)], t));
- else
- snaps.Add(0);
- lerpValues.Add(pos + t);
- points.Add(newPos);
- Vector3 tangent = GetCatmullRomTangent(t, p0, p1, p2, p3).normalized;
- Vector3 normal = CalculateNormal(tangent, Vector3.up).normalized;
- // Debug.Log(tangent + " CalculatePointParameters: " + normal);
- Quaternion orientation;
- if (normal == tangent && normal == Vector3.zero)
- orientation = Quaternion.identity;
- else
- orientation = Quaternion.LookRotation(tangent, normal);
- orientation *= Quaternion.Lerp(controlPointsRotations[pos], controlPointsRotations[ClampListPos(pos + 1)], t);
- orientations.Add(orientation);
- tangents.Add(tangent);
- if (normalsList.Count > 0 && Vector3.Angle(normalsList[normalsList.Count - 1], normal) > 90)
- {
- normal *= -1;
- }
- normalsList.Add(normal);
- }
- int ClampListPos(int pos)
- {
- if (pos < 0)
- {
- pos = controlPoints.Count - 1;
- }
- if (pos > controlPoints.Count)
- {
- pos = 1;
- }
- else if (pos > controlPoints.Count - 1)
- {
- pos = 0;
- }
- return pos;
- }
- Vector3 GetCatmullRomPosition(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
- {
- Vector3 a = 2f * p1;
- Vector3 b = p2 - p0;
- Vector3 c = 2f * p0 - 5f * p1 + 4f * p2 - p3;
- Vector3 d = -p0 + 3f * p1 - 3f * p2 + p3;
- Vector3 pos = 0.5f * (a + (b * t) + (c * t * t) + (d * t * t * t));
- return pos;
- }
- Vector3 GetCatmullRomTangent(float t, Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3)
- {
- return 0.5f * ((-p0 + p2) + 2f * (2f * p0 - 5f * p1 + 4f * p2 - p3) * t + 3f * (-p0 + 3f * p1 - 3f * p2 + p3) * t * t);
- }
- Vector3 CalculateNormal(Vector3 tangent, Vector3 up)
- {
- Vector3 binormal = Vector3.Cross(up, tangent);
- return Vector3.Cross(tangent, binormal);
- }
- void GenerateMesh(ref Mesh mesh)
- {
- MeshRenderer meshRenderer = gameObject.GetComponent<MeshRenderer>();
- if (meshRenderer != null)
- {
- meshRenderer.receiveShadows = receiveShadows;
- meshRenderer.shadowCastingMode = shadowCastingMode;
- }
- foreach (var item in meshesPartTransforms)
- {
- if (item != null)
- {
- #if UNITY_EDITOR
- if (EditorApplication.isPlaying)
- Destroy(item.gameObject);
- else
- DestroyImmediate(item.gameObject);
- #else
- Destroy(item.gameObject);
- #endif
- }
- }
- int segments = points.Count - 1;
- int edgeLoops = points.Count;
- int vertCount = vertsInShape * edgeLoops;
- List<int> triangleIndices = new List<int>();
- Vector3[] vertices = new Vector3[vertCount];
- Vector3[] normals = new Vector3[vertCount];
- Vector2[] uvs = new Vector2[vertCount];
- Vector2[] uvs3 = new Vector2[vertCount];
- Vector2[] uvs4 = new Vector2[vertCount];
- if (colors == null || colors.Length != vertCount)
- {
- colors = new Color[vertCount];
- for (int i = 0; i < colors.Length; i++)
- {
- colors[i] = Color.black;
- }
- }
- if (colorsFlowMap.Count != vertCount)
- colorsFlowMap.Clear();
- length = 0;
- fulllength = 0;
- if (beginningSpline != null)
- length = beginningSpline.length;
- minMaxWidth = 1;
- uvWidth = 1;
- uvBeginning = 0;
- if (beginningSpline != null)
- {
- minMaxWidth = beginningMaxWidth - beginningMinWidth;
- uvWidth = minMaxWidth * beginningSpline.uvWidth;
- uvBeginning = beginningSpline.uvWidth * beginningMinWidth + beginningSpline.uvBeginning;
- }
- else if (endingSpline != null)
- {
- minMaxWidth = endingMaxWidth - endingMinWidth;
- uvWidth = minMaxWidth * endingSpline.uvWidth;
- uvBeginning = endingSpline.uvWidth * endingMinWidth + endingSpline.uvBeginning;
- }
- for (int i = 0; i < pointsDown.Count; i++)
- {
- float width = widths[i];
- if (i > 0)
- fulllength += uvWidth * Vector3.Distance(pointsDown[i], pointsDown[i - 1]) / (float)(uvScale * width);
- }
- float roundEnding = Mathf.Round(fulllength);
- for (int i = 0; i < pointsDown.Count; i++)
- {
- float width = widths[i];
- int offset = i * vertsInShape;
- if (i > 0)
- {
- length += (uvWidth * Vector3.Distance(pointsDown[i], pointsDown[i - 1]) / (float)(uvScale * width)) / fulllength * roundEnding;
- }
- float u = 0;
- float u3 = 0;
- for (int j = 0; j < vertsInShape; j++)
- {
- int id = offset + j;
- //VERTICES
- float pos = j / (float)(vertsInShape - 1);
- if (pos < 0.5f)
- pos *= minVal * 2;
- else
- pos = ((pos - 0.5f) * (1 - maxVal) + 0.5f * maxVal) * 2;
- if (i == 0 && beginningSpline != null && beginningSpline.verticesEnding != null && beginningSpline.normalsEnding != null)
- {
- int pos2 = (int)(beginningSpline.vertsInShape * beginningMinWidth);
- vertices[id] = beginningSpline.verticesEnding[Mathf.Clamp(j + pos2, 0, beginningSpline.verticesEnding.Count - 1)] + beginningSpline.transform.position - transform.position;
- //if (beginningSpline.normalsEnding.Count > 0)
- // normals [id] = beginningSpline.normalsEnding [Mathf.Clamp (j + pos2, 0, beginningSpline.normalsEnding.Count - 1)];
- }
- else if (i == pointsDown.Count - 1 && endingSpline != null && endingSpline.verticesBeginning != null && endingSpline.verticesBeginning.Count > 0 && endingSpline.normalsBeginning != null)
- {
- int pos2 = (int)(endingSpline.vertsInShape * endingMinWidth);
- vertices[id] = endingSpline.verticesBeginning[Mathf.Clamp(j + pos2, 0, endingSpline.verticesBeginning.Count - 1)] + endingSpline.transform.position - transform.position;
- //if (endingSpline.normalsBeginning.Count > 0)
- // normals [id] = endingSpline.normalsBeginning [Mathf.Clamp (j + pos2, 0, endingSpline.normalsBeginning.Count - 1)];
- }
- else
- {
- vertices[id] = Vector3.Lerp(pointsDown[i], pointsUp[i], pos);
- RaycastHit hit;
- if (Physics.Raycast(vertices[id] + transform.position + Vector3.up * 5, Vector3.down, out hit, 1000, snapMask.value))
- {
- 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);
- }
- if (normalFromRaycast)
- {
- RaycastHit hit2;
- if (Physics.Raycast(points[i] + transform.position + Vector3.up * 5, Vector3.down, out hit2, 1000, snapMask.value))
- {
- normals[id] = hit2.normal;
- }
- }
- vertices[id].y += Mathf.Lerp(controlPointsMeshCurves[Mathf.FloorToInt(lerpValues[i])].Evaluate(pos),
- controlPointsMeshCurves[Mathf.CeilToInt(lerpValues[i])].Evaluate(pos),
- lerpValues[i] - Mathf.Floor(lerpValues[i]));
- }
- if (i > 0 && i < 5 && beginningSpline != null && beginningSpline.verticesEnding != null)
- {
- vertices[id].y = (vertices[id].y + vertices[id - vertsInShape].y) * 0.5f;
- }
- if (i == pointsDown.Count - 1 && endingSpline != null && endingSpline.verticesBeginning != null)
- {
- for (int k = 1; k < 5; k++)
- {
- vertices[id - vertsInShape * k].y = (vertices[id - vertsInShape * (k - 1)].y + vertices[id - vertsInShape * k].y) * 0.5f;
- }
- }
- if (i == 0)
- verticesBeginning.Add(vertices[id]);
- if (i == pointsDown.Count - 1)
- verticesEnding.Add(vertices[id]);
- //NORMALS
- if (!normalFromRaycast)
- // if ((i > 0 || beginningSpline == null) && (i < pointsDown.Count - 1 || endingSpline == null))
- normals[id] = orientations[i] * Vector3.up;
- //if (beginningSpline != null && i == 1)
- // normals [id] = (normals [id] + normals [id - vertsInShape]) * 0.5f;
- //
- //if (i == pointsDown.Count - 2 && endingSpline != null && endingSpline.normalsBeginning != null && endingSpline.normalsBeginning.Count > 0) {
- //
- // int pos2 = (int)(endingSpline.vertsInShape * endingMinWidth);
- // normals [id] = (normals [id] + endingSpline.normalsBeginning [Mathf.Clamp (j + pos2, 0, endingSpline.normalsBeginning.Count - 1)]) * 0.5f;
- //
- //}
- if (i == 0)
- normalsBeginning.Add(normals[id]);
- if (i == pointsDown.Count - 1)
- normalsEnding.Add(normals[id]);
- //UVS
- if (j > 0)
- {
- u = (pos) * uvWidth;
- u3 = pos;
- }
- if (beginningSpline != null || endingSpline != null)
- {
- u += uvBeginning;
- }
- u = u / uvScale;
- float uv4u = FlowCalculate(u3, normals[id].y, vertices[id]);
- int lerpDistance = 10;
- if (beginnigChildSplines.Count > 0 && i <= lerpDistance)
- {
- float lerpUv4u = 0;
- foreach (var item in beginnigChildSplines)
- {
- if (item == null)
- continue;
- if (Mathf.CeilToInt(item.endingMaxWidth * (vertsInShape - 1)) >= j && j >= Mathf.CeilToInt(item.endingMinWidth * (vertsInShape - 1)))
- {
- lerpUv4u = (j - Mathf.CeilToInt(item.endingMinWidth * (vertsInShape - 1)))
- / (float)(Mathf.CeilToInt(item.endingMaxWidth * (vertsInShape - 1)) - Mathf.CeilToInt(item.endingMinWidth * (vertsInShape - 1)));
- lerpUv4u = FlowCalculate(lerpUv4u, normals[id].y, vertices[id]);
- }
- }
- if (i > 0)
- uv4u = Mathf.Lerp(uv4u, lerpUv4u, 1 - (i / (float)lerpDistance));
- else
- uv4u = lerpUv4u;
- }
- if (i >= pointsDown.Count - lerpDistance - 1 && endingChildSplines.Count > 0)
- {
- float lerpUv4u = 0;
- foreach (var item in endingChildSplines)
- {
- if (item == null)
- continue;
- if (Mathf.CeilToInt(item.beginningMaxWidth * (vertsInShape - 1)) >= j && j >= Mathf.CeilToInt(item.beginningMinWidth * (vertsInShape - 1)))
- {
- lerpUv4u = (j - Mathf.CeilToInt(item.beginningMinWidth * (vertsInShape - 1)))
- / (float)(Mathf.CeilToInt(item.beginningMaxWidth * (vertsInShape - 1)) - Mathf.CeilToInt(item.beginningMinWidth * (vertsInShape - 1)));
- lerpUv4u = FlowCalculate(lerpUv4u, normals[id].y, vertices[id]);
- }
- }
- if (i < pointsDown.Count - 1)
- uv4u = Mathf.Lerp(uv4u, lerpUv4u, (i - (pointsDown.Count - lerpDistance - 1)) / (float)lerpDistance);
- else
- uv4u = lerpUv4u;
- }
- float uv4v = -(u3 - 0.5f) * 0.01f;
- if (uvRotation)
- {
- if (!invertUVDirection)
- {
- uvs[id] = new Vector2(1 - length, u);
- uvs3[id] = new Vector2(1 - length / (float)fulllength, u3);
- uvs4[id] = new Vector2(uv4u, uv4v);
- }
- else
- {
- uvs[id] = new Vector2(1 + length, u);
- uvs3[id] = new Vector2(1 + length / (float)fulllength, u3);
- uvs4[id] = new Vector2(uv4u, uv4v);
- }
- }
- else
- {
- if (!invertUVDirection)
- {
- uvs[id] = new Vector2(u, 1 - length);
- uvs3[id] = new Vector2(u3, 1 - length / (float)fulllength);
- uvs4[id] = new Vector2(uv4v, uv4u);
- }
- else
- {
- uvs[id] = new Vector2(u, 1 + length);
- uvs3[id] = new Vector2(u3, 1 + length / (float)fulllength);
- uvs4[id] = new Vector2(uv4v, uv4u);
- }
- }
- float tempRound = (int)(uvs4[id].x * 100);
- uvs4[id].x = tempRound * 0.01f;
- tempRound = (int)(uvs4[id].y * 100);
- uvs4[id].y = tempRound * 0.01f;
- if (colorsFlowMap.Count <= id)
- colorsFlowMap.Add(uvs4[id]);
- else if (!overrideFlowMap)
- colorsFlowMap[id] = uvs4[id];
- }
- }
- //TRIANGLES
- for (int i = 0; i < segments; i++)
- {
- int offset = i * vertsInShape;
- for (int l = 0; l < vertsInShape - 1; l += 1)
- {
- int a = offset + l;
- int b = offset + l + vertsInShape;
- int c = offset + l + 1 + vertsInShape;
- int d = offset + l + 1;
- triangleIndices.Add(a);
- triangleIndices.Add(b);
- triangleIndices.Add(c);
- triangleIndices.Add(c);
- triangleIndices.Add(d);
- triangleIndices.Add(a);
- }
- }
- verticeDirection.Clear();
- for (int i = 0; i < vertices.Length - vertsInShape; i++)
- {
- Vector3 dir = (vertices[i + vertsInShape] - vertices[i]).normalized;
- if (uvRotation)
- dir = new Vector3(dir.z, 0, -dir.x);
- verticeDirection.Add(dir);
- }
- for (int i = vertices.Length - vertsInShape; i < vertices.Length; i++)
- {
- Vector3 dir = (vertices[i] - vertices[i - vertsInShape]).normalized;
- if (uvRotation)
- dir = new Vector3(dir.z, 0, -dir.x);
- verticeDirection.Add(dir);
- }
- mesh = new Mesh();
- mesh.Clear();
- mesh.vertices = vertices;
- mesh.normals = normals;
- mesh.uv = uvs;
- mesh.uv3 = uvs3;
- mesh.uv4 = colorsFlowMap.ToArray();
- mesh.triangles = triangleIndices.ToArray();
- mesh.colors = colors;
- mesh.RecalculateTangents();
- meshfilter.mesh = mesh;
- GetComponent<MeshRenderer>().enabled = true;
- if (generateMeshParts)
- GenerateMeshParts(mesh);
- }
- public void GenerateMeshParts(Mesh baseMesh)
- {
- foreach (var item in meshesPartTransforms)
- {
- if (item != null)
- DestroyImmediate(item.gameObject);
- }
- Vector3[] vertices = baseMesh.vertices;
- Vector3[] normals = baseMesh.normals;
- Vector2[] uvs = baseMesh.uv;
- Vector2[] uvs3 = baseMesh.uv3;
- GetComponent<MeshRenderer>().enabled = false;
- int verticesLinesPart = Mathf.RoundToInt((vertices.Length / vertsInShape) / (float)meshPartsCount);
- int verticesInPart = verticesLinesPart * vertsInShape;
- for (int i = 0; i < meshPartsCount; i++)
- {
- GameObject go = new GameObject(gameObject.name + "- Mesh part " + i);
- go.transform.SetParent(gameObject.transform, false);
- go.transform.localPosition = Vector3.zero;
- go.transform.localEulerAngles = Vector3.zero;
- go.transform.localScale = Vector3.one;
- meshesPartTransforms.Add(go.transform);
- MeshRenderer meshRendererPart = go.AddComponent<MeshRenderer>();
- meshRendererPart.sharedMaterial = GetComponent<MeshRenderer>().sharedMaterial;
- meshRendererPart.receiveShadows = receiveShadows;
- meshRendererPart.shadowCastingMode = shadowCastingMode;
- MeshFilter mf = go.AddComponent<MeshFilter>();
- Mesh meshPart = new Mesh();
- meshPart.Clear();
- List<Vector3> verticesPart = new List<Vector3>();
- List<Vector3> normalsPart = new List<Vector3>();
- List<Vector2> uvPart = new List<Vector2>();
- List<Vector2> uv3Part = new List<Vector2>();
- List<Vector2> uv4Part = new List<Vector2>();
- List<Color> colorsPart = new List<Color>();
- List<int> trianglesPart = new List<int>();
- for (int j = verticesInPart * i + (i > 0 ? -vertsInShape : 0); (j < verticesInPart * (i + 1) && j < vertices.Length) || (i == meshPartsCount - 1 && j < vertices.Length); j++)
- {
- verticesPart.Add(vertices[j]);
- normalsPart.Add(normals[j]);
- uvPart.Add(uvs[j]);
- uv3Part.Add(uvs3[j]);
- uv4Part.Add(colorsFlowMap[j]);
- colorsPart.Add(colors[j]);
- }
- if (verticesPart.Count > 0)
- {
- Vector3 pivotChange = verticesPart[0];
- for (int j = 0; j < verticesPart.Count; j++)
- {
- verticesPart[j] = verticesPart[j] - pivotChange;
- }
- for (int k = 0; k < verticesPart.Count / vertsInShape - 1; k++)
- {
- int offset = k * vertsInShape;
- for (int l = 0; l < vertsInShape - 1; l += 1)
- {
- int a = offset + l;
- int b = offset + l + vertsInShape;
- int c = offset + l + 1 + vertsInShape;
- int d = offset + l + 1;
- trianglesPart.Add(a);
- trianglesPart.Add(b);
- trianglesPart.Add(c);
- trianglesPart.Add(c);
- trianglesPart.Add(d);
- trianglesPart.Add(a);
- }
- }
- go.transform.position += pivotChange;
- meshPart.vertices = verticesPart.ToArray();
- meshPart.triangles = trianglesPart.ToArray();
- meshPart.normals = normalsPart.ToArray();
- meshPart.uv = uvPart.ToArray();
- meshPart.uv3 = uv3Part.ToArray();
- meshPart.uv4 = uv4Part.ToArray();
- meshPart.colors = colorsPart.ToArray();
- meshPart.RecalculateTangents();
- mf.mesh = meshPart;
- //MeshCollider meshCollider = go.AddComponent<MeshCollider>();
- //meshCollider.cookingOptions = MeshColliderCookingOptions.InflateConvexMesh | MeshColliderCookingOptions.CookForFasterSimulation | MeshColliderCookingOptions.EnableMeshCleaning | MeshColliderCookingOptions.WeldColocatedVertices;
- //meshCollider.skinWidth = 0.1f;
- //meshCollider.convex = true;
- //meshCollider.isTrigger = true;
- }
- }
- }
- public void AddNoiseToWidths()
- {
- for (int i = 0; i < controlPoints.Count; i++)
- {
- Vector4 controlPoint = controlPoints[i];
- controlPoint.w = controlPoint.w + (noiseWidth ? noiseMultiplierWidth * (Mathf.PerlinNoise(noiseSizeWidth * i, 0) - 0.5f) : 0);
- if (controlPoint.w < 0)
- {
- controlPoint.w = 0;
- }
- controlPoints[i] = controlPoint;
- }
- }
- public void SimulateRiver(bool generate = true)
- {
- if (meshGO != null)
- {
- if (Application.isEditor)
- DestroyImmediate(meshGO);
- else
- Destroy(meshGO);
- }
- if (controlPoints.Count == 0)
- {
- Debug.Log("Add one point to start Simulating River");
- return;
- }
- Ray ray = new Ray();
- RaycastHit hit;
- Vector3 lastPosition = transform.TransformPoint((Vector3)controlPoints[controlPoints.Count - 1]);
- List<Vector3> positionsGenerated = new List<Vector3>();
- if (controlPoints.Count > 1)
- {
- positionsGenerated.Add(transform.TransformPoint((Vector3)controlPoints[controlPoints.Count - 2]));
- positionsGenerated.Add(lastPosition);
- }
- List<Vector3> samplePositionsGenerated = new List<Vector3>();
- samplePositionsGenerated.Add(lastPosition);
- //Debug.DrawRay(lastPosition + new Vector3(0, 3, 0), Vector3.down * 20, Color.white, 3);
- float length = 0;
- int i = -1;
- int added = 0;
- bool end = false;
- float widthNew = 0;
- if (controlPoints.Count > 0)
- widthNew = controlPoints[controlPoints.Count - 1].w;
- else
- widthNew = width;
- do
- {
- i++;
- if (i > 0)
- {
- Vector3 maxPosition = Vector3.zero;
- float max = float.MinValue;
- bool foundNextPositon = false;
- for (float j = simulatedMinStepSize; j < 10; j += 0.1f)
- {
- for (int angle = 0; angle < 36; angle++)
- {
- float x = j * Mathf.Cos(angle);
- float z = j * Mathf.Sin(angle);
- ray.origin = lastPosition + new Vector3(0, 1000, 0) + new Vector3(x, 0, z);
- ray.direction = Vector3.down;
- if (Physics.Raycast(ray, out hit, 10000))
- {
- if (hit.distance > max)
- {
- bool goodPoint = true;
- foreach (var item in positionsGenerated)
- {
- if (Vector3.Distance(item, lastPosition) > Vector3.Distance(item, hit.point) + 0.5f)
- {
- goodPoint = false;
- break;
- }
- }
- if (goodPoint)
- {
- foundNextPositon = true;
- max = hit.distance;
- maxPosition = hit.point;
- }
- }
- //else
- // Debug.DrawRay(ray.origin, ray.direction * 10000, Color.red, 3);
- }
- }
- if (foundNextPositon)
- break;
- }
- if (!foundNextPositon)
- break;
- if (maxPosition.y > lastPosition.y)
- {
- if (simulatedNoUp)
- maxPosition.y = lastPosition.y;
- if (simulatedBreakOnUp)
- end = true;
- //Debug.DrawRay(maxPosition + new Vector3(0, 5, 0), ray.direction * 10, Color.red, 3);
- }
- // else
- // Debug.DrawRay(maxPosition + new Vector3(0, 5, 0), ray.direction * 10, Color.blue, 3);
- length += Vector3.Distance(maxPosition, lastPosition);
- if (i % simulatedRiverPoints == 0 || simulatedRiverLength <= length || end)
- {
- //Debug.DrawRay(maxPosition + new Vector3(0, 5, 0), ray.direction * 20, Color.white, 3);
- samplePositionsGenerated.Add(maxPosition);
- if (generate)
- {
- added++;
- Vector4 newPosition = maxPosition - transform.position;
- newPosition.w = widthNew + (noiseWidth ? noiseMultiplierWidth * (Mathf.PerlinNoise(noiseSizeWidth * added, 0) - 0.5f) : 0);
- controlPointsRotations.Add(Quaternion.identity);
- controlPoints.Add(newPosition);
- controlPointsSnap.Add(0);
- controlPointsMeshCurves.Add(new AnimationCurve(meshCurve.keys));
- }
- }
- else
- {
- //samplePositionsGenerated.Add(maxPosition);
- //Debug.DrawRay(maxPosition + new Vector3(0, 3, 0), ray.direction * 20, Color.Lerp(Color.red, Color.green, i / (float)spline.simulatedRiverLength), 3);
- }
- positionsGenerated.Add(lastPosition);
- lastPosition = maxPosition;
- }
- } while (simulatedRiverLength > length && !end);
- if (!generate)
- {
- if (controlPoints.Count > 0)
- widthNew = controlPoints[controlPoints.Count - 1].w;
- else
- widthNew = width;
- float widthNoise = 0;
- List<List<Vector4>> positionArray = new List<List<Vector4>>();
- Vector3 v1 = new Vector3();
- for (i = 0; i < samplePositionsGenerated.Count - 1; i++)
- {
- widthNoise = widthNew + (noiseWidth ? noiseMultiplierWidth * (Mathf.PerlinNoise(noiseSizeWidth * i, 0) - 0.5f) : 0);
- //Debug.DrawLine(samplePositionsGenerated[i], samplePositionsGenerated[i + 1], Color.white, 3);
- v1 = Vector3.Cross(samplePositionsGenerated[i + 1] - samplePositionsGenerated[i], Vector3.up).normalized;
- if (i > 0)
- {
- Vector3 v2 = Vector3.Cross(samplePositionsGenerated[i] - samplePositionsGenerated[i - 1], Vector3.up).normalized;
- v1 = (v1 + v2).normalized;
- }
- //Vector3 v2 = Vector3.Cross(samplePositionsGenerated[i + 1] - samplePositionsGenerated[i], v1).normalized;
- //Debug.DrawLine(samplePositionsGenerated[i] - v1 * widthNew * 0.5f, samplePositionsGenerated[i] + v1 * widthNew * 0.5f, Color.blue, 3);
- List<Vector4> positionRow = new List<Vector4>();
- positionRow.Add(samplePositionsGenerated[i] + v1 * widthNoise * 0.5f);
- positionRow.Add(samplePositionsGenerated[i] - v1 * widthNoise * 0.5f);
- positionArray.Add(positionRow);
- }
- widthNoise = widthNew + (noiseWidth ? noiseMultiplierWidth * (Mathf.PerlinNoise(noiseSizeWidth * i, 0) - 0.5f) : 0);
- List<Vector4> positionRowLast = new List<Vector4>();
- positionRowLast.Add(samplePositionsGenerated[i] + v1 * widthNoise * 0.5f);
- positionRowLast.Add(samplePositionsGenerated[i] - v1 * widthNoise * 0.5f);
- positionArray.Add(positionRowLast);
- Mesh meshTerrain = new Mesh();
- meshTerrain.indexFormat = IndexFormat.UInt32;
- List<Vector3> vertices = new List<Vector3>();
- List<int> triangles = new List<int>();
- // List<Vector2> uv = new List<Vector2>();
- foreach (var positionRow in positionArray)
- {
- foreach (var vert in positionRow)
- {
- vertices.Add(vert);
- }
- }
- for (i = 0; i < positionArray.Count - 1; i++)
- {
- int count = positionArray[i].Count;
- for (int j = 0; j < count - 1; j++)
- {
- triangles.Add(j + i * count);
- triangles.Add(j + (i + 1) * count);
- triangles.Add((j + 1) + i * count);
- triangles.Add((j + 1) + i * count);
- triangles.Add(j + (i + 1) * count);
- triangles.Add((j + 1) + (i + 1) * count);
- }
- }
- meshTerrain.SetVertices(vertices);
- meshTerrain.SetTriangles(triangles, 0);
- // meshTerrain.SetUVs(0, uv);
- meshTerrain.RecalculateNormals();
- meshTerrain.RecalculateTangents();
- meshTerrain.RecalculateBounds();
- meshGO = new GameObject("TerrainMesh");
- meshGO.hideFlags = HideFlags.HideAndDontSave;
- meshGO.AddComponent<MeshFilter>();
- MeshRenderer meshRenderer = meshGO.AddComponent<MeshRenderer>();
- meshRenderer.sharedMaterial = new Material(Shader.Find("Debug Terrain Carve"));
- meshRenderer.sharedMaterial.color = new Color(0, 0.5f, 0);
- meshGO.transform.position = Vector3.zero;
- meshGO.GetComponent<MeshFilter>().sharedMesh = meshTerrain;
- }
- }
- #region Terrain
- public void ShowTerrainCarve(float differentSize = 0)
- {
- if (Application.isEditor && meshGO == null)
- {
- Transform meshGoTrans = transform.Find("TerrainMesh");
- if (meshGoTrans != null)
- meshGO = meshGoTrans.gameObject;
- }
- if (meshGO != null)
- {
- if (Application.isEditor)
- DestroyImmediate(meshGO);
- else
- Destroy(meshGO);
- }
- Mesh mesh = meshfilter.sharedMesh;
- RaycastHit hit;
- Vector3 rayPointDown;
- Vector3 rayPointUp;
- Vector3 point;
- detailTerrainForward = 2;
- detailTerrain = 10;
- if (differentSize == 0)
- terrainAdditionalWidth = distSmooth + distSmoothStart;
- else
- terrainAdditionalWidth = differentSize;
- List<List<Vector4>> positionArray = new List<List<Vector4>>();
- float noise = 0;
- for (int i = 0; i < pointsDown.Count - 1; i++)
- {
- for (int tf = 0; tf <= detailTerrainForward; tf++)
- {
- List<Vector4> positionArrayRow = new List<Vector4>();
- rayPointDown = Vector3.Lerp(pointsDown[i], pointsDown[i + 1], tf / (float)detailTerrainForward);
- rayPointUp = Vector3.Lerp(pointsUp[i], pointsUp[i + 1], tf / (float)detailTerrainForward);
- Vector3 diff = rayPointDown - rayPointUp;
- float diffMagintude = diff.magnitude;
- rayPointDown += diff * 0.05f;
- rayPointUp -= diff * 0.05f;
- diff.Normalize();
- Vector3 rayPointDownNew = rayPointDown + diff * terrainAdditionalWidth * 0.5f;
- Vector3 rayPointUpNew = rayPointUp - diff * terrainAdditionalWidth * 0.5f;
- if (terrainAdditionalWidth > 0)
- {
- for (int t = 0; t < detailTerrain; t++)
- {
- point = Vector3.Lerp(rayPointDownNew, rayPointDown, t / (float)detailTerrain) + transform.position;
- if (Physics.Raycast(point + Vector3.up * 500, Vector3.down, out hit))
- {
- if (noiseCarve)
- noise = Mathf.PerlinNoise(point.x * noiseSizeX, point.z * noiseSizeZ) * noiseMultiplierOutside - noiseMultiplierOutside * 0.5f;
- else
- noise = 0;
- float evaluate = 1 - t / (float)detailTerrain;
- evaluate *= terrainAdditionalWidth;
- float height = point.y + terrainCarve.Evaluate(-evaluate) + terrainCarve.Evaluate(-evaluate) * noise;
- float smoothValue = t / (float)detailTerrain;
- smoothValue = Mathf.Pow(smoothValue, terrainSmoothMultiplier);
- height = Mathf.Lerp(hit.point.y, height, smoothValue);
- Vector4 newPos = new Vector4(hit.point.x, height, hit.point.z, -evaluate);
- positionArrayRow.Add(newPos);
- }
- else
- positionArrayRow.Add(point);
- }
- }
- for (int t = 0; t <= detailTerrain; t++)
- {
- point = Vector3.Lerp(rayPointDown, rayPointUp, t / (float)detailTerrain) + transform.position;
- if (Physics.Raycast(point + Vector3.up * 500, Vector3.down, out hit))
- {
- if (noiseCarve)
- noise = Mathf.PerlinNoise(point.x * noiseSizeX, point.z * noiseSizeZ) * noiseMultiplierInside - noiseMultiplierInside * 0.5f;
- else
- noise = 0;
- float evaluate = diffMagintude * (0.5f - Mathf.Abs(0.5f - t / (float)detailTerrain));
- float height = point.y + terrainCarve.Evaluate(evaluate) + terrainCarve.Evaluate(evaluate) * noise;
- float smoothValue = 1 - 2 * Mathf.Abs(t / (float)detailTerrain - 0.5f);
- smoothValue = Mathf.Pow(smoothValue, terrainSmoothMultiplier);
- height = Mathf.Lerp(hit.point.y, height, 1);
- Vector4 newPos = new Vector4(hit.point.x, height, hit.point.z, evaluate);
- positionArrayRow.Add(newPos);
- }
- else
- positionArrayRow.Add(point);
- }
- if (terrainAdditionalWidth > 0)
- {
- for (int t = 1; t <= detailTerrain; t++)
- {
- point = Vector3.Lerp(rayPointUp, rayPointUpNew, t / (float)detailTerrain) + transform.position;
- if (Physics.Raycast(point + Vector3.up * 50, Vector3.down, out hit))
- {
- if (noiseCarve)
- noise = Mathf.PerlinNoise(point.x * noiseSizeX, point.z * noiseSizeZ) * noiseMultiplierOutside - noiseMultiplierOutside * 0.5f;
- else
- noise = 0;
- float evaluate = t / (float)detailTerrain;
- evaluate *= terrainAdditionalWidth;
- float height = point.y + terrainCarve.Evaluate(-evaluate) + terrainCarve.Evaluate(-evaluate) * noise;
- float smoothValue = 1 - t / (float)detailTerrain;
- smoothValue = Mathf.Pow(smoothValue, terrainSmoothMultiplier);
- height = Mathf.Lerp(hit.point.y, height, smoothValue);
- Vector4 newPos = new Vector4(hit.point.x, height, hit.point.z, -evaluate);
- positionArrayRow.Add(newPos);
- }
- else
- positionArrayRow.Add(point);
- }
- }
- positionArray.Add(positionArrayRow);
- }
- }
- Mesh meshTerrain = new Mesh();
- meshTerrain.indexFormat = IndexFormat.UInt32;
- List<Vector3> vertices = new List<Vector3>();
- List<int> triangles = new List<int>();
- List<Vector2> uv = new List<Vector2>();
- foreach (var positionRow in positionArray)
- {
- foreach (var vert in positionRow)
- {
- vertices.Add(vert);
- }
- }
- for (int i = 0; i < positionArray.Count - 1; i++)
- {
- int count = positionArray[i].Count;
- for (int j = 0; j < count - 1; j++)
- {
- triangles.Add(j + i * count);
- triangles.Add(j + (i + 1) * count);
- triangles.Add((j + 1) + i * count);
- triangles.Add((j + 1) + i * count);
- triangles.Add(j + (i + 1) * count);
- triangles.Add((j + 1) + (i + 1) * count);
- }
- }
- foreach (var positionRow in positionArray)
- {
- foreach (var vert in positionRow)
- {
- uv.Add(new Vector2(vert.w, 0));
- }
- }
- meshTerrain.SetVertices(vertices);
- meshTerrain.SetTriangles(triangles, 0);
- meshTerrain.SetUVs(0, uv);
- meshTerrain.RecalculateNormals();
- meshTerrain.RecalculateTangents();
- meshTerrain.RecalculateBounds();
- //if (meshGO == null)
- //{
- meshGO = new GameObject("TerrainMesh");
- meshGO.transform.parent = transform;
- meshGO.hideFlags = HideFlags.HideAndDontSave;
- meshGO.AddComponent<MeshFilter>();
- MeshRenderer meshRenderer = meshGO.AddComponent<MeshRenderer>();
- meshRenderer.sharedMaterial = new Material(Shader.Find("Debug Terrain Carve"));
- meshRenderer.sharedMaterial.color = new Color(0, 0.5f, 0);
- // }
- meshGO.transform.position = Vector3.zero;
- meshGO.GetComponent<MeshFilter>().sharedMesh = meshTerrain;
- if (overrideRiverRender)
- meshGO.GetComponent<MeshRenderer>().sharedMaterial.renderQueue = 5000;
- else
- meshGO.GetComponent<MeshRenderer>().sharedMaterial.renderQueue = 2980;
- }
- public void TerrainCarve()
- {
- bool debugLines = false;
- Physics.autoSyncTransforms = false;
- foreach (Terrain terrain in Terrain.activeTerrains)
- {
- TerrainData terrainData = terrain.terrainData;
- float posY = terrain.transform.position.y;
- float sizeX = terrain.terrainData.size.x;
- float sizeY = terrain.terrainData.size.y;
- float sizeZ = terrain.terrainData.size.z;
- float terrainTowidth = (1 / (float)sizeZ * (terrainData.heightmapResolution - 1));
- float terrainToheight = (1 / (float)sizeX * (terrainData.heightmapResolution - 1));
- float minX;
- float maxX;
- float minZ;
- float maxZ;
- #if UNITY_EDITOR
- Undo.RegisterCompleteObjectUndo(terrainData, "River curve");
- #endif
- MeshCollider meshCollider = meshGO.gameObject.AddComponent<MeshCollider>();
- List<Vector3> transformPointUp = new List<Vector3>();
- List<Vector3> transformPointDown = new List<Vector3>();
- int pointsCount = 5;
- int pointsStart = 0;//pointsUp.Count
- //List<Vector2> done = new List<Vector2>();
- //List<Vector3> positionArray = new List<Vector3>();
- Vector3 pointOne = Vector3.zero;
- Vector3 pointTwo = Vector3.zero;
- for (pointsStart = 0; pointsStart < pointsUp.Count; pointsStart = Mathf.Clamp(pointsStart + pointsCount - 1, 0, pointsUp.Count))
- {
- int end = Mathf.Min(pointsStart + pointsCount, pointsUp.Count);
- //int currentCount = Mathf.Min(pointsCount, pointsUp.Count - pointsStart);
- transformPointUp.Clear();
- transformPointDown.Clear();
- for (int i = pointsStart; i < end; i++)
- {
- transformPointUp.Add(transform.TransformPoint(pointsUp[i]));
- transformPointDown.Add(transform.TransformPoint(pointsDown[i]));
- }
- minX = float.MaxValue;
- maxX = float.MinValue;
- minZ = float.MaxValue;
- maxZ = float.MinValue;
- for (int i = 0; i < transformPointUp.Count; i++)
- {
- Vector3 point = transformPointUp[i];
- if (minX > point.x)
- minX = point.x;
- if (maxX < point.x)
- maxX = point.x;
- if (minZ > point.z)
- minZ = point.z;
- if (maxZ < point.z)
- maxZ = point.z;
- }
- for (int i = 0; i < transformPointDown.Count; i++)
- {
- Vector3 point = transformPointDown[i];
- if (minX > point.x)
- minX = point.x;
- if (maxX < point.x)
- maxX = point.x;
- if (minZ > point.z)
- minZ = point.z;
- if (maxZ < point.z)
- maxZ = point.z;
- }
- minX -= terrain.transform.position.x + distSmooth;
- maxX -= terrain.transform.position.x - distSmooth;
- minZ -= terrain.transform.position.z + distSmooth;
- maxZ -= terrain.transform.position.z - distSmooth;
- minX = minX * terrainToheight;
- maxX = maxX * terrainToheight;
- minZ = minZ * terrainTowidth;
- maxZ = maxZ * terrainTowidth;
- maxX = Mathf.Ceil(Mathf.Clamp(maxX + 1, 0, (terrainData.heightmapResolution)));
- minZ = Mathf.Floor(Mathf.Clamp(minZ, 0, (terrainData.heightmapResolution)));
- maxZ = Mathf.Ceil(Mathf.Clamp(maxZ + 1, 0, (terrainData.heightmapResolution)));
- minX = Mathf.Floor(Mathf.Clamp(minX, 0, (terrainData.heightmapResolution)));
- float[,] heightmapData = terrainData.GetHeights((int)minX, (int)minZ, (int)(maxX - minX), (int)(maxZ - minZ));
- Vector3 position = Vector3.zero;
- Vector3 pointMin = Vector3.zero;
- for (int x = 0; x < heightmapData.GetLength(0); x++)
- {
- for (int z = 0; z < heightmapData.GetLength(1); z++)
- {
- position.x = (z + minX) / (float)terrainToheight + terrain.transform.position.x;
- position.z = (x + minZ) / (float)terrainTowidth + terrain.transform.position.z;
- Ray ray = new Ray(position + Vector3.up * 3000, Vector3.down);
- RaycastHit hit;
- if (meshCollider.Raycast(ray, out hit, 10000))
- {
- float height = hit.point.y - posY;
- heightmapData[x, z] = height / (float)sizeY;
- if (debugLines)
- {
- Debug.DrawLine(hit.point, hit.point + Vector3.up * 0.5f, Color.magenta, 10);
- }
- }
- }
- }
- terrainData.SetHeights((int)minX, (int)minZ, heightmapData);
- }
- DestroyImmediate(meshCollider);
- terrain.Flush();
- }
- Physics.autoSyncTransforms = true;
- if (meshGO != null)
- DestroyImmediate(meshGO);
- }
- public void TerrainPaintMeshBased()
- {
- Physics.autoSyncTransforms = false;
- foreach (Terrain terrain in Terrain.activeTerrains)
- {
- TerrainData terrainData = terrain.terrainData;
- float sizeX = terrain.terrainData.size.x;
- float sizeY = terrain.terrainData.size.y;
- float sizeZ = terrain.terrainData.size.z;
- float terrainTowidth = (1 / (float)sizeZ * (terrainData.alphamapWidth - 1));
- float terrainToheight = (1 / (float)sizeX * (terrainData.alphamapHeight - 1));
- #if UNITY_EDITOR
- Undo.RegisterCompleteObjectUndo(terrainData, "Paint river");
- Undo.RegisterCompleteObjectUndo(terrain, "Terrain draw texture");
- Undo.RegisterCompleteObjectUndo(terrainData.alphamapTextures, "alpha");
- #endif
- float minX;
- float maxX;
- float minZ;
- float maxZ;
- MeshCollider meshCollider = meshGO.gameObject.AddComponent<MeshCollider>();
- List<Vector3> transformPointUp = new List<Vector3>();
- List<Vector3> transformPointDown = new List<Vector3>();
- int pointsCount = 5;
- int pointsStart = 0;//pointsUp.Count
- //List<Vector2> done = new List<Vector2>();
- //List<Vector3> positionArray = new List<Vector3>();
- Vector3 pointOne = Vector3.zero;
- Vector3 pointTwo = Vector3.zero;
- for (pointsStart = 0; pointsStart < pointsUp.Count; pointsStart = Mathf.Clamp(pointsStart + pointsCount - 1, 0, pointsUp.Count))
- {
- int end = Mathf.Min(pointsStart + pointsCount, pointsUp.Count);
- //int currentCount = Mathf.Min(pointsCount, pointsUp.Count - pointsStart);
- transformPointUp.Clear();
- transformPointDown.Clear();
- for (int i = pointsStart; i < end; i++)
- {
- transformPointUp.Add(transform.TransformPoint(pointsUp[i]));
- transformPointDown.Add(transform.TransformPoint(pointsDown[i]));
- }
- minX = float.MaxValue;
- maxX = float.MinValue;
- minZ = float.MaxValue;
- maxZ = float.MinValue;
- for (int i = 0; i < transformPointUp.Count; i++)
- {
- Vector3 point = transformPointUp[i];
- if (minX > point.x)
- minX = point.x;
- if (maxX < point.x)
- maxX = point.x;
- if (minZ > point.z)
- minZ = point.z;
- if (maxZ < point.z)
- maxZ = point.z;
- }
- for (int i = 0; i < transformPointDown.Count; i++)
- {
- Vector3 point = transformPointDown[i];
- if (minX > point.x)
- minX = point.x;
- if (maxX < point.x)
- maxX = point.x;
- if (minZ > point.z)
- minZ = point.z;
- if (maxZ < point.z)
- maxZ = point.z;
- }
- minX -= terrain.transform.position.x + distSmooth;
- maxX -= terrain.transform.position.x - distSmooth;
- minZ -= terrain.transform.position.z + distSmooth;
- maxZ -= terrain.transform.position.z - distSmooth;
- minX = minX * terrainToheight;
- maxX = maxX * terrainToheight;
- minZ = minZ * terrainTowidth;
- maxZ = maxZ * terrainTowidth;
- minX = Mathf.Floor(Mathf.Clamp(minX, 0, (terrainData.alphamapWidth)));
- maxX = Mathf.Ceil(Mathf.Clamp(maxX + 1, 0, (terrainData.alphamapWidth)));
- minZ = Mathf.Floor(Mathf.Clamp(minZ, 0, (terrainData.alphamapHeight)));
- maxZ = Mathf.Ceil(Mathf.Clamp(maxZ + 1, 0, (terrainData.alphamapHeight)));
- float[,,] alphamapData = terrainData.GetAlphamaps((int)minX, (int)minZ, (int)(maxX - minX), (int)(maxZ - minZ));
- Vector3 position = Vector3.zero;
- Vector3 pointMin = Vector3.zero;
- float noise = 0;
- for (int x = 0; x < alphamapData.GetLength(0); x++)
- {
- for (int z = 0; z < alphamapData.GetLength(1); z++)
- {
- position.x = (z + minX) / (float)terrainToheight + terrain.transform.position.x;
- position.z = (x + minZ) / (float)terrainTowidth + terrain.transform.position.z;
- Ray ray = new Ray(position + Vector3.up * 3000, Vector3.down);
- RaycastHit hit;
- if (meshCollider.Raycast(ray, out hit, 10000))
- {
- float minDist = hit.textureCoord.x;
- if (!mixTwoSplatMaps)
- {
- if (noisePaint)
- {
- if (minDist >= 0)
- noise = Mathf.PerlinNoise(hit.point.x * noiseSizeXPaint, hit.point.z * noiseSizeZPaint) * noiseMultiplierInsidePaint - noiseMultiplierInsidePaint * 0.5f;
- else
- noise = Mathf.PerlinNoise(hit.point.x * noiseSizeXPaint, hit.point.z * noiseSizeZPaint) * noiseMultiplierOutsidePaint - noiseMultiplierOutsidePaint * 0.5f;
- }
- else
- noise = 0;
- float oldValue = alphamapData[x, z, currentSplatMap];
- alphamapData[x, z, currentSplatMap] = Mathf.Clamp01(Mathf.Lerp(alphamapData[x, z, currentSplatMap], 1, terrainPaintCarve.Evaluate(minDist) + terrainPaintCarve.Evaluate(minDist) * noise));
- for (int l = 0; l < terrainData.terrainLayers.Length; l++)
- {
- if (l != currentSplatMap)
- {
- alphamapData[x, z, l] = oldValue == 1 ? 0 : Mathf.Clamp01(alphamapData[x, z, l] * ((1 - alphamapData[x, z, currentSplatMap]) / (1 - oldValue)));
- }
- }
- }
- else
- {
- if (minDist >= 0)
- noise = Mathf.PerlinNoise(hit.point.x * noiseSizeXPaint, hit.point.z * noiseSizeZPaint) * noiseMultiplierInsidePaint - noiseMultiplierInsidePaint * 0.5f;
- else
- noise = Mathf.PerlinNoise(hit.point.x * noiseSizeXPaint, hit.point.z * noiseSizeZPaint) * noiseMultiplierOutsidePaint - noiseMultiplierOutsidePaint * 0.5f;
- float oldValue = alphamapData[x, z, currentSplatMap];
- alphamapData[x, z, currentSplatMap] = Mathf.Clamp01(Mathf.Lerp(alphamapData[x, z, currentSplatMap], 1, terrainPaintCarve.Evaluate(minDist)));
- for (int l = 0; l < terrainData.terrainLayers.Length; l++)
- {
- if (l != currentSplatMap)
- {
- alphamapData[x, z, l] = oldValue == 1 ? 0 : Mathf.Clamp01(alphamapData[x, z, l] * ((1 - alphamapData[x, z, currentSplatMap]) / (1 - oldValue)));
- }
- }
- if (noise > 0)
- {
- oldValue = alphamapData[x, z, secondSplatMap];
- alphamapData[x, z, secondSplatMap] = Mathf.Clamp01(Mathf.Lerp(alphamapData[x, z, secondSplatMap], 1, noise));
- for (int l = 0; l < terrainData.terrainLayers.Length; l++)
- {
- if (l != secondSplatMap)
- {
- alphamapData[x, z, l] = oldValue == 1 ? 0 : Mathf.Clamp01(alphamapData[x, z, l] * ((1 - alphamapData[x, z, secondSplatMap]) / (1 - oldValue)));
- }
- }
- }
- }
- if (addCliffSplatMap)
- {
- if (minDist >= 0)
- {
- float angle = Vector3.Angle(hit.normal, Vector3.up);
- if (angle > cliffAngle)
- {
- float oldValue = alphamapData[x, z, cliffSplatMap];
- alphamapData[x, z, cliffSplatMap] = cliffBlend;
- for (int l = 0; l < terrainData.terrainLayers.Length; l++)
- {
- if (l != cliffSplatMap)
- {
- alphamapData[x, z, l] = oldValue == 1 ? 0 : Mathf.Clamp01(alphamapData[x, z, l] * ((1 - alphamapData[x, z, cliffSplatMap]) / (1 - oldValue)));
- }
- }
- }
- }
- else
- {
- float angle = Vector3.Angle(hit.normal, Vector3.up);
- if (angle > cliffAngleOutside)
- {
- float oldValue = alphamapData[x, z, cliffSplatMapOutside];
- alphamapData[x, z, cliffSplatMapOutside] = cliffBlendOutside;
- for (int l = 0; l < terrainData.terrainLayers.Length; l++)
- {
- if (l != cliffSplatMapOutside)
- {
- alphamapData[x, z, l] = oldValue == 1 ? 0 : Mathf.Clamp01(alphamapData[x, z, l] * ((1 - alphamapData[x, z, cliffSplatMapOutside]) / (1 - oldValue)));
- }
- }
- }
- }
- }
- }
- }
- }
- terrainData.SetAlphamaps((int)minX, (int)minZ, alphamapData);
- }
- DestroyImmediate(meshCollider);
- terrain.Flush();
- }
- Physics.autoSyncTransforms = true;
- if (meshGO != null)
- DestroyImmediate(meshGO);
- }
- public void TerrainClearFoliage(bool details = true)
- {
- Physics.autoSyncTransforms = false;
- foreach (Terrain terrain in Terrain.activeTerrains)
- {
- TerrainData terrainData = terrain.terrainData;
- Transform transformTerrain = terrain.transform;
- float posY = terrain.transform.position.y;
- float sizeX = terrain.terrainData.size.x;
- float sizeY = terrain.terrainData.size.y;
- float sizeZ = terrain.terrainData.size.z;
- float terrainTowidth = (1 / (float)sizeX * (terrainData.detailWidth - 1));
- float terrainToheight = (1 / (float)sizeZ * (terrainData.detailHeight - 1));
- #if UNITY_EDITOR
- Undo.RegisterCompleteObjectUndo(terrainData, "Paint river");
- Undo.RegisterCompleteObjectUndo(terrain, "Terrain draw texture");
- #endif
- float minX;
- float maxX;
- float minZ;
- float maxZ;
- MeshCollider meshCollider = meshGO.gameObject.AddComponent<MeshCollider>();
- List<Vector3> transformPointUp = new List<Vector3>();
- List<Vector3> transformPointDown = new List<Vector3>();
- int pointsCount = 5;
- int pointsStart = 0;//pointsUp.Count
- //List<Vector2> done = new List<Vector2>();
- //List<Vector3> positionArray = new List<Vector3>();
- Vector3 pointOne = Vector3.zero;
- Vector3 pointTwo = Vector3.zero;
- Vector3 position = Vector3.zero;
- if (details)
- {
- for (pointsStart = 0; pointsStart < pointsUp.Count; pointsStart = Mathf.Clamp(pointsStart + pointsCount - 1, 0, pointsUp.Count))
- {
- int end = Mathf.Min(pointsStart + pointsCount, pointsUp.Count);
- //int currentCount = Mathf.Min(pointsCount, pointsUp.Count - pointsStart);
- transformPointUp.Clear();
- transformPointDown.Clear();
- for (int i = pointsStart; i < end; i++)
- {
- transformPointUp.Add(transform.TransformPoint(pointsUp[i]));
- transformPointDown.Add(transform.TransformPoint(pointsDown[i]));
- }
- minX = float.MaxValue;
- maxX = float.MinValue;
- minZ = float.MaxValue;
- maxZ = float.MinValue;
- for (int i = 0; i < transformPointUp.Count; i++)
- {
- Vector3 point = transformPointUp[i];
- if (minX > point.x)
- minX = point.x;
- if (maxX < point.x)
- maxX = point.x;
- if (minZ > point.z)
- minZ = point.z;
- if (maxZ < point.z)
- maxZ = point.z;
- }
- for (int i = 0; i < transformPointDown.Count; i++)
- {
- Vector3 point = transformPointDown[i];
- if (minX > point.x)
- minX = point.x;
- if (maxX < point.x)
- maxX = point.x;
- if (minZ > point.z)
- minZ = point.z;
- if (maxZ < point.z)
- maxZ = point.z;
- }
- minX -= terrain.transform.position.x + distSmooth;
- maxX -= terrain.transform.position.x - distSmooth;
- minZ -= terrain.transform.position.z + distSmooth;
- maxZ -= terrain.transform.position.z - distSmooth;
- minX = minX * terrainToheight;
- maxX = maxX * terrainToheight;
- minZ = minZ * terrainTowidth;
- maxZ = maxZ * terrainTowidth;
- minX = Mathf.Floor(Mathf.Clamp(minX, 0, (terrainData.alphamapWidth)));
- maxX = Mathf.Ceil(Mathf.Clamp(maxX + 1, 0, (terrainData.alphamapWidth)));
- minZ = Mathf.Floor(Mathf.Clamp(minZ, 0, (terrainData.alphamapHeight)));
- maxZ = Mathf.Ceil(Mathf.Clamp(maxZ + 1, 0, (terrainData.alphamapHeight)));
- int[,] detailLayer;// = terrainData.GetAlphamaps((int)minX, (int)minZ, (int)(maxX - minX), (int)(maxZ - minZ));
- for (int l = 0; l < terrainData.detailPrototypes.Length; l++)
- {
- detailLayer = terrainData.GetDetailLayer((int)minX, (int)minZ, (int)(maxX - minX), (int)(maxZ - minZ), l);
- for (int x = 0; x < detailLayer.GetLength(0); x++)
- {
- for (int z = 0; z < detailLayer.GetLength(1); z++)
- {
- position.x = (z + minX) / (float)terrainToheight + terrain.transform.position.x;
- position.z = (x + minZ) / (float)terrainTowidth + terrain.transform.position.z;
- Ray ray = new Ray(position + Vector3.up * 3000, Vector3.down);
- RaycastHit hit;
- if (meshCollider.Raycast(ray, out hit, 10000))
- {
- detailLayer[x, z] = 0;
- }
- }
- }
- terrainData.SetDetailLayer((int)minX, (int)minZ, l, detailLayer);
- }
- }
- }
- else
- {
- List<TreeInstance> newTrees = new List<TreeInstance>();
- TreeInstance[] oldTrees = terrainData.treeInstances;
- foreach (var tree in oldTrees)
- {
- //Debug.DrawRay(new Vector3(, 0, tree.position.z * sizeZ) + terrain.transform.position, Vector3.up * 5, Color.red, 3);
- position.x = tree.position.x * sizeX + transformTerrain.position.x;//, polygonHeight
- position.z = tree.position.z * sizeZ + transformTerrain.position.z;
- Ray ray = new Ray(position + Vector3.up * 3000, Vector3.down);
- RaycastHit hit;
- if (!meshCollider.Raycast(ray, out hit, 10000))
- {
- newTrees.Add(tree);
- }
- }
- terrainData.treeInstances = newTrees.ToArray();
- }
- DestroyImmediate(meshCollider);
- terrain.Flush();
- }
- Physics.autoSyncTransforms = true;
- if (meshGO != null)
- DestroyImmediate(meshGO);
- }
- #endregion
- float FlowCalculate(float u, float normalY, Vector3 vertice)
- {
- float noise = (noiseflowMap ? Mathf.PerlinNoise(vertice.x * noiseSizeXflowMap, vertice.z * noiseSizeZflowMap) * noiseMultiplierflowMap - noiseMultiplierflowMap * 0.5f : 0) * Mathf.Pow(Mathf.Clamp(normalY, 0, 1), 5);
- return Mathf.Lerp(flowWaterfall.Evaluate(u), flowFlat.Evaluate(u) + noise, Mathf.Clamp(normalY, 0, 1));
- }
- }
|