Esempio n. 1
0
    private void OnSceneGUI()
    {
        spline          = target as MtreeBezier;
        handleTransform = spline.transform;
        handleRotation  = Tools.pivotRotation == PivotRotation.Local ?
                          handleTransform.rotation : Quaternion.identity;

        Vector3 p0 = ShowPoint(0);

        if (spline.points.Length > 3)
        {
            for (int i = 1; i < spline.ControlPointCount; i += 3)
            {
                Vector3 p1 = ShowPoint(i);
                Vector3 p2 = ShowPoint(i + 1);
                Vector3 p3 = ShowPoint(i + 2);

                Handles.color = Color.gray;
                Handles.DrawLine(p0, p1);
                Handles.DrawLine(p2, p3);

                Handles.DrawBezier(p0, p3, p1, p2, Color.white, null, 2f);
                p0 = p3;
            }
        }
    }
Esempio n. 2
0
    public void BezierManager()
    {
        if (hasBezier == 1)
        {
            mtreeBezier = gameObject.AddComponent <MtreeBezier> ();
            mtreeBezier.MTreeDoBezier = true;
            GenerateTree();
        }
        if (mtreeBezier == null)
        {
            mtreeBezier = GetComponent <MtreeBezier> ();
        }

        if (hasBezier == 0 && mtreeBezier != null)
        {
            mtreeBezier.MTreeDoBezier      = false;
            mtreeBezier.MTreeLeafDirection = false;
            DestroyImmediate(mtreeBezier);
            GenerateTree();
        }
    }
Esempio n. 3
0
        public void AddTrunk(Vector3 position, Vector3 direction, float length, AnimationCurve radius, float radiusMultiplier, float resolution
                             , float randomness, int creator, AnimationCurve rootShape, float rootRadius, float rootHeight, float RootResolutionMultiplier
                             , float originAttraction)
        {
            MtreeBezier bezier          = treeTransform.GetComponent <MtreeBezier>();
            float       remainingLength = length;
            Node        extremity       = new Node(position, radius.Evaluate(0) * radiusMultiplier, direction, creator, NodeType.Flare);

            stems.Add(extremity);

            if (!bezier || bezier && !bezier.MTreeDoBezier)
            {
                while (remainingLength > 0)
                {
                    float    res     = resolution;
                    NodeType type    = NodeType.Trunk;
                    Vector3  tangent = Vector3.Cross(direction, Random.onUnitSphere);
                    if (length - remainingLength < rootHeight)
                    {
                        tangent /= RootResolutionMultiplier * 2;
                        res     *= RootResolutionMultiplier;
                        type     = NodeType.Flare;
                    }

                    float   branchLength           = 1f / res;
                    Vector3 dir                    = randomness * tangent + extremity.direction * (1 - randomness);
                    Vector3 originAttractionVector = (position - extremity.position) * originAttraction;
                    originAttractionVector.y = 0;
                    dir += originAttractionVector;
                    dir.Normalize();
                    if (remainingLength <= branchLength)
                    {
                        branchLength = remainingLength;
                    }
                    remainingLength -= branchLength;

                    Vector3 pos = extremity.position + dir * branchLength;
                    float   rad = radius.Evaluate(1 - remainingLength / length) * radiusMultiplier;
                    //if (length - remainingLength < rootHeight)
                    //    rad += radiusMultiplier * rootRadius * rootShape.Evaluate((length - remainingLength) / rootHeight);
                    Node child = new Node(pos, rad, dir, creator, type, distancToOrigin: length - remainingLength);
                    extremity.children.Add(child);
                    extremity = child;
                }
            }

            if (bezier && bezier.MTreeDoBezier)
            {
                length          = bezier.GetLength();
                remainingLength = length;
                while (remainingLength > 1f / resolution)
                {
                    float   step    = 1 - (remainingLength / length);
                    Vector3 stepDir = bezier.GetDirection(step);
                    Vector3 stepPos = bezier.GetPoint(step) - treeTransform.position;

                    float    res     = resolution;
                    NodeType type    = NodeType.Trunk;
                    Vector3  tangent = Vector3.Cross(direction, Random.onUnitSphere);
                    if (length - remainingLength < rootHeight)
                    {
                        tangent /= RootResolutionMultiplier * 2;
                        res     *= RootResolutionMultiplier;
                        type     = NodeType.Flare;
                    }

                    float   branchLength           = 1f / res;
                    Vector3 dir                    = randomness * tangent + stepDir * (1 - randomness);
                    Vector3 originAttractionVector = (position - stepPos) * originAttraction;
                    originAttractionVector.y = 0;
                    dir += originAttractionVector;
                    dir.Normalize();
                    if (remainingLength <= branchLength)
                    {
                        branchLength = remainingLength;
                    }
                    remainingLength -= branchLength;

                    Vector3 pos = stepPos + dir * branchLength;
                    float   rad = radius.Evaluate(1 - remainingLength / length) * radiusMultiplier;
                    //if (length - remainingLength < rootHeight)
                    //    rad += radiusMultiplier * rootRadius * rootShape.Evaluate((length - remainingLength) / rootHeight);
                    Node child = new Node(pos, rad, dir, creator, type, distancToOrigin: length - remainingLength);
                    extremity.children.Add(child);
                    extremity = child;
                }
            }
        }
Esempio n. 4
0
        public void Split(int selection, int expectedNumber, float splitAngle, int creator, float splitRadius, float startLength
                          , float spread, float flatten)
        {
            Queue <Node> candidates = GetSplitCandidates(selection, startLength);
            MtreeBezier  bezier = treeTransform.GetComponent <MtreeBezier>(); Vector3 direction = Vector3.zero;

            if (bezier && bezier.MTreeLeafDirection)
            {
                direction = bezier.s_branchdirection;
            }

            float totalLength = 0;

            foreach (Node ext in candidates)
            {
                totalLength += (ext.position - ext.children[0].position).magnitude;
            }

            float splitPerMeter = expectedNumber / totalLength;

            float remainder = 0f;

            foreach (Node ext in candidates)
            {
                float distToChild = (ext.position - ext.children[0].position).magnitude;

                float targetSplitNumber = distToChild * splitPerMeter + remainder;
                int   number            = (int)targetSplitNumber;
                remainder = targetSplitNumber - number;

                Vector3 randomVect = Random.onUnitSphere;
                if (flatten > 0)
                {
                    randomVect = Vector3.Lerp(randomVect, Vector3.up, flatten).normalized *(Random.Range(0, 1) * 2 - 1);
                }
                Vector3    tangent         = Vector3.Cross(randomVect, ext.direction);
                Quaternion rot             = Quaternion.AngleAxis(360f / number, ext.direction);
                Vector3    spreadDirection = ext.children[0].direction;
                for (int i = 0; i < number; i++)
                {
                    float   blend        = Random.value * spread;
                    float   rad          = Mathf.Lerp(ext.radius * splitRadius, ext.children[0].radius * splitRadius, blend);
                    Vector3 pos          = ext.position + spreadDirection * blend * distToChild;
                    Vector3 dir          = Vector3.LerpUnclamped(ext.direction, tangent, splitAngle * (1 - ext.positionInBranch * .7f)).normalized + direction;
                    float   radiusFactor = Mathf.Clamp01(rad);
                    Node    child0       = new Node(pos, ext.radius * radiusFactor + rad * (1 - radiusFactor), dir, creator, distancToOrigin: ext.distanceFromOrigin + blend * distToChild);
                    child0.branchVariation = ext.branchVariation;
                    if (ext.type == NodeType.Trunk || ext.type == NodeType.Flare)
                    {
                        child0.type = NodeType.FromTrunk;
                    }
                    Node child1 = new Node(pos + dir * ext.radius / Mathf.Max(0.3f, Vector3.Dot(dir, tangent)) * 1f, rad, dir, creator, distancToOrigin: ext.distanceFromOrigin + blend * distToChild);
                    child1.branchVariation = ext.branchVariation;
                    child0.children.Add(child1);

                    child0.growth.canBeSplit = false;
                    ext.children.Add(child0);
                    tangent = rot * tangent;
                }
            }
        }
Esempio n. 5
0
    public override void OnInspectorGUI()
    {
        var gs = new GUIStyle();

        gs.fontStyle = FontStyle.Bold;

        spline = target as MtreeBezier;
        GUILayout.Space(10);
        EditorGUI.BeginChangeCheck();
        EditorGUILayout.LabelField("MTree Addon", gs);

        if (spline.MTreeDoBezier)
        {
            DoBezier = "Deactivate Bezier Mode";
        }
        else
        {
            DoBezier = "Activate Bezier Mode";
        }
        if (GUILayout.Button(DoBezier))
        {
            Undo.RecordObject(spline, DoBezier);
            spline.MTreeDoBezier = !spline.MTreeDoBezier;
            EditorUtility.SetDirty(spline);
        }
        if (GUILayout.Button("Add Curve"))
        {
            Undo.RecordObject(spline, "Add Curve");
            spline.AddCurve();
            EditorUtility.SetDirty(spline);
        }
        if (EditorGUI.EndChangeCheck())
        {
            spline.GetComponent <MtreeComponent>().GenerateTree();
        }
        GUILayout.Space(10);
        EditorGUI.BeginChangeCheck();
        EditorGUILayout.LabelField("Branch / Leaf Directions", gs);
        if (spline.MTreeLeafDirection)
        {
            DoLeaf = "Deactivate Leaf Direction Mode";
        }
        else
        {
            DoLeaf = "Activate Leaf Direction Mode";
        }
        if (GUILayout.Button(DoLeaf))
        {
            Undo.RecordObject(spline, DoLeaf);
            spline.MTreeLeafDirection = !spline.MTreeLeafDirection;
            EditorUtility.SetDirty(spline);
        }
        spline.s_branchdirection = EditorGUILayout.Vector3Field("Branch Growth Direction", spline.s_branchdirection);

        if (EditorGUI.EndChangeCheck())
        {
            spline.s_branchdirection.x = Mathf.Clamp(spline.s_branchdirection.x, -1, 1);
            spline.s_branchdirection.y = Mathf.Clamp(spline.s_branchdirection.y, -1, 1);
            spline.s_branchdirection.z = Mathf.Clamp(spline.s_branchdirection.z, -1, 1);
            Undo.RecordObject(spline, "Branch Growth Direction");
            spline.GetComponent <MtreeComponent>().GenerateTree();
            EditorUtility.SetDirty(spline);
        }
        GUILayout.Space(10);

        if (selectedIndex >= 0 && selectedIndex < spline.ControlPointCount)
        {
            EditorGUILayout.LabelField("Bezier Position / Mode", gs);
            DrawSelectedPointInspector();
        }
    }