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);
        }
Exemple #10
0
        //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);
 }