A plugin can be thought of as an addition to existing software so that we can add on specific functions that suit our needs. In Clara.io, all plugins are written in Javascript. The following describes how to create and write new plugins.
You must request plugin access before you can create a plugin. In order to grant access, we will need to confirm who you are. Please send an email to support@exocortex.com with the following information:
We can create any number of plugins, each of which is stored on the server. We can create a new plugin by following these steps. Please note that to create a plugin, you must first request plugin access. Contact us at support@exocortex.com to get started!
To begin, we must name and version our plugin in the script. In Clara.io we do not include it in your script as you will be filling in the information on the plugin page.
When we load a plugin on the Clara.io server, it has access to any other files that have also been loaded onto the server.
A plugin uses a user defined command to execute specific functions. In order to define a command, we must include a name
member and an execute
function. We can also specify a location for the command in the interface.
registrar.defineCommand({
name: 'HelloWorld',
uiPlace: { menu: ['My Plugin'] },
uiState: { label: 'Hello World', category: 'hello' },
execute: function(app, options, callback) {
alert('Hello, world!');
callback();
}
});
Each scene is made up of multiple nodes which contain many plugs within them. These plugs describe the mesh, material and transformation of the node.The node can be modified / created by an operator. There are two parts to an operator, its name
and its target
. The name specifies what the operator is called. The target specifies where the operator will plug into.
registrar.defineOperator({
name: 'Box',
target: 'PolyMesh',
...
});
A schema is used when an input from the user or other parameter is required. Each member is given a type such as ‘Color’ and ‘Text’.
registrary.defineOperator({
name: 'Box',
target: 'PolyMesh',
schema: {
// State the type of default value of the size property so the UI knows what to display
size: {type: 'Vec3', defaultValue: new THREE.Vector3(1, 1, 1), minValue: 0.1, step: 1, animatable: true}
},
...
});
The creation operator is used to create mesh by using a create
function. It allows the vertices and faces of a mesh to be set up.
create: function(operator) {
// Get the current value of size from the operator instance
var size = operator.get('size');
// Use the half size to send into the box so it's centered
var half = size.clone().multiplyScalar(0.5);
var positions = [
new THREE.Vector3(-half.x, -half.y, -half.z),
new THREE.Vector3(half.x, -half.y, -half.z),
new THREE.Vector3(half.x, half.y, -half.z),
new THREE.Vector3(-half.x, half.y, -half.z),
new THREE.Vector3(half.x, half.y, half.z),
new THREE.Vector3(half.x, -half.y, half.z),
new THREE.Vector3(-half.x, half.y, half.z),
new THREE.Vector3(-half.x, -half.y, half.z)
];
var faces = [
[0, 1, 2, 3],
[1, 5, 4, 2],
[3, 2, 4, 6],
[7, 5, 4, 6],
[0, 7, 6, 3],
[0, 1, 5, 7]
];
return new exo.geometry.PolyMesh(faces, positions);
}
Unlike the creation operator, the modification operator works with existing meshes. It allows us to alter the existing vertices and faces.
modify: function(operator, polyMesh) {
var aabb = polyMesh.boundingBox();
var deAlignX = operator.get('deAlignX');
var deAlignY = operator.get('deAlignY');
var deAlignZ = operator.get('deAlignZ');
var halfSize = aabb.size().multiplyScalar(0.5);
_.each(polyMesh.positions, function(position) {
if (deAlignX) position.x += halfSize.x;
if (deAlignY) position.y += halfSize.y;
if (deAlignZ) position.z += halfSize.z;
});
return polyMesh;
}
Console output from a server side command will be attached to the job (Visible from the Jobs
link in your user menu dropdown). Therefore, to debug a plugin running on the server, you can add console.log
statements to the command as needed, and verify the output from the stdout.txt
file attached to the job.