JavaScript - Library (Available on WebRepo)

@UberGoober You can try these file, I packed from my Codea

@binaryblues thanks!

JavaScript seems to work well but Three.is won’t run, it just gives an error message.

I don’t fully get what this is doing—could it, for example, run ProcTree:

https://github.com/supereggbert/proctree.js/blob/master/proctree.js

@UberGoober I looked at the code you provided and found that it used a special representation that was different from my usual javascript code because I was a javascript beginner myself, so it wasn’t clear, how does this form need to be transformed in three.js works within a common code framework.

I looked up that syntax:

(function(window){
var Tree=function(data){
		for(var i in data){
			if(this.properties[i]!==undefined){
				this.properties[i]=data[i];
			}
		}
		this.properties.rseed=this.properties.seed;
		this.root=new Branch([0,this.properties.trunkLength,0]);
		this.root.length=this.properties.initalBranchLength;
		this.verts=[];
		this.faces=[];
		this.normals=[];
		this.UV=[];
		this.vertsTwig=[];
		this.normalsTwig=[];
		this.facesTwig=[];
		this.uvsTwig=[];
		this.root.split(null,null,this.properties);
		this.createForks();
		this.createTwigs();
		this.doFaces();
		this.calcNormals();		
	};

    ......

Tree.flattenArray=function(input){
var retArray=[];
	for(var i=0;i<input.length;i++){
		for(var j=0;j<input[i].length;j++){
			retArray.push(input[i][j]);
		}
	}
	return retArray;
}

	window.Tree=Tree;
})(window);

and it turns out that you define an anonymous function and then call it immediately after.

In other words, it’s a form of closure.

Define an anonymous function?

(function(window){...})

Call this anonymous function?

(window)

…sorry, but does that mean that it can run ProcTree or that it can’t?

@UberGoober I looked at Proctree.js and found that it didn’t call three.js, nor any other drawing-related statements, and it looked like a separate module that needed to be called through other modules.

Can you elaborate on how you got it to work?

The only thing that might be relevant is the window parameter, which I guess is the key to getting proctree to run, but that happens to be my knowledge blind spot

The window parameter here is only used to make Tree a global variable that you can call anywhere with “ Tree” you could pass any object to have Tree assigned to it.

~~The problem I see is this call this.root=new Branch( “Branch” has to exist in this scope. ~~ actually it’s there in the full file on GitHub

@skar Thank you for explaining the window parameters.

In fact, I found that this code should be native webgl, not using three.js, but using vertices, uv, normals, which looks like Codea mesh, but without shader.

Attached is my own project where I clumsily tried to port the JavaScript procTree to lua.

Didn’t get far, as you’ll see.

Also here’s the link I got this code from, it’s different than the one I gave before:

https://github.com/jarikomppa/proctree

So in case it isn’t clear—in my project I tried to turn JavaScript code into lua code, but the project itself still contains the JavaScript code as reference.

My conversion of the js code didn’t work, but if I could run the js code itself I should be able to use it to make a nice little tree.

So if someone could tell me how to use the JavaScript project from this thread to run the js code in the above project, it could be really cool.

Okay in attached file I’ve tried to use WebView to load the JavaScript but when I hit play I get an error about not having stlib.

Well I figured out that problem and have been trying to get the js working but I’m getting errors I don’t understand about something like “undefined is not an object”.

Would love any help I can get—just run the project and you’ll see the error in the output panel.

“Undefined is not an object” will be an error thrown when you try to access an undefined variable as an object:

myUndefinedVar.thing // throws error Undefined is not an object

var myDefinedVar = { thing : “test” }

myDefinedVar.thing // “test”


Unlike Lua, which only has nil, JS has a default of “undefined” and a possible “null”. These are ever so slightly different.

@UberGoober I’m not very familiar with JS, so I can only make some guesses based on the examples of JS I’ve run successfully. Running JS projects in Codea requires full documentation of the dependencies, here is the javascript code I ran successfully, which you can refer to:

I have been trying to resolve the JS errors as they arise, and this version avoids many of them.

But I’ve hit one I have no idea how to address:

WKJavaScriptExceptionMessage: RangeError: Maximum call stack size exceeded.

btw it does seem that too much nested iterating in JS crashes Codea.

@UberGoober According to the proctree.js code, You need a full run-time environment, or you can create your own environment that calls proctree.js normally, with a lot of input parameters in the table data:

    var Tree=function(data){
        for(var i in data){
            if(this.properties[i]!==undefined){
                this.properties[i]=data[i];
                }
        }

I studied the information you provided and found that the website is a complete environment and provides all the source code(https://github.com/supereggbert/SnappyTree), but the trouble is, it’s a bit complicated with jquery,GLGE and CSS, if you load this into Codea correctly, it should work, but there’s a lot of detail to work with here, so here’s my attempt, which unfortunately failed:

my project (You need to use @Steppers 's JavaScript as a dependency) return the error:

Loading modules...

225:7 TypeError: null is not an object (evaluating 'canvas.width=800')

Done loading modules.

0:0 SyntaxError: Unexpected identifier 'MANIFEST'

0:0 SyntaxError: Unexpected token '<'

@UberGoober I got it!

see this site(https://github.com/supereggbert/proctree.js), This provides a minimal running environment.

All that remains is to load the correct texture map.

The new code:

function main()
    
    -- Create a webview
    webview = WebView()
        
    -- Load Three.js
    webview:loadJS(asset.three, true)
    webview:loadJS(asset.physi, true)
    webview:loadJS(asset.tween, true)
    webview:loadJS(asset.sounds, true)
    webview:loadJS(asset.scoreboard, true)
    webview:loadJS(asset.FlyControls, true)
    webview:loadJS(asset.OrbitControls, true)
    webview:loadJS(asset.noise, true)
    webview:loadJS(asset.spe, true)
       
    -- Load your js code here
    webview:loadJS(ProcTree, true)
    webview:loadJS(CreateProcTree, true)

    -- Display once the engine has initialised
    webview:show()
end


-- create scene etc.
CreateProcTree = [[
// The "scene" is where stuff in our game will happen:
var scene = new THREE.Scene();

// The "camera" is what sees the stuff:
var aspect_ratio = window.innerWidth / window.innerHeight;
var camera = new THREE.PerspectiveCamera(75, aspect_ratio, 1, 10000);
camera.position.y = 8;
camera.position.z = 5;

scene.add(camera);

var light = new THREE.HemisphereLight('white', 'grey', 0.5);
scene.add( light );

// The "renderer" draws what the camera sees onto the screen:
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var orbit = new THREE.OrbitControls( camera, renderer.domElement );
	orbit.enableZoom = true;


// Helper function to transform the vertices and faces
function newTreeGeometry(tree, isTwigs) {
var output = new THREE.Geometry();

tree[ isTwigs ? 'vertsTwig' : 'verts'].forEach(function(v) {
output.vertices.push(new THREE.Vector3(v[0], v[1], v[2]));
});

var uv = isTwigs ? tree.uvsTwig : tree.UV;
tree[ isTwigs ? 'facesTwig' : 'faces'].forEach(function(f) {
output.faces.push(new THREE.Face3(f[0], f[1], f[2]));
output.faceVertexUvs[0].push(f.map(function(v) {
return new THREE.Vector2(uv[v][0], uv[v][1]);
}));
});

output.computeFaceNormals();
output.computeVertexNormals(true);

return output;
}

var myTree = new Tree({
		"seed": 262,
		"segments": 6,
		"levels": 8,
		"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
	});

var trunkGeo = newTreeGeometry(myTree);
var trunkMaterial = new THREE.MeshLambertMaterial( { color: 'brown', wireframe: false } );
var trunkMesh = new THREE.Mesh(trunkGeo, trunkMaterial);
scene.add(trunkMesh); // Use your own scene

var twigsGeo = newTreeGeometry(myTree, true);
var twigsMaterial = new THREE.MeshLambertMaterial( { color: 'green', wireframe: false } );
var twigsMesh = new THREE.Mesh(twigsGeo, twigsMaterial);
scene.add(twigsMesh); // Use your own scene

//renderer.render(scene, camera); 
   
animate();
function animate() {
requestAnimationFrame(animate);
var t = Date.now() * 0.0001;

/*** (4) PLAY with the numbers!! ***/
//trunkMesh.rotation.x = 2*t;
trunkMesh.rotation.y = 5*t;

//twigsMesh.rotation.x = 2*t;
twigsMesh.rotation.y = 5*t;

renderer.render(scene, camera);
}              
]]

the video:

https://youtu.be/DS_6OnJCem4

Amazing

It looks like you’re using JS to generate the data and Three to show it, but in theory I could also use Craft in place of Three, right?

@UberGoober Yes, there’s no doubt that it’s possible to do this without the need for craft, just using mesh, but it’s also possible to use mesh as a custom model in craft after a successful migration, the most basic being to port to mesh first.