protected virtual void Growing(int branchIndex, float deltaTime) { RTBranchContainer currentBranch = activeBuildingBranches[branchIndex]; CalculateFactors(srcPoints[branchIndex], dstPoints[branchIndex]); meshBuilder.SetLeafLengthCorrectionFactor(leafLengthCorrrectionFactor); growingFactorPerBranch[branchIndex] += currentSpeed * deltaTime; growingFactorPerBranch[branchIndex] = Mathf.Clamp(growingFactorPerBranch[branchIndex], 0f, 1f); currentBranch.totalLength = Mathf.Lerp(srcTotalLengthPerBranch[branchIndex], dstTotalLengthPerBranch[branchIndex], growingFactorPerBranch[branchIndex]); RTBranchPoint lastPoint = currentBranch.GetLastBranchPoint(); lastPoint.length = currentBranch.totalLength; lastPoint.point = Vector3.Lerp(srcPoints[branchIndex], dstPoints[branchIndex], growingFactorPerBranch[branchIndex]); if (growingFactorPerBranch[branchIndex] >= 1) { RefreshGeometry(); NextPoints(branchIndex); } }
//Añadimos punto y todo lo que ello conlleva. Está la posibilidad de spawnear una rama public void AddPoint(RTBranchContainer branch, Vector3 point, Vector3 normal) { branch.totalLength += ivyParameters.stepSize; RTBranchPoint branchPoint = GetNextFreeBranchPoint(); branchPoint.SetValues(point + normal * branch.currentHeight, -normal); branch.AddBranchPoint(branchPoint, ivyParameters.stepSize); CalculateVerticesLastPoint(branch); //Vector3 axis = GetLoopAxis(branchPoint, branch, rtIvyContainer, ivyGO); //Vector3 firstVector = GetFirstVector(branchPoint, branch, rtIvyContainer, ivyParameters, axis); //branchPoint.CalculateCenterLoop(ivyGO); //branchPoint.CalculateVerticesLoop(ivyParameters, rtIvyContainer, ivyGO, firstVector, axis); /*if(branch.branchPoints.Count >= 1) * { * branch.branchPoints[branch.branchPoints.Count - 2].CalculateVerticesLoop(ivyParameters, rtIvyContainer, ivyGO); * }*/ if (Random.value < ivyParameters.branchProvability && rtIvyContainer.branches.Count < ivyParameters.maxBranchs) { AddBranch(branch, branch.GetLastBranchPoint(), branch.branchPoints[branch.branchPoints.Count - 1].point, normal); } if (ivyParameters.generateLeaves) { AddLeave(branch); } }
protected virtual void AddNextBranch(int branchNumber) { lastIdxActiveBranch++; RTBranchContainer newBuildingBranch = activeBuildingBranches[lastIdxActiveBranch]; RTBranchContainer bakedBranch = rtIvyContainer.GetBranchContainerByBranchNumber(branchNumber); newBuildingBranch.AddBranchPoint(bakedBranch.branchPoints[0], ivyParameters.stepSize); newBuildingBranch.AddBranchPoint(bakedBranch.branchPoints[1], ivyParameters.stepSize); newBuildingBranch.leavesOrderedByInitSegment = bakedBranch.leavesOrderedByInitSegment; rtBuildingIvyContainer.AddBranch(newBuildingBranch); activeBakedBranches.Add(bakedBranch); activeBuildingBranches.Add(newBuildingBranch); meshBuilder.activeBranches.Add(newBuildingBranch); UpdateGrowingPoints(rtBuildingIvyContainer.branches.Count - 1); RTBranchPoint lastBranchPoint = newBuildingBranch.GetLastBranchPoint(); if (lastBranchPoint.newBranch) { AddNextBranch(lastBranchPoint.newBranchNumber); } }
public Vector3 GetFirstVector(RTBranchPoint rtBranchPoint, RTBranchContainer rtBranchContainer, RTIvyContainer rtIvyContainer, IvyParameters ivyParameters, Vector3 axis) { Vector3 firstVector = Vector3.zero; if (rtBranchContainer.branchNumber == 0 && rtBranchPoint.index == 0) { if (!ivyParameters.halfgeom) { firstVector = rtIvyContainer.firstVertexVector; } else { firstVector = Quaternion.AngleAxis(90f, axis) * rtIvyContainer.firstVertexVector; } } else { if (!ivyParameters.halfgeom) { firstVector = Vector3.Normalize(Vector3.ProjectOnPlane(rtBranchPoint.grabVector, axis)); } else { firstVector = Quaternion.AngleAxis(90f, axis) * Vector3.Normalize(Vector3.ProjectOnPlane(rtBranchPoint.grabVector, axis)); } } return(firstVector); }
//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(RTBranchContainer branch, RTBranchPoint potentialPoint, Vector3 oldSurfaceNormal) { Ray ray = new Ray(potentialPoint.point, -oldSurfaceNormal); RaycastHit RC; if (Physics.Raycast(ray, out RC, branch.currentHeight * 2f, ivyParameters.layerMask.value)) { AddPoint(branch, RC.point, RC.normal); NewGrowDirection(branch); branch.fallIteration = 0f; branch.falling = false; } else { if (Random.value < ivyParameters.grabProvabilityOnFall) { CheckCorner(branch, potentialPoint, oldSurfaceNormal); } else { AddFallingPoint(branch); branch.fallIteration += 1f - ivyParameters.stiffness; branch.falling = true; branch.currentHeight = 0f; branch.heightParameter = -45f; } } }
private void BuildLeaves(int branchIndex, RTBranchContainer buildingBranchContainer, RTBranchContainer bakedBranchContainer) { RTMeshData chosenLeaveMeshData; int firstPointIdx = buildingBranchContainer.branchPoints.Count - backtrackingPoints; firstPointIdx = Mathf.Clamp(firstPointIdx, 0, int.MaxValue); for (int i = firstPointIdx; i < buildingBranchContainer.branchPoints.Count; i++) { RTLeafPoint[] leaves = bakedBranchContainer.leavesOrderedByInitSegment[i]; RTBranchPoint rtBranchPoint = buildingBranchContainer.branchPoints[i]; for (int j = 0; j < leaves.Length; j++) { RTLeafPoint currentLeaf = leaves[j]; if (currentLeaf == null) { continue; } float tipInfluenceFactor = Mathf.InverseLerp(buildingBranchContainer.totalLength, (buildingBranchContainer.totalLength - ivyParameters.tipInfluence), rtBranchPoint.length); chosenLeaveMeshData = leavesMeshesByChosenLeaf[currentLeaf.chosenLeave]; //Metemos los triángulos correspondientes en el array correspondiente al material que estamos iterando for (int t = 0; t < chosenLeaveMeshData.triangles[0].Length; t++) { int triangleValue = chosenLeaveMeshData.triangles[0][t] + vertCount; int submesh = submeshByChoseLeaf[currentLeaf.chosenLeave]; buildingMeshData.AddTriangle(submesh, triangleValue); } for (int v = 0; v < currentLeaf.vertices.Length; v++) { Vector3 vertex = Vector3.LerpUnclamped(currentLeaf.leafCenter, currentLeaf.vertices[v].vertex, tipInfluenceFactor); buildingMeshData.AddVertex(vertex, currentLeaf.vertices[v].normal, currentLeaf.vertices[v].uv, currentLeaf.vertices[v].color); vertCountLeavesPerBranch[branchIndex]++; vertCountsPerBranch[branchIndex]++; vertCount++; } } } }
//public void PrepareRTLeavesDict() //{ // dictRTLeavesByInitSegment = new Dictionary<int, List<RTLeafPoint>>(); // for (int i = 0; i < branchPoints.Count; i++) // { // List<RTLeafPoint> leaves = new List<RTLeafPoint>(); // GetLeavesInSegment(branchPoints[i], leaves); // dictRTLeavesByInitSegment[i] = leaves; // } //} //public void UpdateLeavesDictEntry(int initSegmentIndex, RTLeafPoint leafAdded) //{ // if(leavesOrderedByInitSegment.Count > initSegmentIndex) // { // leavesOrderedByInitSegment[initSegmentIndex] = leafAdded; // } // else // { // leavesOrderedByInitSegment[initSegmentIndex].Add(leafAdded); // } //} public void AddBranchPoint(RTBranchPoint rtBranchPoint, float deltaLength) { this.totalLength += deltaLength; rtBranchPoint.length = this.totalLength; rtBranchPoint.index = branchPoints.Count; rtBranchPoint.branchContainer = this; branchPoints.Add(rtBranchPoint); }
private void CalculateVerticesLastPoint(RTBranchContainer rtBranchContainer) { if (rtBranchContainer.branchPoints.Count > 1) { RTBranchPoint branchPoint = rtBranchContainer.branchPoints[rtBranchContainer.branchPoints.Count - 2]; float radius = CalculateRadius(branchPoint.length); Vector3 axis = GetLoopAxis(branchPoint, rtBranchContainer, rtIvyContainer, ivyGO); Vector3 firstVector = GetFirstVector(branchPoint, rtBranchContainer, rtIvyContainer, ivyParameters, axis); branchPoint.CalculateCenterLoop(ivyGO); branchPoint.CalculateVerticesLoop(ivyParameters, rtIvyContainer, ivyGO, firstVector, axis, radius); } }
public void SetValues(Vector3 point, float lpLength, Vector3 lpForward, Vector3 lpUpward, int chosenLeave, RTBranchPoint initSegment, RTBranchPoint endSegment, float leafScale, IvyParameters ivyParameters) { this.point = point; this.lpLength = lpLength; this.lpForward = lpForward; this.lpUpward = lpUpward; this.chosenLeave = chosenLeave; this.initSegmentIdx = initSegment.index; this.endSegmentIdx = endSegment.index; this.leafScale = leafScale; this.left = Vector3.Cross(lpForward, lpUpward).normalized; CalculateLeafRotation(ivyParameters); }
private void UpdateGrowingPoints(int branchIndex) { if (rtBuildingIvyContainer.branches[branchIndex].branchPoints.Count > 0) { RTBranchPoint fromPoint = rtBuildingIvyContainer.branches[branchIndex].GetLastBranchPoint(); if (fromPoint.index < activeBakedBranches[branchIndex].branchPoints.Count - 1) { RTBranchPoint nextPoint = activeBakedBranches[branchIndex].branchPoints[fromPoint.index + 1]; growingFactorPerBranch[branchIndex] = 0f; srcPoints[branchIndex] = fromPoint.point; dstPoints[branchIndex] = nextPoint.point; srcTotalLengthPerBranch[branchIndex] = fromPoint.length; dstTotalLengthPerBranch[branchIndex] = fromPoint.length + ivyParameters.stepSize; } } }
protected virtual void NextPoints(int branchIndex) { if (rtBuildingIvyContainer.branches[branchIndex].branchPoints.Count > 0) { RTBranchPoint lastBuildingBranchPoint = rtBuildingIvyContainer.branches[branchIndex].GetLastBranchPoint(); if (lastBuildingBranchPoint.index < activeBakedBranches[branchIndex].branchPoints.Count - 1) { int indexBranchPoint = lastBuildingBranchPoint.index; indexBranchPoint++; RTBranchPoint branchPoint = activeBakedBranches[branchIndex].branchPoints[indexBranchPoint]; RTBranchContainer branch = rtBuildingIvyContainer.branches[branchIndex]; branch.AddBranchPoint(branchPoint, ivyParameters.stepSize); if (branchPoint.newBranch) { RTBranchContainer candidateBranch = rtIvyContainer.GetBranchContainerByBranchNumber(branchPoint.newBranchNumber); if (candidateBranch.branchPoints.Count >= 2) { AddNextBranch(branchPoint.newBranchNumber); } } UpdateGrowingPoints(branchIndex); if (rtBuildingIvyContainer.branches[branchIndex].branchPoints.Count > backtrackingPoints) { if (!IsVertexLimitReached()) { meshBuilder.CheckCopyMesh(branchIndex, activeBakedBranches); refreshProcessedMesh = true; } else { Debug.LogWarning("Limit vertices reached! --> " + Constants.VERTEX_LIMIT_16 + " vertices", meshBuilder.ivyGO); } } } } }
//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) < ivyParameters.stepSize * 0.7f || * Vector3.Distance(branch.branchPoints[branch.branchPoints.Count - 2].point, branch.branchPoints[branch.branchPoints.Count - 1].point) < 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); * * } * } * } */ private RTBranchPoint GetNextFreeBranchPoint() { RTBranchPoint res = branchPointsPool[branchPointPoolIndex]; branchPointPoolIndex++; if (branchPointPoolIndex >= branchPointsPool.Length) { System.Array.Resize(ref branchPointsPool, branchPointsPool.Length * 2); for (int i = branchPointPoolIndex; i < branchPointsPool.Length; i++) { RTBranchPoint branchPoint = new RTBranchPoint(); branchPoint.PreInit(ivyParameters); branchPointsPool[i] = branchPoint; } } return(res); }
//Todo lo necesario para añadir una rama public void AddBranch(RTBranchContainer branch, RTBranchPoint originBranchPoint, Vector3 point, Vector3 normal) { RTBranchContainer newBranchContainer = GetNextBranchContainer(); RTBranchPoint nextPoint = GetNextFreeBranchPoint(); nextPoint.SetValues(point, -normal); newBranchContainer.AddBranchPoint(nextPoint, ivyParameters.stepSize); 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(); rtIvyContainer.AddBranch(newBranchContainer); originBranchPoint.InitBranchInThisPoint(newBranchContainer.branchNumber); }
//Si hábíamos perdido pie, comprobamos si estamos en una esquina e intentamos seguir por el otro lado de lamisma void CheckCorner(RTBranchContainer branch, RTBranchPoint 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, ivyParameters.stepSize * 1.15f, 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 - ivyParameters.stiffness; branch.falling = true; branch.currentHeight = 0f; branch.heightParameter = -45f; } }
//Todo lo necesario para añadir una nueva hoja void AddLeave(RTBranchContainer branch) { if (branch.branchPoints.Count % (ivyParameters.leaveEvery + Random.Range(0, ivyParameters.randomLeaveEvery)) == 0) { int chosenLeaf = Random.Range(0, ivyParameters.leavesPrefabs.Length); RTBranchPoint initSegment = branch.branchPoints[branch.branchPoints.Count - 2]; RTBranchPoint endSegment = branch.branchPoints[branch.branchPoints.Count - 1]; Vector3 leafPoint = Vector3.Lerp(initSegment.point, endSegment.point, 0.5f); float leafScale = Random.Range(ivyParameters.minScale, ivyParameters.maxScale); RTLeafPoint leafAdded = GetNextLeafPoint(); leafAdded.SetValues(leafPoint, branch.totalLength, branch.growDirection, -branch.GetLastBranchPoint().grabVector, chosenLeaf, initSegment, endSegment, leafScale, ivyParameters); RTMeshData leafMeshData = leavesMeshesByChosenLeaf[leafAdded.chosenLeave]; leafAdded.CreateVertices(ivyParameters, leafMeshData, ivyGO); branch.AddLeaf(leafAdded); } }
public Vector3 GetLoopAxis(RTBranchPoint rtBranchPoint, RTBranchContainer rtBranchContainer, RTIvyContainer rtIvyContainer, GameObject ivyGo) { Vector3 axis = Vector3.zero; if (rtBranchPoint.index == 0 && rtBranchContainer.branchNumber == 0) { axis = ivyGo.transform.up; } else { if (rtBranchPoint.index == 0) { axis = rtBranchPoint.GetNextPoint().point - rtBranchPoint.point; } else { axis = Vector3.Normalize(Vector3.Lerp(rtBranchPoint.point - rtBranchPoint.GetPreviousPoint().point, rtBranchPoint.GetNextPoint().point - rtBranchPoint.point, 0.5f)); } } return(axis); }
//Añadimos punto y todo lo que ello conlleva. Es ligeramente diferente a AddPoint. Está la posibilidad de spawnear una rama void AddFallingPoint(RTBranchContainer branch) { Vector3 grabVector = branch.rotationOnFallIteration * branch.GetLastBranchPoint().grabVector; RTBranchPoint branchPoint = GetNextFreeBranchPoint(); branchPoint.point = branch.branchPoints[branch.branchPoints.Count - 1].point + branch.growDirection * ivyParameters.stepSize; branchPoint.grabVector = grabVector; branch.AddBranchPoint(branchPoint, ivyParameters.stepSize); CalculateVerticesLastPoint(branch); //Vector3 axis = GetLoopAxis(branchPoint, branch, rtIvyContainer, ivyGO); //Vector3 firstVector = GetFirstVector(branchPoint, branch, rtIvyContainer, ivyParameters, axis); //branchPoint.CalculateCenterLoop(ivyGO); //branchPoint.CalculateVerticesLoop(ivyParameters, rtIvyContainer, ivyGO, firstVector, axis); /*if (branch.branchPoints.Count >= 1) * { * branch.branchPoints[branch.branchPoints.Count - 2].CalculateVerticesLoop(ivyParameters, rtIvyContainer, ivyGO); * }*/ if (Random.value < ivyParameters.branchProvability && rtIvyContainer.branches.Count < ivyParameters.maxBranchs) { AddBranch(branch, branch.GetLastBranchPoint(), branch.branchPoints[branch.branchPoints.Count - 1].point, -branch.GetLastBranchPoint().grabVector); } if (ivyParameters.generateLeaves) { AddLeave(branch); } }
//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(RTBranchContainer branch) { RTBranchPoint checkPoint = GetNextFreeBranchPoint(); checkPoint.point = branch.GetLastBranchPoint().point + branch.growDirection * ivyParameters.stepSize + branch.GetLastBranchPoint().grabVector *branch.deltaHeight; checkPoint.index = branch.branchPoints.Count; //checkPoint.length = 0f; 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, ivyParameters.stepSize * 1.15f, ivyParameters.layerMask.value)) { CheckFloor(branch, checkPoint, -branch.GetLastBranchPoint().grabVector); } else { NewGrowDirectionAfterWall(branch, -branch.GetLastBranchPoint().grabVector, RC.normal); AddPoint(branch, RC.point, RC.normal); } }
public RTBranchPoint GetPreviousPoint() { RTBranchPoint res = branchContainer.branchPoints[this.index - 1]; return(res); }
public void CopyToFixedMesh(int branchIndex, int initSegmentIdx, int endSegmentIdx, RTBranchContainer branchContainer, RTBranchContainer bakedBranchContainer) { int numVerticesPerLoop = ivyParameters.sides + 1; int numTrianglesPerLoop = ivyParameters.sides * 6; int numLoopsToProcess = 1; int onlyBranchVertices = (vertCountsPerBranch[branchIndex] - vertCountLeavesPerBranch[branchIndex]); int vertexOffset = 0; for (int i = 1; i <= branchIndex; i++) { vertexOffset += vertCountsPerBranch[branchIndex]; } if (processedBranchesVerticesIndicesPerBranch[branchIndex].Count <= 0) { numLoopsToProcess = 2; } else { numLoopsToProcess = 1; vertexOffset += numVerticesPerLoop; } for (int i = numLoopsToProcess - 1; i >= 0; i--) { int index = branchContainer.branchPoints.Count - backtrackingPoints - i; RTBranchPoint rtBranchPoint = branchContainer.branchPoints[index]; for (int j = 0; j < rtBranchPoint.verticesLoop.Length; j++) { RTVertexData vertexData = rtBranchPoint.verticesLoop[j]; processedMeshData.AddVertex(vertexData.vertex, vertexData.normal, vertexData.uv, vertexData.color); processedBranchesVerticesIndicesPerBranch[branchIndex].Add(processedMeshData.VertexCount() - 1); } } int triangleIndexOffset = 0; if (branchIndex > 0) { triangleIndexOffset = lastTriangleIndexPerBranch[branchIndex]; } if (processedBranchesVerticesIndicesPerBranch[branchIndex].Count >= numVerticesPerLoop * 2) { int initIdx = processedBranchesVerticesIndicesPerBranch[branchIndex].Count - (numVerticesPerLoop * 2); for (int i = 0; i < ivyParameters.sides; i++) { int v0 = processedBranchesVerticesIndicesPerBranch[branchIndex][i + initIdx]; int v1 = processedBranchesVerticesIndicesPerBranch[branchIndex][i + 1 + initIdx]; int v2 = processedBranchesVerticesIndicesPerBranch[branchIndex][i + ivyParameters.sides + 1 + initIdx]; int v3 = processedBranchesVerticesIndicesPerBranch[branchIndex][i + 1 + initIdx]; int v4 = processedBranchesVerticesIndicesPerBranch[branchIndex][i + ivyParameters.sides + 2 + initIdx]; int v5 = processedBranchesVerticesIndicesPerBranch[branchIndex][i + ivyParameters.sides + 1 + initIdx]; processedMeshData.AddTriangle(0, v0); processedMeshData.AddTriangle(0, v1); processedMeshData.AddTriangle(0, v2); processedMeshData.AddTriangle(0, v3); processedMeshData.AddTriangle(0, v4); processedMeshData.AddTriangle(0, v5); } } if (ivyParameters.generateLeaves) { int lastVertexLeafProcessed = processedMeshData.VertexCount(); int numLeavesProcessed = 0; for (int i = initSegmentIdx; i < endSegmentIdx; i++) { RTLeafPoint[] leaves = bakedBranchContainer.leavesOrderedByInitSegment[i]; for (int j = 0; j < leaves.Length; j++) { RTLeafPoint currentLeaf = leaves[j]; if (currentLeaf == null) { continue; } RTMeshData chosenLeaveMeshData = leavesMeshesByChosenLeaf[currentLeaf.chosenLeave]; int submesh = submeshByChoseLeaf[currentLeaf.chosenLeave]; for (int t = 0; t < chosenLeaveMeshData.triangles[0].Length; t++) { int triangleValue = chosenLeaveMeshData.triangles[0][t] + lastVertexLeafProcessed; processedMeshData.AddTriangle(submesh, triangleValue); } for (int v = 0; v < currentLeaf.vertices.Length; v++) { RTVertexData vertexData = currentLeaf.vertices[v]; processedMeshData.AddVertex(vertexData.vertex, vertexData.normal, vertexData.uv, vertexData.color); processedVerticesIndicesPerBranch[branchIndex].Add(processedMeshData.VertexCount() - 1); lastVertexLeafProcessed++; } numLeavesProcessed++; } } } }
public RTBranchPoint GetLastBranchPoint() { RTBranchPoint res = branchPoints[branchPoints.Count - 1]; return(res); }
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; } } } }
public void Init(RTIvyContainer ivyContainer, IvyParameters ivyParameters, GameObject ivyGO, RTMeshData[] leavesMeshesByChosenLeaf, int numPoints, int numLeaves, int maxNumVerticesPerLeaf) { this.rtIvyContainer = ivyContainer; this.ivyParameters = ivyParameters; this.ivyGO = ivyGO; this.leavesMeshesByChosenLeaf = leavesMeshesByChosenLeaf; this.numPoints = numPoints; this.numLeaves = numLeaves; this.maxNumVerticesPerLeaf = maxNumVerticesPerLeaf; this.branchPointsPool = new RTBranchPoint[numPoints]; this.branchPointPoolIndex = 0; for (int i = 0; i < numPoints; i++) { RTBranchPoint branchPoint = new RTBranchPoint(); branchPoint.PreInit(ivyParameters); branchPointsPool[i] = branchPoint; } this.leavesPool = new RTLeafPoint[numLeaves]; this.leavesPoolIndex = 0; for (int i = 0; i < numLeaves; i++) { RTLeafPoint leafPoint = new RTLeafPoint(); leafPoint.PreInit(maxNumVerticesPerLeaf); leavesPool[i] = leafPoint; } this.branchesPool = new RTBranchContainer[ivyParameters.maxBranchs]; for (int i = 0; i < ivyParameters.maxBranchs; i++) { this.branchesPool[i] = new RTBranchContainer(numPoints, numLeaves); } Random.InitState(System.Environment.TickCount); RTBranchContainer firstBranch = GetNextBranchContainer(); ivyContainer.AddBranch(firstBranch); RTBranchPoint nextRTBranchPoint = GetNextFreeBranchPoint(); nextRTBranchPoint.SetValues(ivyGO.transform.position, -ivyGO.transform.up, false, 0); firstBranch.AddBranchPoint(nextRTBranchPoint, ivyParameters.stepSize); CalculateVerticesLastPoint(firstBranch); //Vector3 axis = GetLoopAxis(nextRTBranchPoint, firstBranch, rtIvyContainer, ivyGO); //Vector3 firstVector = GetFirstVector(nextRTBranchPoint, firstBranch, rtIvyContainer, ivyParameters, axis); //nextRTBranchPoint.CalculateCenterLoop(ivyGO); //nextRTBranchPoint.CalculateVerticesLoop(ivyParameters, rtIvyContainer, ivyGO, firstVector, axis); ivyContainer.branches[0].growDirection = Quaternion.AngleAxis(Random.value * 360f, ivyGO.transform.up) * ivyGO.transform.forward; ivyContainer.firstVertexVector = ivyContainer.branches[0].growDirection; ivyContainer.branches[0].randomizeHeight = Random.Range(4f, 8f); CalculateNewHeight(ivyContainer.branches[0]); ivyContainer.branches[0].branchSense = ChooseBranchSense(); randomstate = Random.state; }
public RTBranchPoint GetNextPoint() { RTBranchPoint res = branchContainer.branchPoints[this.index + 1]; return(res); }
public void BuildGeometry02(List <RTBranchContainer> activeBakedBranches, List <RTBranchContainer> activeBuildingBranches) { if (!ivyParameters.halfgeom) { angle = Mathf.Rad2Deg * 2 * Mathf.PI / ivyParameters.sides; } else { angle = Mathf.Rad2Deg * 2 * Mathf.PI / ivyParameters.sides / 2; } if (leavesDataInitialized) { ClearTipMesh(); //Recorremos cada rama y definimos el primer vértice que tenemos que escribir del array, recogido del vertcount actualizado en la iteración anterior for (int b = 0; b < rtIvyContainer.branches.Count; b++) { int firstVertex = vertCount; RTBranchContainer currentBranch = activeBuildingBranches[b]; if (currentBranch.branchPoints.Count > 1) { lastVertCount = 0; //Recorremos cada punto de la rama hasta el penúltimo int initIndexPoint = currentBranch.branchPoints.Count - backtrackingPoints; initIndexPoint = Mathf.Clamp(initIndexPoint, 0, int.MaxValue); int endIndexPoint = currentBranch.branchPoints.Count; for (int p = initIndexPoint; p < endIndexPoint; p++) { RTBranchPoint currentBranchPoint = currentBranch.branchPoints[p]; Vector3 centerLoop = ivyGO.transform.InverseTransformPoint(currentBranchPoint.point); Vector3 vertex = zeroVector3; Vector3 normal = zeroVector3; Vector2 uv = zeroVector2; Vector2 uv2 = zeroVector2; Color vertexColor = blackColor; float tipInfluenceFactor = Mathf.InverseLerp(currentBranch.totalLength, currentBranch.totalLength - ivyParameters.tipInfluence, currentBranchPoint.length); if (p < currentBranch.branchPoints.Count - 1) { for (int i = 0; i < currentBranchPoint.verticesLoop.Length; i++) { if (ivyParameters.generateBranches) { vertex = Vector3.LerpUnclamped(currentBranchPoint.centerLoop, currentBranchPoint.verticesLoop[i].vertex, tipInfluenceFactor); buildingMeshData.AddVertex(vertex, currentBranchPoint.verticesLoop[i].normal, currentBranchPoint.verticesLoop[i].uv, currentBranchPoint.verticesLoop[i].color); vertCountsPerBranch[b]++; vertCount++; lastVertCount++; } } } else { vertex = centerLoop; normal = Vector3.Normalize(currentBranchPoint.point - currentBranchPoint.GetPreviousPoint().point); normal = ivyGO.transform.InverseTransformVector(normal); uv = currentBranch.GetLastUV(ivyParameters); buildingMeshData.AddVertex(vertex, normal, uv, Color.black); vertCountsPerBranch[b]++; vertCount++; lastVertCount++; } } SetTriangles(currentBranch, vertCount, initIndexPoint, b); } fromTo[0] = firstVertex; fromTo[1] = vertCount - 1; if (ivyParameters.generateLeaves) { BuildLeaves(b, activeBuildingBranches[b], activeBakedBranches[b]); } } RefreshMesh(); } }