JavaScript - Library (Available on WebRepo)

…that seems the easiest way to me, and it’s what I do in my original project (albeit with lousy original data). :wink:

I’d try to do it here too but I just don’t understand how to get the vertex data out of the JS environment in your code.

Also btw the following settings generate the tree in the attached image:


                    var myTree = new Tree({ //values in comments are originals
                        "seed": 11104, //262
                        "segments": 10, //6
                        "levels": 4, //8
                        "vMultiplier": 2.6, //2.36
                        "twigScale": 0.29, //0.39
                        "initalBranchLength": 0.69, //0.49
                        "lengthFalloffFactor": 1.2, //0.855
                        "lengthFalloffPower": 0.09, //0.99
                        "clumpMax": 0.464, //0.454
                        "clumpMin": 0.430, //0.404
                        "branchFactor": 8.45, //2.45
                        "dropAmount": -0.01,
                        "growAmount": 0.435, //0.235
                        "sweepAmount": 0.01,
                        "maxRadius": 0.19, //0.139
                        "climbRate": 0.471, //0.371
                        "trunkKink": 0.09, //0.093
                        "treeSteps": 6, //5
                        "taperRate": 0.97, //0.947
                        "radiusFalloffRate": 0.615, //0.73
                        "twistRate": 3.02,
                        "trunkLength": 4.1 //2.4
                    });

@UberGoober These are the attributes?

thes for trunk:

myTree.verts;
myTree.faces;
myTree.normals;
myTree.UV;

these for leaves:

myTree.vertsTwig;
myTree.normalsTwig;
myTree.facesTwig;
myTree.uvsTwig;

I don’t actually use these vertices, normals, outside of JS code, but I still use a three.js-encapsulated OpenGLES method in JS to generate the mesh.

? I’m confused.

You generate those values, but you don’t actually use them?

Why do you generate them then? And what do you use instead of them?

@UberGoober I mean, I use this data in my javascript environment, not out of js environment.

@binaryblues first, thanks for all your investigations here, it’s brilliant.

I’ve tried to make a project that only runs the ProcTree code so I can get at those attributes, but it crashes.

It’s super short, can you tell me where I’m going wrong?

@UberGoober I made a few changes to remove the unnecessary code and added a few that are now working and can be displayed in Codea’s mesh, as follows:

-- LuaProcTree via bb

function main()
    local webview = WebView()
    
    webview:loadJS(ProcTree)
    webview:loadJS(MakeTree)
    
    local result = webview:call("makeTree")    
    local verts,faces,normals,UV = result[1],result[2],result[3],result[4]
    local vertsTwig,facesTwig,normalsTwig,UVTwig = result[5],result[6],result[7],result[8]
  
    ---[[ 
    saveText(asset.documents.."verts.txt",json.encode(verts))
    saveText(asset.documents.."faces.txt",json.encode(faces))
    saveText(asset.documents.."normals.txt",json.encode(normals))
    saveText(asset.documents.."UV.txt",json.encode(UV))
    
    saveText(asset.documents.."vertsTwig.txt",json.encode(vertsTwig))
    saveText(asset.documents.."facesTwig.txt",json.encode(facesTwig))
    saveText(asset.documents.."normalsTwig.txt",json.encode(normalsTwig))
    saveText(asset.documents.."UVTwig.txt",json.encode(UVTwig))
    --]]
    
    local v,n,uv = convert(verts,normals,UV)
    local f = convertFaces(faces)
    myTreeTrunkMesh = mesh()
    myTreeTrunkMesh.vertices = newVerts(v,f)
    myTreeTrunkMesh.normals = n
    myTreeTrunkMesh.texCoords = uv
    myTreeTrunkMesh:setColors(color(103, 99, 41))
    
   
    local v1,n1,uv1 = convert(vertsTwig, normalsTwig, UVTwig)
    local f1 = convertFaces(facesTwig)
    myTreeTwigMesh = mesh()
    myTreeTwigMesh.vertices = newVerts(v1,f1)
    myTreeTwigMesh.normals = n1
    myTreeTwigMesh.texCoords = uv1
    myTreeTwigMesh:setColors(color(73, 254, 3))
    
    pushMatrix()
    -- background(0)
    translate(WIDTH/2, HEIGHT/2)
    scale(100, 100, 100)

    myTreeTrunkMesh:draw()
    myTreeTwigMesh:draw()
    
    popMatrix()
end

function newVerts(v,f)
    local newV = {}
    for i=1,#f do
        local index = f[i]
        table.insert(newV, v[index])
    end
    return newV
end

function convert(verts, normals, UV)
    local v,n,uv = {},{},{}
    for i=1,#verts do
        local x,y,z =verts[i][1], verts[i][2], verts[i][3]
        local n1,n2,n3 = normals[i][1], normals[i][2], normals[i][3]
        local u1,v1 = UV[i][1], UV[i][2]      
        table.insert(v,vec3(x,y,z))
        table.insert(n, vec3(n1,n2,n3))
        table.insert(uv,vec2(u1,v1))
    end
    return v,n,uv
end

function convertFaces(faces)
    local f = {}
    for i=1,#faces do
        local x1,y1,z1 = faces[i][1]+1, faces[i][2]+1, faces[i][3]+1
        table.insert(f,x1)
        table.insert(f,y1)
        table.insert(f,z1)
    end
    return f
end

MakeTree = [[
function makeTree(){
        var t = new Tree({
            "seed":252,
            "segments":6,
            "levels":5,
            "vMultiplier":1.16,
            "twigScale":0.39,
            "initalBranchLength":0.49,
            "lengthFalloffFactor":0.85,
            "lengthFalloffPower":0.99,
            "clumpMax":0.454,
            "clumpMin":0.454,
            "branchFactor":3.2,
            "dropAmount":0.09,
            "growAmount":0.235,
            "sweepAmount":0.051,
            "maxRadius":0.105,
            "climbRate":0.322,
            "trunkKink":0,
            "treeSteps":5,
            "taperRate":0.964,
            "radiusFalloffRate":0.73,
            "twistRate":1.5,
            "trunkLength":2.25,
            "trunkMaterial":"texture1",
            "twigMaterial":"BranchType2"
        	});
        return [t.verts, t.faces, t.normals, t.UV, t.vertsTwig, t.facesTwig, t.normalsTwig, t.uvsTwig];
    }
]]

https://youtu.be/wzin8wtbPT4

@binaryblues wow you do this stuff so fast.

I’ve tried to use your latest iteration to convert the mesh into a Craft model—I got
mixed results, as can be seen in the attached project.

The leaves (for some reason called twigs?) seem to have come out right but the tree and branches came out incomplete.

@UberGoober Good Job!

I tried to draw it in craft too. However, there were some problems, mainly the vertex order and some errors caused by changing the index value range from 0 to 1.

Btw. this project need the mesh data(vertices,normals etc.) generated from the last project(LuaProcTree new.zip) in this post, so you need to run it first to save the mesh data into assets.documents.

https://youtu.be/TJpa1mJGJiA

@binaryblues thanks but you seem to have done much better than I did. I used @LoopSpace’s PseudoMesh routines to handle the re-indexing but mine ended up looking much worse.

The project you just posted crashes on my iPhone 8 btw.

@binaryblues …ah, the problem was missing assets.

I’ve made a slight adjustment to your project so it now uses available assets plus a leaf texture included in the project itself.

Btw I can’t figure out how to mess with the parameters—there seem to be three different places in the code where all the tree parameters are listed, but I don’t see any changes from fiddling with any of them—which is the one the actual model is using?

@UberGoober @binaryblues My apologies for not being around recently, my personal life has had some changes so I haven’t been around quite as much.

I just wanted to say this is looking fantastic and it’s great to see the library being put to use already! :smile:

@UberGoober I’ve added a few caveats to make it clear.

If you’re using readText() to get mesh data, it’s the parameters from the previous javascript, and if you’re using Tree() from the ProcTreeLua tab, it’s the parameters from the code:

    -- print(round(5.5))
    myTree = Tree({
        seed =262,
        segments= 8,
        levels= 5,
        vMultiplier= 2.36,
        twigScale= 0.39,
        initalBranchLength= 0.49,
        lengthFalloffFactor= 0.85,
        lengthFalloffPower= 0.99,
        clumpMax= 0.454,
        clumpMin= 0.404,
        branchFactor= 2.45,
        dropAmount= -0.1,
        growAmount= 0.235,
        sweepAmount= 0.01,
        maxRadius= 0.139,
        climbRate= 0.371,
        trunkKink= 0.093,
        treeSteps= 5,
        taperRate= 0.947,
        radiusFalloffRate= 0.73,
        twistRate= 3.02,
        trunkLength= 2.4,
        trunkMaterial=texture1,
        twigMaterial=BranchType2
    	}    
    )

But there are problems with the Tree() class in the ProcTreeLua tab, which generates trees that look like this, and it’s clear that there are quite a few vertices that are out of order and need to be debugged.

@Steppers I have to say, your javascript library is so great that we can see ProcTree’s implementation in real time!

@binaryblues just noticed that the craft tree has an oddly inverted trunk—you actually only ever see the inside of it it, no matter what angle you’re looking from.

@binaryblues I’m still getting nowhere trying to adjust the tree properties.

Attached is a version where I trimmed out all of the property lists except the js one, so that there’s only one possible place the values could be coming from, and then I did some ridiculous tweaks like making initalBranchLength, which started at 0.85, into 41.85, and making trunkLength, which started at 2.1, into 222.5.

None of that seems to have had any effect.

@UberGoober As for always seeing the interior, it should be a question of vertices order, and I’m not sure that push operations in javascript are exactly equivalent to table.Insert in lua, you may need to do this in reverse order.

In js When I changed this in the string CreateProcTree:

"initalBranchLength":10.49,

I will get the result:

https://youtu.be/3tTrh45OlPw

@binaryblues all I see is a black screen on my iPhone. I may have to wait until I get home and can run it on my iPad until I can see your results.

It may be worth noting that this isn’t exactly a full comparison, because the tree is not being translated into a Craft object, as far as I can tell.

@UberGoober Pls use this new version. I will check it on my iPhone later.

The temporary code wasn’t very clear before, because I would comment on some statements to see the different settings, and I had just made a change and added some controls to make it look a little clearer.

Btw. A performance tweak was made to remove the read file processing from the update function

https://youtu.be/FsZapdU7u-U

In more detail, we can use two ways to generate the tree:

  • Project1 is via javascript (in Project LuaProcTreeJs.zip) , which also saves the generated data to a directory to be loaded by others;
  • Project2 is to use the ported Lua class TreeVec() directly (in Project MyProcTreeCraftNew1.zip) ,In this  Project, you can choose to use either data from Project 1 or data generated by yourself.
    

I think we may be at slightly cross purposes, but that’s OK.

You have figured out how to make a bunch of different trees in a bunch of different ways — with Three, with JS, with meshes, with Craft—and so, I think, you naturally want to share projects that contain each of those achievements.

That makes total sense, and I think you should, I think that’s a service to the community, so to speak.

But for myself, I am trying to whittle this down to a single project that does just one thing: make the best-looking Craft tree (which for me is the JS-generated one).

I think the code for that is now divided between two projects, one of which writes the JS data to disk, and the other which converts that data to a Craft model. Is that right?

It looks like this, and my iteration path looks like this:

  • 1 First try the individual JS, 
    
  • 2 After success, start experimenting with porting to a lua table form, 
    
  • 3 There were some minor visual issues after the transplant. 
    
  • 4 Then use JS to provide mesh data, drawn in mesh, 
    
  • 5 Continue to use JS to provide mesh data, drawing with craft, 
    
  • 6 Rewrites Lua's table form to vector form, using two mesh data sources: 
    
    • generated from javascript in project LuaProcTreeJs.zip;
      
    • generated from the Lua class TreeVec()
      

You can use the Project LuaProcTreeJs.zip to generate the mesh data and save them, then open the Project MyProcTreeCraftNew1.zip to load them and draw using craft.

In this case, if you want to adjust the tree generation parameters, you need to adjust in the JS project, a little bit inconvenient. If there is time, I will continue to improve the TreeVec () , to solve those details, good luck