Jump to content

Simple pine trees.


Recommended Posts

Hi everyone,

I made a  function to generate some simple, low-poly pine trees and thought i would share it with you all. 
Perhaps someone can use it.

->Playground<- (createTree is called at the bottom of the code section.)

The function allows both "strict" and "non-strict" size, where strict mode creates a specific size & thickness, and non-strict randomizes them slightly. 



    var createTree = function (name, x, y, z, sizeInput, strict, scene, woodMaterial, grassMaterial) {
        var size, l_height, l_width, trunk, leafs_1, leafs_2, leafs_3, leafs_4, leafs_5, leafs;
        if(strict){ //strict
            size = l_width = sizeInput;
            l_height = size * 0.2;
        } else { //randomize tree thickness & height, hopefully with realistic results.
            size = random(sizeInput * 0.80, sizeInput * 1.25);
            l_height = size * 0.2;
            l_width = random(size * 0.65, size * 1.1);
        trunk = BABYLON.Mesh.CreateCylinder(name + "trunk", 1, 1, 1, 12, 1, scene);
        trunk.scaling = new BABYLON.Vector3(l_width *0.2, size * 0.25, l_width *0.2);
        trunk.position = new BABYLON.Vector3(x, y + (trunk.scaling.y * 0.5), z);
        trunk.material = woodMaterial;

        leafs_1 = BABYLON.Mesh.CreateCylinder(name + "leafs", l_height, l_width * 0.5, l_width * 1.0, 6, 1, scene, false);
        leafs_1.position = new BABYLON.Vector3(x, y + (trunk.scaling.y * 0.5) + (l_height), z);
        leafs_1.material = grassMaterial;
        leafs_2 = BABYLON.Mesh.CreateCylinder(name + "leafs", l_height, l_width * 0.4, l_width * 0.85, 6, 1, scene, false);
        leafs_2.position = new BABYLON.Vector3(x, (leafs_1.position.y) + (l_height), z);
        leafs_2.material = grassMaterial;
        leafs_3 = BABYLON.Mesh.CreateCylinder(name + "leafs", l_height, l_width * 0.3, l_width * 0.65, 6, 1, scene, false);
        leafs_3.position = new BABYLON.Vector3(x, (leafs_2.position.y) + (l_height), z);
        leafs_3.material = grassMaterial;
        leafs_4 = BABYLON.Mesh.CreateCylinder(name + "leafs", l_height, l_width * 0.2, l_width * 0.50, 6, 1, scene, false);
        leafs_4.position = new BABYLON.Vector3(x, (leafs_3.position.y) + (l_height), z);
        leafs_4.material = grassMaterial;
        leafs_5 = BABYLON.Mesh.CreateCylinder(name + "leafs", l_height * 1.5, l_width * 0, l_width * 0.325, 6, 1, scene, false);
        leafs_5.position = new BABYLON.Vector3(x, (leafs_4.position.y) + (l_height * 1.25), z);
        leafs_5.material = grassMaterial;
        leafs = BABYLON.Mesh.MergeMeshes([leafs_1, leafs_2, leafs_3, leafs_4, leafs_5], true, false, false);

    function random(min, max)
        return Math.floor(Math.random()*(max-min+1)+min);



    var woodMaterial = new BABYLON.StandardMaterial(name, scene);
    var woodTexture = new BABYLON.WoodProceduralTexture(name + "text", 512, scene);
          woodTexture.ampScale = 50;
    woodMaterial.diffuseTexture = woodTexture;

    var grassMaterial = new BABYLON.StandardMaterial(name + "bawl", scene);
    var grassTexture = new BABYLON.GrassProceduralTexture(name + "textbawl", 512, scene);
          grassMaterial.ambientTexture = grassTexture;

    //create 5 strict and 5 non-strict trees
    for (var i = 0; i < 5; i++){
    var randx  = random(1, 25);
        randx *= random(1, 2) == 1 ? 1 : -1;
    var randz  = random(20, 20);
        randz *= random(1, 2) == 1 ? 1 : -1;

        /* createTree: Structure: 
        x pos, 
        y pos, 
        z pos, 
        size (1 size unit equals aproximately 1.2 babylon size units), 
        strict (true: Strict size & standard thickness, false: Randomize thickness & height, (based on size ofc)), 
        trunk material, 
        leaf material
        //Random placements
        //createTree("00" + i, randx, 0, randz, 10, false, scene, woodMaterial, grassMaterial);
        //createTree("00" + i, randx*2, 0, randz*2, 10, true, scene, woodMaterial, grassMaterial);
        //non-strict trees
        createTree("00" + i, 10, 0, -15 + (i *10), 10, false, scene, woodMaterial, grassMaterial);

        //Strict trees
        createTree("00" + i, -10, 0, -15 + (i *10), 10, true, scene, woodMaterial, grassMaterial);

Let me know what you think

Edited by aWeirdo
updated playground, reduced the number of sides on each cone to cut the vertice count down to aprox 1/2.
Link to comment
Share on other sites

Very nice!  That is my shortest drive ever... to get into the woods.  :)

You KNOW what the next step is, right?  Yep, Babylon tubes for tree trunks.  The abilities for tubes to have an easily-adjustable "path" of points to follow... makes them handy for random truck bends... and even bending with the wind.  Wow!  http://doc.babylonjs.com/tutorials/Parametric_Shapes and http://doc.babylonjs.com/tutorials/How_to_dynamically_morph_a_mesh and http://doc.babylonjs.com/tutorials/How_to_use_Path3D tell the story of tubes.

It's darned nice just the way it is, but line 14 is just BEGGING for a BABYLON.Mesh.CreateTube or a BABYLON.Mesh.ExtrudeShape .  Can you hear it?  I can.  :D   Nice work, aW, I love it!  This is one of the first steps to the "Build me a low-poly environment" button for the playground... similar to playground "themes".  Should be easy, considering @Pryme8 recently invented playground plugins;)  (See the extra playground button?)  We could make one for "Set Decorator" and put a choice on its menu called "Pine Me Up"   Yay!  Low-poly models are SO useful and so easily "set the mood" of scenes... for artists.

aW, your pine tree engine will surely power the "Give Me Woods NOW" choice.  *nod*

Link to comment
Share on other sites

haha thanks.

Does tubes allow "ends"? i was thinking about indexing the trees, fixing the trunk material with a multi material and the top("end") of the trunk looking cut over, then it's just a simple leafs.isVisible = false; and you have the basics for lumber-jacking^^
instead of having to hide the entire tree and loading a new trunk.

Link to comment
Share on other sites

Yeah, tubes do caps.  And they can variably taper... something not possible with the cone.  And, the whole tube/ribbon/extrude area of BJS... was written by @jerome... who is MISTER customize.  The path can easily be generated by a function hanging on the renderloop (live-animating/morphing).  So can the radius... easily "custom function".  The stuff is SO friggin' versatile... and there is SO many power-explained playground examples... that you are gonna crap a log.  ;)  Jerome writes thorough docs and thorough systems.  You're in for a treat, but it will take a bit of time to get the feel of it.

Link to comment
Share on other sites

hehe... @jerome is being a goofball.  :) 

Just the trunks, aW.  Jerome, remember your "grass in the wind" demo you did with linesMesh?  The same can be done with 20-50 tubes, right?  I'm thinkin' 7-sided... but plenty of vertical subdivisions, so we see a nice smooth arc as the tubes bend in the wind.  Let's go, hop to it, J... help aW get some wobbly trees.  :)  (if ya want) 

After we get "the woods", then we'll add "the hoods".  I'm thinkin' Robin Hood, or Little Red Riding Hood.  Both stories need a forest.  Maybe we'll mix the two stories... a father (Robin) and his long-lost daughter (LittleRedRiding)... reunited... but she is rich (home healthcare work)... and Robin... robs from the rich.  Wolf-lawyers get involved, and it becomes a big drama at Grandma's house.  Coooool.

Link to comment
Share on other sites

This is cool, but you should try to save on the number of draw calls, clone will be your fiend here...

you could create the initial Cyl, and then clone it a set number of times with the scale of the first one set down a certain amount and then just loop through that cloning with the next clones parent being set to the last, and you will be able to make the trees way faster and have a ton less draw calls...

Also you could add a randomness to the scaling of the initial clone and that will give you randomness to your trees falloff taper.

Awesome prototype though!  It would be cool to see this be callable on a ground object with a growth vector and angular restraints!


another method would be to extrude a circle with a sawtooth calculation for scale.

Link to comment
Share on other sites

Jerome hit the head of the nail right there, the control aloud by using a saw tooth algorithm and some 3d noise will be the solution to get the best results.  Then the next step is to add some simple L-System Rules and you will be able to do different species, and variations of them.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...