//Si no encontramos muro en el paso anterior, entonces buscamos si tenemos suelo. tiramos el rayo y si da positivo, añadimos punto, calculamos growdirection y decimos al sistema que no estamos cayendo. Si por el contrario no //hemos encontrado suelo, intenamos agarrarnos al otro lado de la posible esquina. void CheckFloor(BranchContainer branch, BranchPoint potentialPoint, Vector3 oldSurfaceNormal) { Ray ray = new Ray(potentialPoint.point, -oldSurfaceNormal); RaycastHit RC; if (Physics.Raycast(ray, out RC, branch.currentHeight * 2f, infoPool.ivyParameters.layerMask.value)) { AddPoint(branch, RC.point, RC.normal); NewGrowDirection(branch); branch.fallIteration = 0f; branch.falling = false; } else { if (Random.value < infoPool.ivyParameters.grabProvabilityOnFall) { CheckCorner(branch, potentialPoint, oldSurfaceNormal); } else { AddFallingPoint(branch); branch.fallIteration += 1f - infoPool.ivyParameters.stiffness; branch.falling = true; branch.currentHeight = 0f; branch.heightParameter = -45f; } } }
//Todo lo necesario para añadir una rama public void AddBranch(BranchContainer branch, BranchPoint originBranchPoint, Vector3 point, Vector3 normal) { BranchContainer newBranchContainer = ScriptableObject.CreateInstance <BranchContainer>(); newBranchContainer.Init(); newBranchContainer.AddBranchPoint(point, -normal); //newBranchContainer.grabVectors.Add (-normal); newBranchContainer.growDirection = Vector3.Normalize(Vector3.ProjectOnPlane(branch.growDirection, normal)); newBranchContainer.randomizeHeight = Random.Range(4f, 8f); newBranchContainer.currentHeight = branch.currentHeight; newBranchContainer.heightParameter = branch.heightParameter; newBranchContainer.branchSense = ChooseBranchSense(); newBranchContainer.originPointOfThisBranch = originBranchPoint; //newBranchContainer.branchNumber = infoPool.ivyContainer.branches.Count; //Undo.RegisterCompleteObjectUndo(infoPool.ivyContainer, "Create new branch"); //EditorUtility.SetDirty(infoPool.ivyContainer); //infoPool.ivyContainer.branches.Add(newBranchContainer); infoPool.ivyContainer.AddBranch(newBranchContainer); originBranchPoint.InitBranchInThisPoint(newBranchContainer.branchNumber); }
public void AddBranch(BranchContainer newBranchContainer) { newBranchContainer.branchNumber = lastNumberAssigned; lastNumberAssigned++; branches.Add(newBranchContainer); }
//Cálculos de nuevas growdirection en diferentes casuísticas void NewGrowDirection(BranchContainer branch) { branch.growDirection = Vector3.Normalize(Vector3.ProjectOnPlane(Quaternion.AngleAxis(Mathf.Sin(branch.branchSense * branch.totalLenght * infoPool.ivyParameters.directionFrequency * (1 + Random.Range(-infoPool.ivyParameters.directionRandomness, infoPool.ivyParameters.directionRandomness))) * infoPool.ivyParameters.directionAmplitude * infoPool.ivyParameters.stepSize * 10f * Mathf.Max(infoPool.ivyParameters.directionRandomness, 1f), branch.GetLastBranchPoint().grabVector) * branch.growDirection, branch.GetLastBranchPoint().grabVector)); }
//Este se usa si estamos en una caída. Está la probabilidad de buscar una superficie donde agarrarnos (checkgrabpoint). Si topamos con una superficie se añade punto y se dice al sistema que no estamos cayendo void CheckFall(BranchContainer branch) { Ray ray = new Ray(branch.branchPoints[branch.branchPoints.Count - 1].point, branch.growDirection); RaycastHit RC; if (!Physics.Raycast(ray, out RC, infoPool.ivyParameters.stepSize * 1.15f, infoPool.ivyParameters.layerMask.value)) { if (Random.value < infoPool.ivyParameters.grabProvabilityOnFall) { CheckGrabPoint(branch); } else { NewGrowDirectionFalling(branch); AddFallingPoint(branch); branch.fallIteration += 1f - infoPool.ivyParameters.stiffness; branch.falling = true; } } else { NewGrowDirectionAfterFall(branch, RC.normal); AddPoint(branch, RC.point, RC.normal); branch.fallIteration = 0f; branch.falling = false; } }
public void RemoveBranch(BranchContainer branchToDelete) { if (branchToDelete.originPointOfThisBranch != null) { branchToDelete.originPointOfThisBranch.branchContainer.ReleasePoint(branchToDelete.originPointOfThisBranch.index); //branchToDelete.originPointOfThisBranch.ReleasePoint(); } branches.Remove(branchToDelete); }
float CalculateRadius(BranchPoint branchPoint, BranchContainer buildingBranchContainer) { float tipInfluenceFactor = Mathf.InverseLerp(branchPoint.branchContainer.totalLenght, branchPoint.branchContainer.totalLenght - ivyParameters.tipInfluence, branchPoint.length - 0.1f); branchPoint.currentRadius = branchPoint.radius * tipInfluenceFactor; float radius = branchPoint.currentRadius; return(radius); }
private float CalculateLeafScale(BranchContainer branch, LeafPoint leafPoint) { //Aquí la escala, que es facilita, incluyendo el tip influence float scale = Random.Range(ivyParameters.minScale, ivyParameters.maxScale); if (leafPoint.lpLength - 0.1f >= branch.totalLenght - ivyParameters.tipInfluence) { scale *= Mathf.InverseLerp(branch.totalLenght, branch.totalLenght - ivyParameters.tipInfluence, leafPoint.lpLength); } return(scale); }
//Este método es para calcular la altura del próximo punto void CalculateNewHeight(BranchContainer branch) { branch.heightVar = (Mathf.Sin(branch.heightParameter * infoPool.ivyParameters.DTSFrequency - 45f) + 1f) / 2f; branch.newHeight = Mathf.Lerp(infoPool.ivyParameters.minDistanceToSurface, infoPool.ivyParameters.maxDistanceToSurface, branch.heightVar); branch.newHeight += (Mathf.Sin(branch.heightParameter * infoPool.ivyParameters.DTSFrequency * branch.randomizeHeight) + 1) / 2f * infoPool.ivyParameters.maxDistanceToSurface / 4f * infoPool.ivyParameters.DTSRandomness; branch.newHeight = Mathf.Clamp(branch.newHeight, infoPool.ivyParameters.minDistanceToSurface, infoPool.ivyParameters.maxDistanceToSurface); branch.deltaHeight = branch.currentHeight - branch.newHeight; branch.currentHeight = branch.newHeight; }
//Si la rama no está cayendo (está agarrada a una superficie) calculamos la nueva altura del próximo punto y buscamos un muro delante. Si está cayendo, buscamos el próximo punto de la caída. void CalculateNewPoint(BranchContainer branch) { if (!branch.falling) { CalculateNewHeight(branch); CheckWall(branch); } else { CheckFall(branch); } }
public BranchContainer GetBranchContainerByBranchNumber(int branchNumber) { BranchContainer res = null; for (int i = 0; i < branches.Count; i++) { if (branches[i].branchNumber == branchNumber) { res = branches[i]; break; } } return(res); }
void NewGrowDirectionFalling(BranchContainer branch) { Vector3 newGrowDirection = Vector3.Lerp(branch.growDirection, infoPool.ivyParameters.gravity, branch.fallIteration / 10f); newGrowDirection = Quaternion.AngleAxis(Mathf.Sin(branch.branchSense * branch.totalLenght * infoPool.ivyParameters.directionFrequency * (1 + Random.Range(-infoPool.ivyParameters.directionRandomness / 8f, infoPool.ivyParameters.directionRandomness / 8f))) * infoPool.ivyParameters.directionAmplitude * infoPool.ivyParameters.stepSize * 5f * Mathf.Max(infoPool.ivyParameters.directionRandomness / 8f, 1f), branch.GetLastBranchPoint().grabVector) * newGrowDirection; newGrowDirection = Quaternion.AngleAxis(Mathf.Sin(branch.branchSense * branch.totalLenght * infoPool.ivyParameters.directionFrequency / 2f * (1 + Random.Range(-infoPool.ivyParameters.directionRandomness / 8f, infoPool.ivyParameters.directionRandomness / 8f))) * infoPool.ivyParameters.directionAmplitude * infoPool.ivyParameters.stepSize * 5f * Mathf.Max(infoPool.ivyParameters.directionRandomness / 8f, 1f), Vector3.Cross(branch.GetLastBranchPoint().grabVector, branch.growDirection)) * newGrowDirection; branch.rotationOnFallIteration = Quaternion.FromToRotation(branch.growDirection, newGrowDirection); branch.growDirection = newGrowDirection; }
//Añadimos punto y todo lo que ello conlleva. Es ligeramente diferente a AddPoint. Está la posibilidad de spawnear una rama void AddFallingPoint(BranchContainer branch) { Vector3 grabVector = branch.rotationOnFallIteration * branch.GetLastBranchPoint().grabVector; branch.totalLenght += infoPool.ivyParameters.stepSize; branch.AddBranchPoint(branch.branchPoints[branch.branchPoints.Count - 1].point + branch.growDirection * infoPool.ivyParameters.stepSize, grabVector); if (Random.value < infoPool.ivyParameters.branchProvability && infoPool.ivyContainer.branches.Count < infoPool.ivyParameters.maxBranchs) { AddBranch(branch, branch.GetLastBranchPoint(), branch.branchPoints[branch.branchPoints.Count - 1].point, -branch.GetLastBranchPoint().grabVector); } AddLeave(branch); }
private void CheckOrphanBranches(List <BranchPoint> pointsToCheck) { for (int i = 0; i < pointsToCheck.Count; i++) { if (pointsToCheck[i].newBranch && pointsToCheck[i].newBranchNumber != overBranch.branchNumber) { BranchContainer orphanBranch = infoPool.ivyContainer.GetBranchContainerByBranchNumber(pointsToCheck[i].newBranchNumber); if (orphanBranch != null) { branchesToRemove.Add(orphanBranch); DrawPoints(orphanBranch.branchPoints, Color.blue); CheckOrphanBranches(orphanBranch.branchPoints); } } } }
public void SelectBranchPointSS(Vector2 mousePosition, float brushSize) { float minDistance = brushSize; overBranch = null; overPoint = null; BranchPoint[] nearestSegment = infoPool.ivyContainer.GetNearestSegmentSSBelowDistance(mousePosition, minDistance); if (nearestSegment != null) { overBranch = nearestSegment[0].branchContainer; overPoint = GetNearestBranchPointBySegment(mousePosition, nearestSegment, brushSize * 0.5f); overSegment = nearestSegment; } }
/*public void AddDrawingPoint(BranchContainer branch, Vector3 point, Vector3 normal, Vector3 paintDir) * { * //Vector3 dir = branch.branchPoints[branch.branchPoints.Count - 1].point - branch.branchPoints[branch.branchPoints.Count - 2].point; * //dir = dir.normalized; * * branch.AddBranchPoint(point + normal * branch.currentHeight, -normal); * * * branch.totalLenght += infoPool.ivyParameters.stepSize; * * branch.GetLastBranchPoint().length = branch.totalLenght; * branch.lenghts.Add(branch.totalLenght); * * AddLeave(branch); * }*/ //Añadimos punto y todo lo que ello conlleva. Está la posibilidad de spawnear una rama public void AddPoint(BranchContainer branch, Vector3 point, Vector3 normal) { branch.totalLenght += infoPool.ivyParameters.stepSize; branch.heightParameter += infoPool.ivyParameters.stepSize; branch.AddBranchPoint(point + normal * branch.currentHeight, -normal); //Con este if lo que comprobamos realmente es si estamos en modo procedural o en modo pintado if (growing) { if (Random.value < infoPool.ivyParameters.branchProvability && infoPool.ivyContainer.branches.Count < infoPool.ivyParameters.maxBranchs) { AddBranch(branch, branch.GetLastBranchPoint(), branch.branchPoints[branch.branchPoints.Count - 1].point, normal); } } AddLeave(branch); }
public void Optimize() { for (int b = 0; b < infoPool.ivyContainer.branches.Count; b++) { BranchContainer branch = infoPool.ivyContainer.branches[b]; for (int p = 1; p < branch.branchPoints.Count - 1; p++) { Vector3 segment1 = branch.branchPoints[p].point - branch.branchPoints[p - 1].point; Vector3 segment2 = branch.branchPoints[p + 1].point - branch.branchPoints[p].point; if (Vector3.Angle(segment1, segment2) < infoPool.ivyParameters.optAngleBias) { SaveIvy(); branch.RemoveBranchPoint(p); RefreshMesh(); } } } }
//Creamos las estructuras de info para las ramas y asignamos las variables iniciales de la primera rama public void Initialize(Vector3 firstPoint, Vector3 firstGrabVector) { Random.InitState(infoPool.ivyParameters.randomSeed); BranchContainer newBranchContainer = ScriptableObject.CreateInstance <BranchContainer>(); newBranchContainer.Init(); newBranchContainer.currentHeight = infoPool.ivyParameters.minDistanceToSurface; infoPool.ivyContainer.AddBranch(newBranchContainer); infoPool.ivyContainer.branches[0].AddBranchPoint(firstPoint, firstGrabVector, true, newBranchContainer.branchNumber); infoPool.ivyContainer.branches [0].growDirection = Quaternion.AngleAxis(Random.value * 360f, infoPool.ivyContainer.ivyGO.transform.up) * infoPool.ivyContainer.ivyGO.transform.forward; infoPool.ivyContainer.firstVertexVector = infoPool.ivyContainer.branches [0].growDirection; infoPool.ivyContainer.branches [0].randomizeHeight = Random.Range(4f, 8f); CalculateNewHeight(infoPool.ivyContainer.branches [0]); infoPool.ivyContainer.branches [0].branchSense = ChooseBranchSense(); randomstate = Random.state; }
public void GetBranchesPointsSS() { //Iteramos las ramas for (int i = 0; i < infoPool.ivyContainer.branches.Count; i++) { BranchContainer currentBranch = infoPool.ivyContainer.branches[i]; //Iteramos los puntos de las ramas, calculamos su screen space y lo almacenamos en el propio punto for (int j = 0; j < currentBranch.branchPoints.Count; j++) { BranchPoint currentBranchPoint = currentBranch.branchPoints[j]; currentBranchPoint.CalculatePointSS(); } if (currentBranch.originPointOfThisBranch != null) { currentBranch.originPointOfThisBranch.CalculatePointSS(); } } }
//Si hábíamos perdido pie, comprobamos si estamos en una esquina e intentamos seguir por el otro lado de lamisma void CheckCorner(BranchContainer branch, BranchPoint potentialPoint, Vector3 oldSurfaceNormal) { Ray ray = new Ray(potentialPoint.point + branch.branchPoints[branch.branchPoints.Count - 1].grabVector * 2f * branch.currentHeight, -branch.growDirection); RaycastHit RC; if (Physics.Raycast(ray, out RC, infoPool.ivyParameters.stepSize * 1.15f, infoPool.ivyParameters.layerMask.value)) { AddPoint(branch, potentialPoint.point, oldSurfaceNormal); AddPoint(branch, RC.point, RC.normal); NewGrowDirectionAfterCorner(branch, oldSurfaceNormal, RC.normal); } else { AddFallingPoint(branch); branch.fallIteration += 1f - infoPool.ivyParameters.stiffness; branch.falling = true; branch.currentHeight = 0f; branch.heightParameter = -45f; } }
//Todo lo necesario para añadir una nueva hoja void AddLeave(BranchContainer branch) { if (branch.branchPoints.Count % (infoPool.ivyParameters.leaveEvery + Random.Range(0, infoPool.ivyParameters.randomLeaveEvery)) == 0) { /*BORRAR*/ //branch.branchPoints[branch.branchPoints.Count - 1].AddCurrentPointAsLeafPoint(); //branch.branchPoints[branch.branchPoints.Count - 1].AddLPLength(branch.totalLenght); //branch.branchPoints[branch.branchPoints.Count - 1].AddLPForward(branch.growDirection); //branch.branchPoints[branch.branchPoints.Count - 1].AddLPUpward(-branch.grabVectors[branch.grabVectors.Count - 1]); float[] probabilities = new float[infoPool.ivyParameters.leavesPrefabs.Length]; int chosenLeave = 0; float max = 0f; for (int i = 0; i < probabilities.Length; i++) { probabilities [i] = Random.Range(0f, infoPool.ivyParameters.leavesProb [i]); } for (int i = 0; i < probabilities.Length; i++) { if (probabilities [i] >= max) { max = probabilities [i]; chosenLeave = i; } } /*BORRAR*/ //branch.branchPoints[branch.branchPoints.Count - 1].AddLPType(chosenLeave); BranchPoint initSegment = branch.branchPoints[branch.branchPoints.Count - 2]; BranchPoint endSegment = branch.branchPoints[branch.branchPoints.Count - 1]; Vector3 leafPoint = Vector3.Lerp(initSegment.point, endSegment.point, 0.5f); branch.AddLeaf(leafPoint, branch.totalLenght, branch.growDirection, -branch.GetLastBranchPoint().grabVector, chosenLeave, initSegment, endSegment); } }
public void SetValues(Vector3 point, Vector3 grabVector, Vector2 pointSS, BranchContainer branchContainer, int index, bool blocked, bool newBranch, int newBranchNumber, float length) { this.point = point; this.grabVector = grabVector; this.pointSS = pointSS; this.branchContainer = branchContainer; this.index = index; this.newBranch = newBranch; this.newBranchNumber = newBranchNumber; this.radius = 1f; this.currentRadius = 1f; this.length = length; this.initialGrowDir = Vector3.zero; if (index >= 1) { this.initialGrowDir = (point - branchContainer.branchPoints[index - 1].point).normalized; } }
//Definimos el punto a checkear y la dirección a él. Tiramos un raycast y si está libre buscamos el suelo. Si por el contrario topamos con un muro, añadimos un punto y calculamos una nueva growdirection void CheckWall(BranchContainer branch) { BranchPoint checkPoint = new BranchPoint( branch.GetLastBranchPoint().point + branch.growDirection * infoPool.ivyParameters.stepSize + branch.GetLastBranchPoint().grabVector *branch.deltaHeight, branch.branchPoints.Count, 0f, branch); Vector3 direction = checkPoint.point - branch.GetLastBranchPoint().point; Ray ray = new Ray(branch.branchPoints[branch.branchPoints.Count - 1].point, direction); RaycastHit RC; if (!Physics.Raycast(ray, out RC, infoPool.ivyParameters.stepSize * 1.15f, infoPool.ivyParameters.layerMask.value)) { CheckFloor(branch, checkPoint, -branch.GetLastBranchPoint().grabVector); } else { NewGrowDirectionAfterWall(branch, -branch.GetLastBranchPoint().grabVector, RC.normal); AddPoint(branch, RC.point, RC.normal); } }
//Con esto tiramos rayos alrededor del último punto buscando una superficie donde agarrarnos. void CheckGrabPoint(BranchContainer branch) { for (int i = 0; i < 6; i++) { float angle = (Mathf.Rad2Deg * 2 * Mathf.PI / 6) * i; Ray ray = new Ray(branch.branchPoints [branch.branchPoints.Count - 1].point + branch.growDirection * infoPool.ivyParameters.stepSize, Quaternion.AngleAxis(angle, branch.growDirection) * branch.GetLastBranchPoint().grabVector); RaycastHit RC; if (Physics.Raycast(ray, out RC, infoPool.ivyParameters.stepSize * 2f, infoPool.ivyParameters.layerMask.value)) { AddPoint(branch, RC.point, RC.normal); NewGrowDirectionAfterGrab(branch, RC.normal); branch.fallIteration = 0f; branch.falling = false; break; } else if (i == 5) { AddFallingPoint(branch); NewGrowDirectionFalling(branch); branch.fallIteration += 1f - infoPool.ivyParameters.stiffness; branch.falling = true; } } }
//Algoritmo de refinamiento Se va ejecutando sobre la marcha, buscando angulos demasiado poco pronunciados y refinándolos o puntos demasiado juntos y eliminando puntos para evitar nudos void Refine(BranchContainer branch) { if (branch.branchPoints.Count > 3) { if (Vector3.Distance(branch.branchPoints [branch.branchPoints.Count - 2].point, branch.branchPoints [branch.branchPoints.Count - 3].point) < infoPool.ivyParameters.stepSize * 0.7f || Vector3.Distance(branch.branchPoints [branch.branchPoints.Count - 2].point, branch.branchPoints [branch.branchPoints.Count - 1].point) < infoPool.ivyParameters.stepSize * 0.7f) { branch.RemoveBranchPoint(branch.branchPoints.Count - 2); //branch.grabVectors.RemoveAt (branch.branchPoints.Count - 2); } if (Vector3.Angle(branch.branchPoints [branch.branchPoints.Count - 1].point - branch.branchPoints [branch.branchPoints.Count - 2].point, branch.branchPoints [branch.branchPoints.Count - 2].point - branch.branchPoints [branch.branchPoints.Count - 3].point) > 25f) { Vector3 last = branch.branchPoints [branch.branchPoints.Count - 1].point - branch.branchPoints [branch.branchPoints.Count - 2].point; Vector3 preLast = branch.branchPoints [branch.branchPoints.Count - 3].point - branch.branchPoints [branch.branchPoints.Count - 2].point; //BranchPoint branchPoint01 = branch.branchPoints[branch.branchPoints.Count - 2]; branch.InsertBranchPoint(branch.branchPoints[branch.branchPoints.Count - 2].point + preLast / 2f, branch.branchPoints[branch.branchPoints.Count - 2].grabVector, branch.branchPoints.Count - 2); //branch.grabVectors.Insert(branch.grabVectors.Count - 2, ,branch.grabVectors[branch.grabVectors.Count-2]); branch.InsertBranchPoint(branch.branchPoints[branch.branchPoints.Count - 2].point + last / 2f, branch.branchPoints[branch.branchPoints.Count - 2].grabVector, branch.branchPoints.Count - 1); //branch.grabVectors.Insert(branch.grabVectors.Count - 1, branch.grabVectors[branch.grabVectors.Count-2]); branch.RemoveBranchPoint(branch.branchPoints.Count - 3); //branch.grabVectors.RemoveAt (branch.branchPoints.Count - 3); } } }
public BranchPoint(Vector3 point, int index, float length, BranchContainer branchContainer) { SetValues(point, Vector3.zero, Vector3.zero, branchContainer, index, false, false, -1, length); }
public BranchPoint(Vector3 point, Vector3 grabVector, int index, bool newBranch, int newBranchNumber, float length, BranchContainer branchContainer) { SetValues(point, grabVector, Vector3.zero, branchContainer, index, false, newBranch, newBranchNumber, length); }
public void Initialize() { //Reiniciamos los triángulos de las hojas en cada iteración infoPool.meshBuilder.trisLeaves = new List <List <int> >(); for (int i = 0; i < infoPool.meshBuilder.leavesMaterials.Count; i++) { infoPool.meshBuilder.trisLeaves.Add(new List <int>()); } //Reiniciamos la malla y definimos el número de materiales ivyMesh.Clear(); if (infoPool.ivyParameters.buffer32Bits) { ivyMesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; } ivyMesh.name = "Ivy Mesh"; ivyMesh.subMeshCount = leavesMaterials.Count + 1; //Y también el diccionario usado en la creación de las uvs de lightmap branchesLeavesIndices.Clear(); //Estos contadores son para calcular cuantos huecos hacen falta en los arrays de vertices y tris int vertCount = 0; int triBranchesCount = 0; if (infoPool.ivyParameters.generateBranches) { //Contamos los verts y tris necesarios y hacemos hueco en las arrays Por este lado las ramas for (int i = 0; i < infoPool.ivyContainer.branches.Count; i++) { if (infoPool.ivyContainer.branches[i].branchPoints.Count > 1) { vertCount += (infoPool.ivyContainer.branches[i].branchPoints.Count - 1) * (infoPool.ivyParameters.sides + 1) + 1; triBranchesCount += (infoPool.ivyContainer.branches[i].branchPoints.Count - 2) * infoPool.ivyParameters.sides * 2 * 3 + infoPool.ivyParameters.sides * 3; } } } if (infoPool.ivyParameters.generateLeaves && infoPool.ivyParameters.leavesPrefabs.Length > 0) { //Y por este las hojas, dependiendo de la malla de cada prefab for (int i = 0; i < infoPool.ivyContainer.branches.Count; i++) { if (infoPool.ivyContainer.branches[i].branchPoints.Count > 1) { for (int j = 0; j < infoPool.ivyContainer.branches[i].leaves.Count; j++) { BranchContainer currentBranch = infoPool.ivyContainer.branches[i]; //BranchPoint currentBranchPoint = infoPool.ivyContainer.branches[i].branchPoints[j]; MeshFilter leafMeshFilter = infoPool.ivyParameters.leavesPrefabs[currentBranch.leaves[j].chosenLeave].GetComponent <MeshFilter>(); vertCount += leafMeshFilter.sharedMesh.vertexCount; /*for (int p = 0; p < currentBranchPoint.leaves.Count; p++) * { * vertCount += infoPool.ivyParameters.leavesPrefabs[currentBranchPoint.leaves[p].chosenLeave].GetComponent<MeshFilter>().sharedMesh.vertexCount; * }*/ } } } } //creamos las arrays para todos los datos de la malla (salvo los triángulos de las hojas que se van añadiendo al vuelo, pues son una listas) verts = new Vector3[vertCount]; normals = new Vector3[vertCount]; uvs = new Vector2[vertCount]; vColor = new Color[vertCount]; trisBranches = new int[Mathf.Max(triBranchesCount, 0)]; //Calculamos el ángulo y tal if (!infoPool.ivyParameters.halfgeom) { angle = Mathf.Rad2Deg * 2 * Mathf.PI / infoPool.ivyParameters.sides; } else { angle = Mathf.Rad2Deg * 2 * Mathf.PI / infoPool.ivyParameters.sides / 2; } }
public RTBranchContainer(BranchContainer branchContainer, IvyParameters ivyParameters, RTIvyContainer rtIvyContainer, GameObject ivyGO, RTMeshData[] leavesMeshesByChosenLeaf) { this.totalLength = branchContainer.totalLenght; this.growDirection = branchContainer.growDirection; this.randomizeHeight = branchContainer.randomizeHeight; this.heightVar = branchContainer.heightVar; this.newHeight = branchContainer.newHeight; this.heightParameter = branchContainer.heightParameter; this.deltaHeight = branchContainer.deltaHeight; this.currentHeight = branchContainer.currentHeight; this.branchSense = branchContainer.branchSense; this.falling = branchContainer.falling; this.rotationOnFallIteration = branchContainer.rotationOnFallIteration; this.branchNumber = branchContainer.branchNumber; this.branchPoints = new List <RTBranchPoint>(branchContainer.branchPoints.Count); for (int i = 0; i < branchContainer.branchPoints.Count; i++) { RTBranchPoint rtBranchPoint = new RTBranchPoint(branchContainer.branchPoints[i], this); rtBranchPoint.CalculateCenterLoop(ivyGO); rtBranchPoint.PreInit(ivyParameters); rtBranchPoint.CalculateVerticesLoop(ivyParameters, rtIvyContainer, ivyGO); this.branchPoints.Add(rtBranchPoint); } branchContainer.PrepareRTLeavesDict(); if (ivyParameters.generateLeaves) { this.leavesOrderedByInitSegment = new RTLeafPoint[branchPoints.Count][]; for (int i = 0; i < branchPoints.Count; i++) { List <LeafPoint> leavesToBake = branchContainer.dictRTLeavesByInitSegment[i]; int numLeaves = 0; if (leavesToBake != null) { numLeaves = leavesToBake.Count; } this.leavesOrderedByInitSegment[i] = new RTLeafPoint[numLeaves]; for (int j = 0; j < numLeaves; j++) { RTLeafPoint rtLeafPoint = new RTLeafPoint(leavesToBake[j], ivyParameters); RTMeshData leafMeshData = leavesMeshesByChosenLeaf[rtLeafPoint.chosenLeave]; rtLeafPoint.CreateVertices(ivyParameters, leafMeshData, ivyGO); this.leavesOrderedByInitSegment[i][j] = rtLeafPoint; } } } }
void NewGrowDirectionAfterCorner(BranchContainer branch, Vector3 oldSurfaceNormal, Vector3 newSurfaceNormal) { branch.growDirection = Vector3.Normalize(Vector3.ProjectOnPlane(-oldSurfaceNormal, newSurfaceNormal)); }