예제 #1
0
        public void UpdateSpline()
        {
            int i = 0;

            float startRadius, endRadius;

            startRadius = radiusRate * growRate;

            if (branchType == BranchType.Leaves)
            {
                return;
            }
            if (branchType == BranchType.Trank)
            {
                endRadius = startRadius * 0.15f;
            }
            else
            {
                endRadius = startRadius * 0.02f;
            }

            Vector3    startPos = centerPos;
            Quaternion q        = rotation;

            lengthStep = height * growRate / (spline.Count);

            /*
             * 在样条线上加一个PerlinNoise,两层(一层是幅度一层是相位)
             * 转轴旋转平面垂直于上一个节点的生长方向,从0开始旋转noiseP度;
             * 然后绕转轴旋转noiseA度。
             */

            int   noiseStep = spline.Count / 4;
            float noiseAmpl = 8;//(height * growRate) / 6.0;

            float[] noiseA = MathCore.PerlinNoise(spline.Count, noiseStep, noiseAmpl, null);
            float[] noiseP = MathCore.PerlinNoise(spline.Count, noiseStep, 180, null);//相位先设定为2pi

            //重力
            float[] gravityFactor        = MathCore.PerlinNoise(spline.Count, noiseStep, 0.1f, gravityConst);
            float   gravityInfectionStep = gravityLenthNormalized / nodes;

            //向心旋转(它的主要组成就是perlinNoise)
            float[] gnarlFactor        = MathCore.PerlinNoise(spline.Count, noiseStep, 0.4f, gnarlConst);
            float   gnarlInfectionStep = gnarlLenthNormalized / nodes;

            //样条线
            //第一个点和当前node的数据一致
            spline[i].position       = centerPos;
            spline[i].rotationGlobal = rotation;
            spline[i].tangentGlobal  = (rotation * new Vector3(1, 0, 0));//假定切线在x轴
            spline[i].radius         = startRadius;

            //如果是主干,根部加粗
            if (branchType == BranchType.Trank)
            {
                spline[i].radius *= 2.0f;
            }

            for (i = 1; i < spline.Count; i++)
            {
                //位置是由上一个node的生长方向决定的
                spline[i].position = spline[i - 1].position + spline[i - 1].rotationGlobal * new Vector3(0, lengthStep, 0);

                //先让这个节点的方向和上一个节点的方向保持一致
                spline[i].rotationGlobal = spline[i - 1].rotationGlobal;
                spline[i].tangentGlobal  = spline[i - 1].tangentGlobal;

                //当前生长方向
                Vector3 dirc = spline[i].rotationGlobal * Vector3.up;

                ////////////////////
                //处理重力
                ////////////////////

                /*
                 * 重力直接作用于生长方向上。
                 * 相加,规范化,乘以步长。
                 */
                dirc += gravityInfectionStep * gravityFactor[i] * gravityAxis;
                dirc.Normalize();

                ////////////////////
                //处理旋力
                ////////////////////

                /*
                 * 为了处理“旋力”,我们需要求出在以主干为圆心,过当前点的切线向量。
                 * 并将这个向量和当前的生长方向相加,规范化,乘以步长。
                 * 最后根据它求得这一段的rotation。
                 */

                //先拿到当前点相对父树枝原点的位置
                Vector3 posLocal = spline[i].position - parentCenterPos;
                //把这个相对位置绕父树枝的方向旋转2度,与原向量相减规范化得到近似的切线朝向
                Vector3 tang = Quaternion.AngleAxis(1.0f, parentAxis) * posLocal - posLocal;
                tang.Normalize();

                dirc += tang * gnarlInfectionStep;
                dirc.Normalize();

                ////////////////////
                //计算rotation
                ////////////////////

                spline[i].rotationLocal = Quaternion.FromToRotation(spline[i - 1].rotationGlobal * Vector3.up, dirc);

                ////////////////////
                //处理噪声
                ////////////////////

                //当前旋转方向由噪声决定
                //处理旋转
                //转轴
                Vector3 rotateAxis = Quaternion.AngleAxis(noiseP[i], spline[i - 1].rotationGlobal * new Vector3(0, lengthStep, 0)) * spline[i - 1].tangentGlobal;
                rotateAxis.Normalize();

                //旋转,并保存一个相对与上一个节点的旋转( rotationLocal )
                spline[i].rotationLocal = Quaternion.AngleAxis(noiseA[i], rotateAxis) * spline[i].rotationLocal;

                //更新global
                spline[i].rotationGlobal = spline[i].rotationLocal * spline[i].rotationGlobal;
                spline[i].tangentGlobal  = spline[i].rotationLocal * spline[i].tangentGlobal;

                //处理当前结点截面的大小
                spline[i].radius = ((endRadius - startRadius) * (i / ((float)spline.Count)) + startRadius) * Random.Range(0.9f, 1.1f);
            }

            rotation = spline[i - 1].rotationGlobal;
        }
예제 #2
0
        public void UpdateSpline()
        {
            int i = 0;

            float startRadius, endRadius;

            startRadius = radiusRate * growRate;

            if (branchType == BranchType.Leaves)
            {
                return;
            }
            if (branchType == BranchType.Trank)
            {
                endRadius = startRadius * 0.15f;
            }
            else
            {
                endRadius = startRadius * 0.02f;
            }

            Vector3    startPos   = centerPos;
            Quaternion q          = rotation;
            float      lengthStep = height * growRate / (spline.Count);

            /*
             * 在样条线上加一个PerlinNoise,两层(一层是幅度一层是相位)
             *
             * 转轴旋转平面垂直于上一个节点的生长方向,从0开始旋转noiseP度;
             * 然后绕转轴旋转noiseA度。
             */

            int   noiseStep = spline.Count / 4;
            float noiseAmpl = 8;//(height * growRate) / 6.0;

            float[] noiseA = MathCore.PerlinNoise(spline.Count, noiseStep, noiseAmpl, null);
            float[] noiseP = MathCore.PerlinNoise(spline.Count, noiseStep, 180, null);//相位先设定为2pi

            //样条线
            //第一个点和当前node的数据一致
            spline[i].position       = centerPos;
            spline[i].rotationGlobal = rotation;
            spline[i].tangentGlobal  = (rotation * new Vector3(1, 0, 0));//假定切线在x轴
            spline[i].radius         = startRadius;

            //如果是主干,根部加粗
            if (branchType == BranchType.Trank)
            {
                spline[i].radius *= 2.0f;
            }

            for (i = 1; i < spline.Count; i++)
            {
                //位置是由上一个node的生长方向决定的
                spline[i].position = spline[i - 1].position + spline[i - 1].rotationGlobal * new Vector3(0, lengthStep, 0);

                //当前旋转方向由噪声决定
                //先让这个节点的方向和上一个节点的方向保持一致
                spline[i].rotationGlobal = spline[i - 1].rotationGlobal;
                spline[i].tangentGlobal  = spline[i - 1].tangentGlobal;

                //再处理旋转
                //转轴
                Vector3 rotateAxis = Quaternion.AngleAxis(noiseP[i], spline[i - 1].rotationGlobal * new Vector3(0, lengthStep, 0)) * spline[i - 1].tangentGlobal;
                rotateAxis.Normalize();

                //旋转
                Quaternion quaternion = Quaternion.AngleAxis(noiseA[i], rotateAxis);
                spline[i].rotationGlobal = quaternion * spline[i].rotationGlobal;
                spline[i].tangentGlobal  = quaternion * spline[i].tangentGlobal;

                //处理当前结点截面的大小
                spline[i].radius = ((endRadius - startRadius) * (i / ((float)spline.Count)) + startRadius) * Random.Range(0.9f, 1.1f);
            }
        }