예제 #1
0
        private static List <BranchArmature> CreateBranches(int count, TreeArmature armature)
        {
            var branches = new List <BranchArmature>();

            var trunkSize             = armature.trunkVertices.Count;
            var branchPointCandidates = new List <int>();

            for (var i = 0; i < trunkSize; i++)
            {
                if (i > Mathf.RoundToInt(trunkSize * .33f) && i < trunkSize - Mathf.RoundToInt(trunkSize * .1f))
                {
                    branchPointCandidates.Add(i);
                }
            }

            // Find highest value for normalizing
            var max = branchPointCandidates.Max();

            // Select #count branch points on tree
            var branchPoints = new List <int>(count);

            do
            {
                for (var i = 0; i < branchPointCandidates.Count && branchPoints.Count < count; i++)
                {
                    var branchPoint = branchPointCandidates[i];
                    var chance      = (float)branchPoint / max * .75f;
                    if (Random.value < chance)
                    {
                        if (!branchPoints.Contains(branchPoint))
                        {
                            branchPoints.Add(branchPoint);
                        }
                    }
                }
            } while (branchPoints.Count != count);

            foreach (var branchPoint in branchPoints)
            {
                var branchOrigin = armature.trunkVertices[branchPoint];
                var branch       = CreateBranchArmature(branchOrigin, trunkSize - 1 - branchPoint - Mathf.RoundToInt(trunkSize * .1f), armature.SegmentHeight, armature.variance);
                branch.RotateVertices(branchOrigin, Quaternion.Euler(0, Random.Range(0, 360), Random.value * armature.variance));

                branches.Add(new BranchArmature {
                    branchVertices    = branch,
                    branchVertexIndex = branchPoint
                });
            }

            armature.branches = branches;

            return(branches);
        }
        private void Update()
        {
            if (armature != TreeMeshGenerator.Armature)
            {
                armature = TreeMeshGenerator.Armature;

                if (!keepChildren)
                {
                    foreach (Transform obj in transform)
                    {
                        Destroy(obj.gameObject);
                    }
                }

                var lines = new List <List <Vector3> > {
                    armature.trunkVertices
                };
                armature.branches?.ForEach(branch => lines.Add(branch.branchVertices));

                var i = 0;
                foreach (var vertList in lines)
                {
                    var obj = new GameObject($"branch{i}");
                    obj.transform.SetParent(transform, false);

                    var gen = new MeshGenerator();
                    gen.AddVertices(vertList);

                    var mf = obj.AddComponent <MeshFilter>();
                    mf.sharedMesh = gen.GetMesh($"branch{i}");

                    obj.AddComponent <MeshRenderer>();

                    var vis = obj.AddComponent <NormalVisualiser>();
                    vis.drawLines            = true;
                    vis.showGizmos           = true;
                    vis.showMeshInfoOnSelect = false;
                    i++;
                }
            }
        }
예제 #3
0
        public static Mesh CreateTree(int vertCount, float radius, float height, int subdivisions, float variance, int branchCount)
        {
            var meshGen = new MeshGenerator();

            var armature = CreateArmature(subdivisions, height, variance);
            var branches = CreateBranches(branchCount, armature);

            armature.branches = branches;
            Armature          = armature;

            // Trunk
            {
                // Create trunk edge loops
                var edgeloops = new List <List <Vector3> >(armature.trunkVertices.Count);
                for (var i = 0; i < armature.trunkVertices.Count; i++)
                {
                    var circle = CreateCircle(vertCount, radius * Mathf.Sqrt(1 - (float)i / subdivisions), armature.trunkVertices[i]);
                    edgeloops.Add(circle);
                    meshGen.AddVertices(circle);
                }

                // Bridge trunk edge loops
                for (var i = 0; i < subdivisions; i++)
                {
                    meshGen.BridgeEdgeLoops(edgeloops[i], edgeloops[i + 1]);
                }
            }

            // Branches
            {
                foreach (var branch in branches)
                {
                    var divisions = branch.branchVertices.Count - 1;

                    var edgeloops = new List <List <Vector3> >(branch.branchVertices.Count);
                    for (var i = 0; i < branch.branchVertices.Count; i++)
                    {
                        var branchPointRadius = radius * Mathf.Sqrt(1 - (float)branch.branchVertexIndex / subdivisions);
                        var circle            = CreateCircle(vertCount, branchPointRadius * .7f * Mathf.Sqrt(1 - (float)i / divisions), branch.branchVertices[i]);

                        Vector3 rotationDir;
                        if (i == 0 || i == branch.branchVertices.Count - 1)
                        {
                            rotationDir = branch.branchVertices[i];
                        }
                        else
                        {
                            rotationDir = branch.branchVertices[i - 1] + branch.branchVertices[i];
                        }

                        circle.RotateVertices(branch.branchVertices[i], Quaternion.LookRotation(rotationDir, Vector3.down));

                        edgeloops.Add(circle);
                        meshGen.AddVertices(circle);
                    }

                    // Bridge edge loops
                    for (var i = 0; i < divisions; i++)
                    {
                        meshGen.BridgeEdgeLoops(edgeloops[i], edgeloops[i + 1]);
                    }
                }
            }

            var mesh = meshGen.GetMesh("Tree");

            mesh.RecalculateNormals();

            return(mesh);
        }