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 AddLeaf(RTLeafPoint leafAdded) { if (leafAdded.initSegmentIdx >= leavesOrderedByInitSegment.Length) { System.Array.Resize(ref leavesOrderedByInitSegment, leavesOrderedByInitSegment.Length * 2); for (int i = leafAdded.initSegmentIdx; i < leavesOrderedByInitSegment.Length; i++) { leavesOrderedByInitSegment[i] = new RTLeafPoint[1]; } } leavesOrderedByInitSegment[leafAdded.initSegmentIdx][0] = leafAdded; }
private RTLeafPoint GetNextLeafPoint() { RTLeafPoint res = leavesPool[leavesPoolIndex]; leavesPoolIndex++; if (leavesPoolIndex >= leavesPool.Length) { System.Array.Resize(ref leavesPool, leavesPool.Length * 2); for (int i = leavesPoolIndex; i < leavesPool.Length; i++) { leavesPool[i] = new RTLeafPoint(); leavesPool[i].PreInit(maxNumVerticesPerLeaf); } } return(res); }
//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 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 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 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++; } } } }