JavaScript API

Koru lets you do simple scene manipulation using JavaScript. It provides API for nodes, snapshots and camera — just enough to build custom scene tree, snapshots buttons and even simple animations or interactive pages.

Koru JavaScript Object

Each Koru scene on the page has its own JavaScript object of type Koru. You can get it using the code below:

var el = document.getElementById("my-object");
var my_object_koru = el.koru;

Where my-object is the id of the koru-viewport <div>. This way you can have many Koru scenes on the same page and control them independently.

Here are the list of Koru object properties you can use:

PropertyTypeDescription
rootKoru.Nodethe root node of the scene
snapshots[Koru.Snapshot]the array of snapshots objects
materials{Koru.Material}the dictionary of scene materials, names are the keys
cameraKoru.Camerathe camera object of the scene
createSnapshotButtonsbooleanflag which is true by default, but you can set it to false if you want to create snapshots buttons yourself
showProgressBarbooleanflag which is true by default, but can be set to false if you don’t want to see the default loading progress bar

Here is the list of methods that Koru object has:

The example below shows scene merging in action:

function koruInit(koru) {
    koru.addEventListener('loadend', onKoruLoaded);
}

function onKoruLoaded(event) {
    const koru = event.koru;
    setTimeout(() => {
        koru.merge('scene2.koruDat', koru.root);
    }, 2000);
}

Koru object also provides some events you can add listeners to:

Each event gets a dictionary as a parameter. The dictionary contains important information regarding the event. Here are the list of keys of the dictionary:

KeyTypeDescription
koruKorucontains Koru object
progressnumbera floating point value from 0 to 1, defining the current loading progress (only in progress event)
deltaTimenumbertime in seconds from the previous scene update (only in update event)
idleTimenumbertime in seconds that the scene is left idle (only in update event)
nodeKoru.Nodecontains node that has changed (only in visibilitychange event)

Here’s how you can be notified about end of loading scene:

function koruInit(koru) {
	koru.addEventListener('loadend', onKoruLoaded);
}

function onKoruLoaded(event) {
	var which_koru = event.koru;
	// do something
}

Function koruInit() is called by the Koru core when the scene is loaded. You can setup flags and subscribe to events here. The second function is called when the scene is loaded. You get Koru object from the event’s parameters and use it to access scene API.

Snapshots

The best way to see what you can do with snapshots API is to have a look at the built-in Snapshots export template code. Basically, there are two things you can do:

Here’s how to override snapshots buttons creation:

function koruInit(koru) {
	koru.createSnapshotButtons = false;
	koru.addEventListener('loadend', onKoruLoaded);
}

function onKoruLoaded(event) {
	var k = event.koru;

	for (var i in k.snapshots) {
		var snapshot = k.snapshots[i];
		if (!snapshot.visible) continue;
		console.log(snapshot.name);
	}
}

Here we tell Koru that we’ll handle snapshots button creation ourselves, then start listening for loadend event. Once we get the event, we run through the scene snapshots and log the names of the visible ones.

Here’s what you can do with snapshots in Koru API:

Once again, the best way to learn snapshots API is to have a look at snapshots export template which features everything discussed above.

Nodes

Each scene node in Koru JavaScript API has following properties:

PropertyTypeDescription
namestringlets you get the name of the node
metadataobjectthe metadata dictionary of the node
userDataobjectthe user defined data of the node
visiblebooleanlets you show and hide nodes by settings true or false values
positionKoru.Vec3the position of the node
rotationKoru.Vec3the Euler rotation angles of the node
scaleKoru.Vec3the scale of the node
matrixKoru.Mat4the local transformation matrix of the node, read-only
matrixWorldKoru.Mat4the world transformation matrix of the node, read-only
boundingBoxKoru.Box3the oriented bounding box of the node’s meshes, read-only
highlightColorKoru.Colorthe highlight color of the node
parentKoru.Nodethe parent node (or null if the node is root), read-only
children[Koru.Node]returns the array of the children nodes of this one
meshes[Koru.Mesh]return the array of meshes that this node contains

Here is the list of node methods:

For examples of using node API, have a look at scene-tree export template which uses most of the properties mentioned above. Also try clock snippet in Script Editor (Scene → Script Editor) which shows how to make animated clock model by rotating clock hands using node rotation API.

Meshes

Here is the list of mesh properties:

PropertyTypeDescription
materialKoru.Materialthe material of the mesh, read only
highlightColorKoru.Colorthe highlight color of the mesh
boundingBoxKoru.Box3the oriented bounding box of the mesh, read only
userDataobjectthe user defined data of the mesh

Each mesh in Koru JavaScript API has material parameter that contains a Material object described below. Here’s how you can access meshes of a node:

var n = koru.root.getNodesByName("node")[0]
var meshes = n.meshes;
for (var i = 0; i < meshes.length; i++)
	console.log(meshes[i].material);

Mesh objects also have the intersect(ray : Koru.Ray) : boolean method that checks the intersection of a ray with the mesh.

Materials

You can get the list of materials using koru.materials property or by enumerating all the nodes, meshes in them and getting their materials. Each Material object has the following properties and methods:

NameTypeDescription
layers[Koru.MaterialLayer]the array of Layer objects (see below)
transparentbooleantrue or false, depending on the materials parameters
doubleSidedbooleantrue or false, depending on the materials parameters
userDataobjectthe user defined data of the material
update()** —updates internal parameters of the material** — call this after changing the material

You can get all the layers from the array returned by the layers property. Each layer has the following properties and methods:

NameTypeDescription
diffuseEnabledbooleanreturns if the diffuse block is enabled
diffuseColorKoru.Colorgets or sets the diffuse tint color. Use either unsigned int or Koru.Color object
diffuseMapKoru.Texturegets or sets the diffuse texture. The layer needs to have this texture in the original scene, as otherwise Koru ignores this property
specularEnabledbooleanreturns if the specular block is enabled
specularColorKoru.Colorsame as diffuseColor, but for the specular one
specularMapKoru.Texturesame as diffuseMap, but for the specular map
emissiveEnabledbooleanreturns if the emissive block is enabled
emissiveColorKoru.Colorsame as diffuseColor, but for emissive color
emissiveMapKoru.Texturesame as diffuseMap, but for emissive map
maskKoru.Texturecontrols layer’s mask
opacitynumberopacity level of this layer
update()** —call this after changing layer’s parameters, except for the maps

All the maps you want to update using API need to have a texture when the scene is exported. Otherwise Koru exports a simpler shader and assigning texture will be ignored.

The maps are of the Koru.Texture type and can be either assigned directly (using the standard Image object), or using the following methods:

A sample code that modifies the diffuse map of the very first layer of the material of the very first mesh of the first node:

var layer = koru.root.children[0].meshes[0].material.layers[0];
layer.diffuseColor.setRGBA(1, 0.5, 0, 0.5);
layer.diffuseMap.set(koru.canvas);
layer.update();

The first line is long, but simple: it gets a “very first” layer. The second line modifies the diffuse tint, the third line assigns the current preview as a texture and the last line updates the layer.

Texture

Koru Texture object has just one method setFromImage(image : Image/Canvas) : this, which updates texture with HTML Image object or with HTML Canvas object.

Camera

You can also manipulate the scene camera with JavaScript. Here’s how to get the camera object:

function koruInit(koru) {
	koru.addEventListener('loadend', onKoruLoaded);
}

function onKoruLoaded(event) {
	var k = event.koru;
	var cam = k.camera;

	// access camera properties here
}

Here is the list of camera properties:

PropertyTypeDescription
targetKoru.Vec3the rotation center of the camera
positionKoru.Vec3the camera position. If camera position is changed, it automatically rotates to see its target
rotationKoru.Vec3the Euler angles of camera rotation: z** — yaw, y** — pitch and x** — roll
distancenumberthe camera distance from its center of rotation
matrixWorldKoru.Mat4the camera world matrix, read only
matrixViewKoru.Mat4the camera view matrix, read only
matrixProjKoru.Mat4the camera projection matrix, read only
matrixViewProjKoru.Mat4the camera view projection matrix, read only

You can create complex animations by combining node and camera transformations.

Camera object also has the following methods:

Ray

Ray object is used for tracing through the scene and compute hit points. This is useful for custom scene objects selection, for instance to display metadata and so on.

Here’s how to construct a Ray object:

var ray = new Koru.Ray(origin : Koru.Vec3, direction : Koru.Vec3, tfar : number)

Ray objects have the following properties:

PropertyTypeDescription
originKoru.Vec3the origin of the ray
directionKoru.Vec3the direction of the ray
tfarnumberthe maximum distance from the ray origin

Ray objects also have these methods:

Vec3

Vec3 object holds three floating point numbers and used for position, rotation and scale parameters. Here’s how to make one:

var v1 = new Koru.Vec3();
var v2 = new Koru.Vec3(x : number, y : number, z : number);

Vec3 objects have three properties:

PropertyTypeDescription
xnumberx component
ynumbery component
znumberz component

They also have quite a lot of methods:

Quaternion

Here’s how to make a Quaternion object in Koru:

var q1 = new Koru.Quaternion();
var q2 = new Koru.Quaternion(x : number, y : number, z : number, w : number);

Quaternion objects have these properties:

PropertyTypeDescription
xnumberx component
ynumbery component
znumberz component
wnumberw component

They also have the following methods:

Mat4

Mat4 object represents a 4x4 matrix and is used for local transformations. Here’s how to make one:

var m1 = new Koru.Mat4();
var m2 = new Koru.Mat4(elements : [ number ])

These object have just one property: m : [number] — an array of 16 numbers, representing the matrix. There are also methods:

Box3

Box3 object represents a bounding box — two vectors, defining minimum and maximum points in the space. Here’s how to create one:

var bb = new Koru.Box(min : Koru.Vec3, max : Koru.Vec3)

Box3 objects have two properties:

PropertyTypeDescription
minKoru.Vec3the “minimum” point of the box
maxKoru.Vec3the “maximum” point of the box

They also have the following methods:

Color

Color object represents a RGBA color, defined by 4 floating point numbers. Here’s how to create a Color object:

var c1 = new Koru.Color();
var c2 = new Koru.Color(red : number, green : number, blue : number, alpha : number);

Here are the properties of Color object:

PropertyTypeDescription
rnumberthe red component of the color
gnumberthe green component of the color
bnumberthe blue component of the color
anumberthe alpha component of the color

Color objects also have the following methods:

Progress Bar

For overriding progress bar you need to set showProgressBar property to false once the window is loaded and Koru object is created, then handle loadstart, progress and loadend events yourself. Then you can create/show your own progress indicator, update it and hide when the scene is loaded.

See progress export template for a complete example of overriding loading progress bar.