x


Recursive Tree Loop? How do i make the matrix-array?

I would like to make fractal tree in Unity3d, omitting branch angles and lengths, just to instantiate cubes as a tree, like 2,4,8,16... i look for solution all day and i figure it could take me days yet? Should i use an array to store and recall a list of coordinates that each new branch should be at? would it contain 2 or 16 values?

Here is an interactive JS code for trees: http://www.processing.org/learning/topics/tree.html

It uses the following code, please bypass the canvas, rotations, stalk length, i'd be so happy to just have a tree like in the image.

  branch(120);

}

void branch(float h) {
// Each branch will be 2/3rds the size of the previous one
h *= 0.66;

// All recursive functions must have an exit condition!!!!
// Here, ours is when the length of the branch is 2 pixels or less
if (h > 2) {
pushMatrix();    // Save the current state of transformation (i.e. where are we now)
rotate(theta);   // Rotate by theta
line(0, 0, 0, -h);  // Draw the branch
translate(0, -h); // Move to the end of the branch
branch(h);       // Ok, now call myself to draw two new branches!!
popMatrix();     // Whenever we get back here, we "pop" in order to restore the previous matrix state

// Repeat the same thing, only branch off to the "left" this time!
pushMatrix();
rotate(-theta);
line(0, 0, 0, -h);
translate(0, -h);
branch(h);
popMatrix();

} }

alt text

here is my funny attempt thus far:

var bullet : Transform;
private var rot : Quaternion;

function Start()
{
for (var j : float = 0; j<10; j++)
{
for (var i : float = 0; i<10; i++)
{
    rot.eulerAngles = Vector3(0,10,0);//Rotation to use with instatiation 
    var InstantiateObject = Instantiate(bullet, Vector3(Mathf.Sin(i*432)*i*j,j*5,Mathf.Cos(i*4375)*i*j), rot);//call clones
    InstantiateObject.localScale += Vector3(25-j*2,22-j*2,22-j*2);//resize clones

}

}
}
more ▼

asked Jul 21 '11 at 12:11 AM

vestax_ion gravatar image

vestax_ion
61 14 19 19

(comments are locked)
10|3000 characters needed characters left

3 answers: sort voted first

Try this as a staring point:

public class CubeSpawn : MonoBehaviour 
{
    public GameObject cubePrefab;
    public GameObject root;

    private Vector3[] CORNERS = 
    {
        new Vector3(-1, 1, -1),
        new Vector3(-1, 1, 1),
        new Vector3(1, 1, 1),
        new Vector3(1, 1, -1),
    };

    public void Start()
    {
        AddChildren(root, 0.5f, 5);
    }

    public void AddChildren(GameObject parent, float childToParentRatio, int depth)
    {


        foreach (Vector3 corner in CORNERS)
        {
            GameObject cube = (GameObject) Instantiate(cubePrefab);
            Vector3 newPosition = parent.transform.TransformPoint(corner * 0.5f);

            //align parent and child
            cube.transform.rotation = parent.transform.rotation;

            cube.transform.position = newPosition;
            cube.transform.localScale *= childToParentRatio;

            if(depth > 0)
            {
                AddChildren(cube, childToParentRatio * childToParentRatio, depth - 1);
            }
        }



    }

    public Vector3 prod(Vector3 v1, Vector3 v2)
    {
        return new Vector3(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z);
    }
}

Put the script on an empty game object. Drag in the parent (you can modify it later to instantiate or whatever), and drag in your cube prefab.

The function above is called recursively on the new corners; the depth value makes sure it is not called indefinitely.

more ▼

answered Jul 21 '11 at 07:27 AM

Herman Tulleken gravatar image

Herman Tulleken
1.6k 25 36 56

Thankyou so much! That's very interesting. i will take a long while to understand and tailor it for other shapes now. I had to add the line "using UnityEngine;" at the top.

Jul 21 '11 at 09:39 AM vestax_ion

the childToParentRatio was scaling exponentially small so i changed line 37 to this: AddChildren(cube, childToParentRatio - (childToParentRatio /2), depth - 1);

because otherwise you could only see the first 3 rows although it would make more sense to write:

            AddChildren(cube, childToParentRatio - (childToParentRatio *.6), depth - 1); 

but it wouldnt let me! CubeSpawn.AddChildren(UnityEngine.GameObject, float, int)' Argument#2' cannot convert double' expression to typefloat'

so it's saying 0.6 is a double not a float? so i have to declare a var as a float and then say it is 0.6? ok i get it. brb ;)

Jul 21 '11 at 10:38 AM vestax_ion

For float literals, just put an f, for example, 0.6f.

Jul 21 '11 at 11:26 AM Herman Tulleken

what is the most computationally efficient way to use such a structure in Unity3d? should "combine mesh" to reduce draw calls, should i do some postprocessing to cull hiddent vertexes and objects? I was only just beginning JS, even instantiation seems very tricky in C#, i haven't yet managed to instantiate the central parent cube.

Jul 21 '11 at 04:55 PM vestax_ion

I think you may want to ask a separate question for that; I am not a 3D model optimisation guru :P.

Jul 24 '11 at 07:02 PM Herman Tulleken
(comments are locked)
10|3000 characters needed characters left

Here is a JS version of your C# script:

var cubePrefab: GameObject ;
var root : GameObject ;

private var corners = new Array (Vector3(-1, 1, -1), Vector3(-1, 1, 1),Vector3(1, 1, 1),Vector3(1, 1, -1));

function Start()
{
    var root = Instantiate(cubePrefab,Vector3.zero,Quaternion.identity);
    AddChildren( root,0.5, 4);
}

function AddChildren( ploppy, ratio ,depth)
{


    for (var x = 0; x < 4; x++) 
    {         
        var cube = Instantiate(cubePrefab,Vector3.zero,Quaternion.identity);


        //align parent and child
        //cube.transform.rotation = prt.transform.rotation;

        cube.transform.position = ploppy.transform.TransformPoint(corners[x]*.5);
        cube.transform.localScale *= ratio;

        if(depth > 0)
        {
            AddChildren( cube, ratio - (ratio*.6) , depth - 1);
        }
    }



}
more ▼

answered Sep 06 '11 at 05:19 PM

vestax_ion gravatar image

vestax_ion
61 14 19 19

(comments are locked)
10|3000 characters needed characters left

There is some info and a source project to draw reference from here http://tonydincau.com/fractal-trees/

more ▼

answered Feb 01 at 08:15 AM

tonydincau gravatar image

tonydincau
1

(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x1359
x294
x228
x81
x15

asked: Jul 21 '11 at 12:11 AM

Seen: 1197 times

Last Updated: Feb 01 at 08:15 AM