private Quaternion CalculateLeafRotation(LeafPoint leafPoint) { Vector3 left, forward; Quaternion res; //Aquí cálculos de orientación en función de las opciones de rotación if (!ivyParameters.globalOrientation) { forward = leafPoint.lpForward; left = leafPoint.left; } else { forward = ivyParameters.globalRotation; left = Vector3.Normalize(Vector3.Cross(ivyParameters.globalRotation, leafPoint.lpUpward)); } //Y aplicamos la rotación res = Quaternion.LookRotation(leafPoint.lpUpward, forward); res = Quaternion.AngleAxis(ivyParameters.rotation.x, left) * Quaternion.AngleAxis(ivyParameters.rotation.y, leafPoint.lpUpward) * Quaternion.AngleAxis(ivyParameters.rotation.z, forward) * res; res = Quaternion.AngleAxis(Random.Range(-ivyParameters.randomRotation.x, ivyParameters.randomRotation.x), left) * Quaternion.AngleAxis(Random.Range(-ivyParameters.randomRotation.y, ivyParameters.randomRotation.y), leafPoint.lpUpward) * Quaternion.AngleAxis(Random.Range(-ivyParameters.randomRotation.z, ivyParameters.randomRotation.z), forward) * res; return(res); }
private LeafPoint GetNextLeaf(LeafInfo leafInfo) { LeafPoint res = null; float length = overSegment[0].length + Vector3.Distance(leafInfo.pointWS, overSegment[0].point); for (int i = 0; i < overBranch.leaves.Count; i++) { if (res == null) { res = overBranch.leaves[i]; } else if (overBranch.leaves[i].lpLength < length) { res = overBranch.leaves[i]; } else { res = overBranch.leaves[i]; break; } } return(res); }
public LeafPoint AddLeaf(Vector3 leafPoint, float lpLength, Vector3 lpForward, Vector3 lpUpward, int chosenLeave, BranchPoint initSegment, BranchPoint endSegment) { LeafPoint newLeaf = new LeafPoint(leafPoint, lpLength, lpForward, lpUpward, chosenLeave, initSegment, endSegment); leaves.Add(newLeaf); return(newLeaf); }
public LeafPoint InsertLeaf(Vector3 leafPoint, float lpLength, Vector3 lpForward, Vector3 lpUpward, int chosenLeave, int leafIndex, BranchPoint initSegment, BranchPoint endSegment) { LeafPoint newLeaf = new LeafPoint(leafPoint, lpLength, lpForward, lpUpward, chosenLeave, initSegment, endSegment); int clampedLeafIndex = Mathf.Clamp(leafIndex, 0, int.MaxValue); leaves.Insert(clampedLeafIndex, newLeaf); return(newLeaf); }
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); }
private void AddLeaf(LeafInfo leafInfo) { BranchPoint branchPoint = overBranch.GetNearestPointFrom(mousePoint); LeafPoint nextLeaf = GetNextLeaf(leafInfo); int leafIndex = overBranch.leaves.IndexOf(nextLeaf); lastLeafPoint = overBranch.AddRandomLeaf(leafInfo.pointWS, overSegment[0], overSegment[1], leafIndex, infoPool); RefreshMesh(true, true); }
public void UpdateLeavesDictEntry(int initSegmentIdx, LeafPoint leaf) { if (dictRTLeavesByInitSegment.ContainsKey(initSegmentIdx)) { dictRTLeavesByInitSegment[initSegmentIdx].Add(leaf); } else { List <LeafPoint> newEntryLeaves = new List <LeafPoint>(); newEntryLeaves.Add(leaf); dictRTLeavesByInitSegment[initSegmentIdx] = newEntryLeaves; } }
public LeafPoint AddRandomLeaf(Vector3 pointWS, BranchPoint initSegment, BranchPoint endSegment, int leafIndex, InfoPool infoPool) { int chosenLeave = UnityEngine.Random.Range(0, infoPool.ivyParameters.leavesPrefabs.Length); Vector3 forward = initSegment.initialGrowDir; float lpLength = initSegment.length + Vector3.Distance(pointWS, initSegment.point); LeafPoint res = InsertLeaf(pointWS, lpLength, forward, -initSegment.grabVector, chosenLeave, leafIndex, initSegment, endSegment); return(res); }
public RTLeafPoint(LeafPoint leafPoint, IvyParameters ivyParameters) { this.point = leafPoint.point; this.lpLength = leafPoint.lpLength; this.left = leafPoint.left; this.lpForward = leafPoint.lpForward; this.lpUpward = leafPoint.lpUpward; this.initSegmentIdx = leafPoint.initSegmentIdx; this.endSegmentIdx = leafPoint.endSegmentIdx; this.chosenLeave = leafPoint.chosenLeave; this.vertices = leafPoint.verticesLeaves.ToArray(); this.leafCenter = leafPoint.leafCenter; this.leafRotation = leafPoint.leafRotation; this.leafScale = leafPoint.leafScale; CalculateLeafRotation(ivyParameters); }
//Aquí se construyen las hojas, este método es llamado rama a rama void BuildLeaves(int b, ref int vertCount) { Mesh chosenLeaveMesh; //Se recorren los materiales for (int i = 0; i < leavesMaterials.Count; i++) { Random.InitState(b + infoPool.ivyParameters.randomSeed + i); for (int j = 0; j < infoPool.ivyContainer.branches[b].leaves.Count; j++) { LeafPoint currentLeaf = infoPool.ivyContainer.branches[b].leaves[j]; //Ahora vemos si para el material que estamos iterando, le corresponde el tipo de hoja que tenemos en este punto if (typesByMat[i].Contains(currentLeaf.chosenLeave)) { currentLeaf.verticesLeaves = new List <RTVertexData>(); //Y vemos qué tipo de hoja corresponde a cada punto a cogemos esa malla chosenLeaveMesh = infoPool.ivyParameters.leavesPrefabs[currentLeaf.chosenLeave].GetComponent <MeshFilter>().sharedMesh; //definimos el vértice por el que tenemos que empezar a escribir en el array int firstVertex = vertCount; Vector3 left, forward; Quaternion quat; //Aquí cálculos de orientación en función de las opciones de rotación if (!infoPool.ivyParameters.globalOrientation) { forward = currentLeaf.lpForward; left = currentLeaf.left; //left = Vector3.Cross(currentLeaf.lpForward, currentLeaf.lpUpward); } else { forward = infoPool.ivyParameters.globalRotation; left = Vector3.Normalize(Vector3.Cross(infoPool.ivyParameters.globalRotation, currentLeaf.lpUpward)); } //Y aplicamos la rotación quat = Quaternion.LookRotation(currentLeaf.lpUpward, forward); quat = Quaternion.AngleAxis(infoPool.ivyParameters.rotation.x, left) * Quaternion.AngleAxis(infoPool.ivyParameters.rotation.y, currentLeaf.lpUpward) * Quaternion.AngleAxis(infoPool.ivyParameters.rotation.z, forward) * quat; quat = Quaternion.AngleAxis(Random.Range(-infoPool.ivyParameters.randomRotation.x, infoPool.ivyParameters.randomRotation.x), left) * Quaternion.AngleAxis(Random.Range(-infoPool.ivyParameters.randomRotation.y, infoPool.ivyParameters.randomRotation.y), currentLeaf.lpUpward) * Quaternion.AngleAxis(Random.Range(-infoPool.ivyParameters.randomRotation.z, infoPool.ivyParameters.randomRotation.z), forward) * quat; quat = currentLeaf.forwarRot * quat; //Aquí la escala, que es facilita, incluyendo el tip influence float scale = Random.Range(infoPool.ivyParameters.minScale, infoPool.ivyParameters.maxScale); currentLeaf.leafScale = scale; scale *= Mathf.InverseLerp(infoPool.ivyContainer.branches[b].totalLenght, infoPool.ivyContainer.branches[b].totalLenght - infoPool.ivyParameters.tipInfluence, currentLeaf.lpLength); /*******************/ currentLeaf.leafRotation = quat; currentLeaf.dstScale = scale; /*******************/ //Metemos los triángulos correspondientes en el array correspondiente al material que estamos iterando for (int t = 0; t < chosenLeaveMesh.triangles.Length; t++) { int triangle = chosenLeaveMesh.triangles[t] + vertCount; trisLeaves[i].Add(triangle); } //ylos vértices, normales y uvs, aplicando las transformaciones pertinentes, actualizando el contador para la siguiente iteración saber por dónde vamos for (int v = 0; v < chosenLeaveMesh.vertexCount; v++) { Vector3 offset = left * infoPool.ivyParameters.offset.x + currentLeaf.lpUpward * infoPool.ivyParameters.offset.y + currentLeaf.lpForward * infoPool.ivyParameters.offset.z; verts[vertCount] = quat * chosenLeaveMesh.vertices[v] * scale + currentLeaf.point + offset; normals[vertCount] = quat * chosenLeaveMesh.normals[v]; uvs[vertCount] = chosenLeaveMesh.uv[v]; vColor[vertCount] = chosenLeaveMesh.colors[v]; normals[vertCount] = Quaternion.Inverse(infoPool.ivyContainer.ivyGO.transform.rotation) * normals[vertCount]; verts[vertCount] -= infoPool.ivyContainer.ivyGO.transform.position; verts[vertCount] = Quaternion.Inverse(infoPool.ivyContainer.ivyGO.transform.rotation) * verts[vertCount]; RTVertexData vertexData = new RTVertexData(verts[vertCount], normals[vertCount], uvs[vertCount], Vector2.zero, vColor[vertCount]); currentLeaf.verticesLeaves.Add(vertexData); currentLeaf.leafCenter = currentLeaf.point - infoPool.ivyContainer.ivyGO.transform.position; currentLeaf.leafCenter = Quaternion.Inverse(infoPool.ivyContainer.ivyGO.transform.rotation) * currentLeaf.leafCenter; vertCount++; } //escribimos en el diccionario el index por donde nos hemos quedado para después poder //transformar las uvs de cada elemento acorde a su dimensión real int[] fromTo = new int[2] { firstVertex, vertCount - 1 }; branchesLeavesIndices.Add(branchesLeavesIndices.Count, fromTo); } //for (int p = 0; p < currentBranchPoint.leaves.Count; p++) //{ //} } /*//Después por cada material, recorremos los puntos de la rama * for (int j = 0; j < infoPool.ivyContainer.branches[b].branchPoints.Count; j++) { * * * * * * * }*/ } }
public void AddLeaf(LeafPoint leafPoint) { leaves.Add(leafPoint); }