public void CreateBuildingMeshData(Mesh bakedMesh, int numBranches) { int numVerticesPerLoop = ivyParameters.sides + 1; int numVertices = (backtrackingPoints * numVerticesPerLoop) + (backtrackingPoints * 2 * 8); numVertices *= numBranches; int subMeshCount = bakedMesh.subMeshCount; List <int> numTrianglesPerSubmesh = new List <int>(); int branchTrianglesNumber = ((backtrackingPoints - 2) * (ivyParameters.sides * 6)) + (ivyParameters.sides * 3); branchTrianglesNumber *= numBranches; numTrianglesPerSubmesh.Add(branchTrianglesNumber); for (int i = 1; i < subMeshCount; i++) { int numTriangles = backtrackingPoints * 6 * numBranches; numTrianglesPerSubmesh.Add(numTriangles); } this.buildingMeshData = new RTMeshData(numVertices, subMeshCount, numTrianglesPerSubmesh); }
private void CreateLeavesDict() { List <List <int> > typesByMat = new List <List <int> >(); this.leavesMaterials = new List <Material>(); this.leavesMeshesByChosenLeaf = new RTMeshData[ivyParameters.leavesPrefabs.Length]; leavesMaterials.Add(ivyParameters.branchesMaterial); this.submeshByChoseLeaf = new int[ivyParameters.leavesPrefabs.Length]; int submeshCount = 0; for (int i = 0; i < ivyParameters.leavesPrefabs.Length; i++) { MeshRenderer leafMeshRenderer = ivyParameters.leavesPrefabs[i].GetComponent <MeshRenderer>(); MeshFilter leafMeshFilter = ivyParameters.leavesPrefabs[i].GetComponent <MeshFilter>(); if (!leavesMaterials.Contains(leafMeshRenderer.sharedMaterial)) { leavesMaterials.Add(leafMeshRenderer.sharedMaterial); submeshCount++; } this.submeshByChoseLeaf[i] = submeshCount; RTMeshData leafMeshData = new RTMeshData(leafMeshFilter.sharedMesh); leavesMeshesByChosenLeaf[i] = leafMeshData; } Material[] materials = leavesMaterials.ToArray(); mrProcessedMesh.sharedMaterials = materials; }
public void CreateVertices(IvyParameters ivyParameters, RTMeshData leafMeshData, GameObject ivyGO) { Vector3 vertex = Vector3.zero; Vector3 normal = Vector3.zero; Vector2 uv = Vector2.zero; Color vertexColor = Color.black; Quaternion ivyGOInverseRotation = Quaternion.Inverse(ivyGO.transform.rotation); leafCenter = ivyGO.transform.InverseTransformPoint(point); for (int v = 0; v < leafMeshData.vertices.Length; v++) { Vector3 offset = left * ivyParameters.offset.x + this.lpUpward * ivyParameters.offset.y + this.lpForward * ivyParameters.offset.z; vertex = leafRotation * leafMeshData.vertices[v] * leafScale + point + offset; vertex = vertex - ivyGO.transform.position; vertex = ivyGOInverseRotation * vertex; normal = leafRotation * leafMeshData.normals[v]; normal = ivyGOInverseRotation * normal; uv = leafMeshData.uv[v]; vertexColor = leafMeshData.colors[v]; this.vertices[v] = new RTVertexData(vertex, normal, uv, Vector2.zero, vertexColor); } }
/*private void DrawBranchPoints(Color color) * { * ivyInfo = (IvyInfo)target; * Handles.color = color; * * RTBakedIvy bakedIvy = ivyInfo.GetComponent<RTBakedIvy>(); * * BranchContainer branch = bakedIvy.ivyContainer.branches[1]; * * //BranchContainer currentBranch = ivyInfo.infoPool.ivyContainer.branches[i]; * Handles.color = Color.blue; * Handles.CubeHandleCap(0, branch.branchPoints[0].point, Quaternion.identity, 0.0025f, EventType.Repaint); * for (int j = 1; j < branch.branchPoints.Count; j++) * { * Handles.color = color; * Handles.CubeHandleCap(0, branch.branchPoints[j].point, Quaternion.identity, 0.0025f, EventType.Repaint); * } * * }*/ private void DrawBuildingMesh(Color color) { ivyInfo = (IvyInfo)target; Handles.color = color; RuntimeBakedIvy bakedIvy = ivyInfo.GetComponent <RuntimeBakedIvy>(); if (bakedIvy != null && bakedIvy.meshBuilder != null) { RTMeshData meshData = bakedIvy.meshBuilder.buildingMeshData; int maxVertices = meshData.VertexCount(); int initIndex = meshData.VertexCount() - 200; initIndex = Mathf.Clamp(initIndex, 0, int.MaxValue); maxVertices = Mathf.Clamp(maxVertices, 0, 100); for (int i = 0; i < meshData.VertexCount(); i++) { Vector3 pos = ivyInfo.transform.TransformPoint(meshData.vertices[i]); Handles.CubeHandleCap(0, pos, Quaternion.identity, 0.0025f, EventType.Repaint); Handles.Label(pos, "" + i); } } //ivyMesh.vertices.Length - 25 }
private void DrawProcessedMeshVertices(Color[] colorPerBranch) { ivyInfo = (IvyInfo)target; RuntimeBakedIvy bakedIvy = ivyInfo.GetComponent <RuntimeBakedIvy>(); RTMeshData processedMeshData = bakedIvy.meshBuilder.processedMeshData; List <List <int> > verticesIndicesPerBranch = bakedIvy.meshBuilder.processedVerticesIndicesPerBranch; int verticesPerLoop = bakedIvy.meshBuilder.ivyParameters.sides + 1; int initIndex = verticesIndicesPerBranch.Count - (verticesPerLoop * 4); initIndex = Mathf.Clamp(initIndex, 0, int.MaxValue); Handles.color = Color.yellow; for (int j = 0; j < bakedIvy.meshBuilder.processedMeshData.VertexCount(); j++) { Vector3 vertex = bakedIvy.meshBuilder.processedMeshData.vertices[j]; Vector3 pos = ivyInfo.transform.TransformPoint(vertex); Handles.CubeHandleCap(0, pos, Quaternion.identity, 0.01f, EventType.Repaint); } for (int j = 0; j < verticesIndicesPerBranch[verticesIndicesPerBranch.Count - 1].Count; j++) { int index = verticesIndicesPerBranch[verticesIndicesPerBranch.Count - 1][j]; Vector3 pos = ivyInfo.transform.TransformPoint(processedMeshData.vertices[index]); Handles.CubeHandleCap(0, pos, Quaternion.identity, 0.01f, EventType.Repaint); } }
public void CreateProcessedMeshData(Mesh bakedMesh) { int numVertices = bakedMesh.vertexCount; int submeshCount = bakedMesh.subMeshCount; List <int> numTrianglesPerSubmesh = new List <int>(); for (int i = 0; i < submeshCount; i++) { int numTriangles = bakedMesh.GetTriangles(i).Length; numTrianglesPerSubmesh.Add(numTriangles); } this.processedMeshData = new RTMeshData(numVertices, submeshCount, numTrianglesPerSubmesh); }
public void CreateProcessedMeshDataProcedural(Mesh bakedMesh, float lifetime, float velocity) { float ratio = lifetime / velocity; int numPoints = Mathf.CeilToInt(ratio * 200); int numVertices = numPoints * (ivyParameters.sides + 1); int submeshCount = bakedMesh.subMeshCount; List <int> numTrianglesPerSubmesh = new List <int>(); for (int i = 0; i < submeshCount; i++) { int numTriangles = ivyParameters.sides * numPoints * 9; numTrianglesPerSubmesh.Add(numTriangles); } this.processedMeshData = new RTMeshData(numVertices, submeshCount, numTrianglesPerSubmesh); }
//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 CopyDataFromIndex(int index, int lastTriCount, int numTris, RTMeshData copyFrom) { vertices[index] = copyFrom.vertices[index]; normals[index] = copyFrom.normals[index]; uv[index] = copyFrom.uv[index]; }
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++; } } } }
public void CreateBakedMeshData(Mesh bakedMesh) { this.bakedMeshData = new RTMeshData(bakedMesh); }
public void PreInit(RTMeshData leafMeshData) { this.vertices = new RTVertexData[leafMeshData.vertices.Length]; }
public void CreateVertices(IvyParameters ivyParameters, RTMeshData leafMeshData, GameObject ivyGO) { Vector3 left, forward; Quaternion quat; //Aquí cálculos de orientación en función de las opciones de rotación if (!ivyParameters.globalOrientation) { forward = lpForward; left = this.left; //left = Vector3.Cross(currentLeaf.lpForward, currentLeaf.lpUpward); } else { forward = ivyParameters.globalRotation; left = Vector3.Normalize(Vector3.Cross(ivyParameters.globalRotation, this.lpUpward)); } //Y aplicamos la rotación quat = Quaternion.LookRotation(this.lpUpward, forward); quat = Quaternion.AngleAxis(ivyParameters.rotation.x, left) * Quaternion.AngleAxis(ivyParameters.rotation.y, this.lpUpward) * Quaternion.AngleAxis(ivyParameters.rotation.z, forward) * quat; quat = Quaternion.AngleAxis(Random.Range(-ivyParameters.randomRotation.x, ivyParameters.randomRotation.x), left) * Quaternion.AngleAxis(Random.Range(-ivyParameters.randomRotation.y, ivyParameters.randomRotation.y), this.lpUpward) * Quaternion.AngleAxis(Random.Range(-ivyParameters.randomRotation.z, ivyParameters.randomRotation.z), forward) * quat; quat = this.forwarRot * quat; //Aquí la escala, que es facilita, incluyendo el tip influence float scale = Random.Range(ivyParameters.minScale, ivyParameters.maxScale); //scale *= Mathf.InverseLerp(infoPool.ivyContainer.branches[b].totalLenght, infoPool.ivyContainer.branches[b].totalLenght - infoPool.ivyParameters.tipInfluence, currentLeaf.lpLength); /*******************/ this.leafRotation = quat; //currentLeaf.dstScale = scale; /*******************/ this.leafCenter = this.point - ivyGO.transform.position; this.leafCenter = Quaternion.Inverse(ivyGO.transform.rotation) * this.leafCenter; if (this.verticesLeaves == null) { this.verticesLeaves = new List <RTVertexData>(4); } //this.verticesLeaves.Clear(); Vector3 vertex = Vector3.zero; Vector3 normal = Vector3.zero; Vector2 uv = Vector2.zero; Color vertexColor = Color.black; Quaternion ivyGOInverseRotation = Quaternion.Inverse(ivyGO.transform.rotation); for (int v = 0; v < leafMeshData.vertices.Length; v++) { Vector3 offset = left * ivyParameters.offset.x + this.lpUpward * ivyParameters.offset.y + this.lpForward * ivyParameters.offset.z; vertex = quat * leafMeshData.vertices[v] * scale + leafCenter + offset; normal = quat * leafMeshData.normals[v]; normal = ivyGOInverseRotation * normal; uv = leafMeshData.uv[v]; vertexColor = leafMeshData.colors[v]; RTVertexData vertexData = new RTVertexData(vertex, normal, uv, Vector2.zero, vertexColor); this.verticesLeaves.Add(vertexData); } }