Esempio n. 1
0
    void CreateTree()
    {
        if (oldSeed == null)
        {
            oldSeed = new Seed();
            oldSeed.InitBranch();
        }

        // If seed hasn't changed return;
        if (Seed.CompareSeeds(oldSeed, seed))
        {
            return;
        }

        if (seed.randomSeedFromObjectHash)
        {
            int hash = this.transform.GetHashCode();
            if (hash != seed.randomSeed)
            {
                seed.randomSeed = hash;
            }
        }

        Seed.CopySeedDataIntoOtherSeed(oldSeed, seed);

        //FIX: Might be for the better reduce function calls
        seed.InitBranch();

        BranchRung firstTreeRung = new BranchRung {
            pos = ZERO,
            rot = new Vector2(
                -transform.localEulerAngles.z * Mathf.Deg2Rad,
                transform.localEulerAngles.x * Mathf.Deg2Rad)
        };

        List <Branch> allBranches = new List <Branch>();

        // This draws whole Tree
        Branch tree = new Branch(firstTreeRung, seed, allBranches);

        // 3D Model Logic:
        DrawTreeDModel(allBranches);
    }
Esempio n. 2
0
    public Branch(BranchRung baseRung, Seed seed, List <Branch> root, Seed originalSeed = null)
    {
        if (originalSeed == null)
        {
            originalSeed = seed;
        }
        core = new List <BranchRung>();
        root.Add(this);
        randomGen = new System.Random(seed.randomSeed);
        int   branchSeed             = randomGen.Next();
        int   rungNum                = Mathf.CeilToInt(seed.growth);
        float rungSize               = seed.rungSize + (seed.growth * Seed.RUNG_VS_GROWTH_SIZE);
        float rungNumFloatDifference = seed.growth - (float)rungNum;
        float treeRadius             = seed.treeRadius * seed.growth * .01f;;
        float treeSegments           = Mathf.Round(seed.radialSegments * treeRadius);

        if (treeSegments < 3)
        {
            treeSegments = 3;
        }

        float treeScale = 1 / (rungNum * Seed.RUNG_CLOSENESS);

        branchShape     = new System.Random(branchSeed);
        branchGenerator = new System.Random(branchSeed);
        core.Add(baseRung);

        //Accessing first branch
        BranchRung rootBranch = root[0].core[0];

        for (int i = 1; i < rungNum; i++)
        {
            BranchRung prevRung     = core[i - 1];
            BranchRung rung         = new BranchRung();
            var        percInBranch = 1 - ((float)i / (float)rungNum);

            //init
            rung.ringData = new List <Vector3>();

            // Twisting the branch randomly
            var rndX = ((float)branchShape.NextDouble());
            var rndY = ((float)branchShape.NextDouble());
            rung.rot.x = prevRung.rot.x + (seed.halfTwistX - seed.twistX * rndX);
            rung.rot.y = prevRung.rot.y + (seed.halfTwistY - seed.twistY * rndY);

            // Straightening up the branch, otherwise it will look like sea weed.
            if (seed.correctiveBehavior != 0)
            {
                rung.rot.x += (rootBranch.rot.x - rung.rot.x) * seed.correctiveBehavior;
                rung.rot.y += (rootBranch.rot.y - rung.rot.y) * seed.correctiveBehavior;
            }
            if (seed.straightness != 0)
            {
                rung.rot.x += (baseRung.rot.x - rung.rot.x) * seed.straightness;
                rung.rot.y += (baseRung.rot.y - rung.rot.y) * seed.straightness;
            }

            // Creating new branch rung position
            var cosY  = Mathf.Cos(rung.rot.y);
            var cartX = (cosY * Mathf.Sin(rung.rot.x));
            var cartY = (cosY * Mathf.Cos(rung.rot.x));
            var cartZ = Mathf.Sin(prevRung.rot.y);
            rungSize  += (Seed.MIN_RUNG_SIZE - rungSize) * treeScale * Seed.RUNG_CLOSENESS;
            rung.pos.x = prevRung.pos.x + rungSize * cartX;
            rung.pos.y = prevRung.pos.y + rungSize * cartY;
            rung.pos.z = prevRung.pos.z + rungSize * cartZ;

            // TODO: FIX, randomizer is too random, use FI somehow.
            if (Mathf.RoundToInt(((float)branchGenerator.NextDouble()) * seed.branchHappening) == 0)
            {
                int newBranchSeed  = randomGen.Next();
                int leftOverGrowth = rungNum - i;
                fullUtilityRandom = new System.Random(newBranchSeed);

                // Randomizing branch direction from mother branch.
                var     newRandX     = 1f - (2f) * ((float)fullUtilityRandom.NextDouble());
                var     newRandY     = 1f - (2f) * ((float)fullUtilityRandom.NextDouble());
                Vector2 newDirection = rung.rot;
                newDirection.x += newRandX;
                newDirection.y += newRandY;
                rung.rot.x     -= newRandX * seed.branchSplitForced;
                rung.rot.y     -= newRandY * seed.branchSplitForced;

                // This ensures the pattern of random generators doesn't break.
                baseRung = rung;

                BranchRung newRung = new BranchRung {
                    pos = rung.pos,
                    rot = newDirection
                };
                var reduction         = .9f * percInBranch;
                var newRadialSegments = Mathf.RoundToInt(treeSegments * reduction);
                if (newRadialSegments < 3)
                {
                    newRadialSegments = 3;
                }
                var newRadius = treeRadius * reduction;
                if (newRadius < originalSeed.minRadius)
                {
                    newRadius = originalSeed.minRadius;
                }
                Seed newBranchOpts = new Seed {
                    twistX             = seed.twistX,
                    twistY             = seed.twistY,
                    correctiveBehavior = seed.correctiveBehavior,
                    randomSeed         = newBranchSeed,
                    branchHappening    = seed.branchHappening,
                    growth             = (leftOverGrowth + rungNumFloatDifference) * (1 - .61802f),

                    //TODO: FIX, dir does nothing
                    growthDirection = Vector3.zero,

                    treeRadius     = newRadius,
                    radialSegments = newRadialSegments
                };

                newBranchOpts.rungSize = rungSize;
                newBranchOpts.InitBranch();
                Branch newBranch = new Branch(newRung, newBranchOpts, root, originalSeed);
            }

            core.Add(rung);
        }

        var branchSize = core.Count;

        for (int i = 0; i < branchSize; i++)
        {
            float      percInBranch = 1 - ((float)i / (float)branchSize);
            BranchRung rung         = core[i];
            rung.ringData = new List <Vector3>();
            for (int a = 0; a < treeSegments; a++)
            {
                var aF         = (float)a;
                var segmentsF  = (float)treeSegments;
                var pieceAngle = (aF / segmentsF) * Mathf.PI * 2;

                var currentAngleX = -rung.rot.x;
                var currentAngleZ = rung.rot.y;
                var x             = Mathf.Cos(pieceAngle) * treeRadius * percInBranch;
                var z             = Mathf.Sin(pieceAngle) * treeRadius * percInBranch;
                var cosX          = Mathf.Cos(currentAngleX);
                var sinX          = Mathf.Sin(currentAngleX);
                var cosZ          = Mathf.Cos(currentAngleZ);
                var sinZ          = Mathf.Sin(currentAngleZ);

                var Axz = sinX * sinZ;
                var Ayz = -cosX * sinZ;
                var Azz = cosZ;

                var projectX = cosX * x + Axz * z;
                var projectY = sinX * x + Ayz * z;
                var projectZ = Azz * z;

                Vector3 vert = new Vector3 {
                    x = projectX,
                    y = projectY,
                    z = projectZ
                };
                rung.ringData.Add(vert);
            }
        }
    }
Esempio n. 3
0
    void DrawTreeDModel(List <Branch> branches)
    {
        // FIX: Change to regular [] arrays.
        List <Vector3> vertexList = new List <Vector3>();
        List <Vector2> uvs        = new List <Vector2>();
        List <int>     trisList   = new List <int>();

        int branchNum   = branches.Count;
        int vertexSoFar = 0;

        for (int i = 0; i < branchNum; i++)
        {
            List <BranchRung> branch = branches[i].core;
            var rungNum     = branch.Count;
            var segmentsNum = 0;
            for (int a = 0; a < rungNum; a++)
            {
                BranchRung rung = branch[a];
                segmentsNum = rung.ringData.Count;

                var rungId  = segmentsNum * (a - 1);
                var rungIdU = segmentsNum * (a);
                if (a > 0)
                {
                    var lowL = rungId + vertexSoFar + segmentsNum - 1;
                    var lowR = rungId + vertexSoFar;
                    var upL  = rungIdU + vertexSoFar + segmentsNum - 1;
                    var upR  = rungIdU + vertexSoFar;

                    // tri 1
                    trisList.Add(upL);
                    trisList.Add(lowR);
                    trisList.Add(lowL);

                    // tri 2
                    trisList.Add(upL);
                    trisList.Add(upR);
                    trisList.Add(lowR);
                }

                // Closing the 3D model
                for (int u = 0; u < segmentsNum; u++)
                {
                    var vert = rung.ringData[u] + rung.pos;
                    vertexList.Add(vert);

                    // Tris are entirely ID based this is valid
                    if (a > 0 && u > 0)
                    {
                        var lowL = rungId + vertexSoFar + u - 1;
                        var lowR = rungId + vertexSoFar + u;
                        var upL  = rungIdU + vertexSoFar + u - 1;
                        var upR  = rungIdU + vertexSoFar + u;

                        // tri 1
                        trisList.Add(upL);
                        trisList.Add(lowR);
                        trisList.Add(lowL);

                        // tri 2
                        trisList.Add(upL);
                        trisList.Add(upR);
                        trisList.Add(lowR);
                    }
                    if (showGizmos)
                    {
                        Gizmos.DrawCube(vert, Vector3.one * 0.03f);
                    }
                }
                if (showGizmos)
                {
                    if (a > 0)
                    {
                        BranchRung prevRung = branch[a - 1];
                        Gizmos.DrawLine(prevRung.pos, rung.pos);
                    }
                }
            }
            vertexSoFar = vertexList.Count;

            if (showGizmos)
            {
                var r = (float)colorRandomizerForGizmos.NextDouble();
                var g = (float)colorRandomizerForGizmos.NextDouble();
                var b = (float)colorRandomizerForGizmos.NextDouble();
                Gizmos.color = new Vector4(r, g, b, 1);
            }
        }

        // TEMP: FIX: Convert lists to Arrays, temporary.
        Vector3[] verts = new Vector3[vertexSoFar];
        for (int i = 0; i < vertexSoFar; i++)
        {
            verts[i] = vertexList[i];
        }
        int triCount = trisList.Count;

        int[] tris = new int[triCount];
        for (int i = 0; i < triCount; i++)
        {
            tris[i] = trisList[i];
        }

        //FIX: Check garbage collector, meshes are a mess.
        // Mesh times, create mesh access filter and renderer.
        MeshFilter   meshFilter   = GetComponent <MeshFilter>() as MeshFilter;
        MeshRenderer meshRenderer = GetComponent <MeshRenderer>() as MeshRenderer;

        treeMesh           = new Mesh();
        treeMesh.vertices  = verts;
        treeMesh.triangles = tris;
        //treeMesh.uv = uvs; //not yet

        meshFilter.mesh = treeMesh;
        treeMesh.RecalculateBounds();
        treeMesh.RecalculateNormals();
    }