So, this is a little project I’ve been working on… (the initial reasons are less relevant now but they still affect my prime use-case)
ScriptMonkey is a Groovy shell window that can be used to control a JME scene. So the app starts up with a standard JME window with a few boxes in it, some default lights, etc… but it also opens up this separate Groovy Console window.
It might look something like this:
It’s still pretty basic but already pretty powerful. Mostly the theory is to make JME groovy by augmenting the existing interfaces just enough to be useful without making the user relearn too many things. So app refers to the app, rootNode refers to the rootNode, and most of the Java-isms you know and love will still work.
However, some things become much easier for experimenting and tweaking. My original use-case was to use this as a model importer because the SDK importer was causing me some pain and because the models I was loading had many meshes and materials and it was becoming tedious to adjust them all by hand. So I wanted some automation.
Here is what is currently available…
General Features
The script console remembers what you have entered from one run to the next. Whatever was there when you closed the app down (presuming no crash) will be there when you start up again. Useful for experimenting with whole scene setup.
Furthermore, if you put .groovy scripts in a local “scripts” directory they will be run automatically when the tool starts up.
As a test, here is the startup script that automatically vies me a sky:
sky = createSky( “galaxy+Z.png”, “galaxy-Z.png”,
“galaxy+X.png”, “galaxy-X.png”,
“galaxy+Y.png”, “galaxy-Y.png” );
rootNode += sky
The screen shot app state is included by default and can be invoked in the usual “SysRq” way. Debug stats can be toggled with F5 as usual. The setup also includes a (currently unused) Lemur-based HUD that can be toggled on/off with F3… but there is nothing in it right now. (coming soon)
Camera
Currently there is a fly-style camera in the 3D view that can be toggled on and off with the space bar. On the scripting side, you can access “camera” or you can use some convenience functions:
go x,y,z
…will move to that location
look Facing (where Facing is either North, South, East, West, Up, or Down)
…will look in that direction.
For example:
go 10, 0, 10
look North
Future: fly (to move over time), lookAt (to look at a location)
Assets and Models
loadTexture(String) or loadTexture(textureKey) will load a texture from the asset manager. Coming soon: loadTexture(File)
loadModel(String) loads a model from the asset manager in the conventional way.
loadModel(File root, String model) will temporarily set an asset root for loading the specified model.
loadModel(File model) will temporarily set an expanding asset locator that can search the nearby directories for the asset’s dependencies. This right here makes all the difference.
Files
chooseFile(extension) will open a file selector dialog and return the file that the user selects.
Future: choose file for saving, etc.
An example usage where the chooseFile and loadModel can be combined to add a model to the scene:
f = chooseFile “j3o”
model = loadModel f
rootNode += model
Materials
Materials have been augmented to behave more like maps. material.params will return a Map of all possible values that the material can have (set to null if they aren’t set) including the ones in the material definition itself. What this means is that you can do things like:
// See all available parameter names on a material
println mat.params.collect{ it.key }
// See all of the set parameters on a material
println mat.params.findAll{ it.value != null }
// Or just generally set and get material values
mat.params.Diffuse = ColorRGBA.Red
println mat.params.Ambient
Scene Stuff
As you saw earlier the sky factory is exposed through a convenience function. Also, Node has been enhanced to support some operator overloads:
// Add a child to a node
node += child
// Get a child at index 2
println node[2]
// Find the child with a particular name
println node[“Box”]
Spatial itself has also been enhanced to support a ‘visit’ method:
// Visit every spatial in someSpatial’s hierarchy in depth-first order
// and print it to the console
someSpatial.visit { println it }
And as mentioned, so far two sky functions (more to come, I guess):
Spatial createSky( Texture west, Texture east, Texture north, Texture south, Texture up, Texture down )
Spatial createSky( String west, String east, String north, String south, String up, String down )
Math
So far, I’ve enhanced Vector3f, Vector2f, and Vector4f to support various operator overloading. I also added some glsl style constructors for them.
v1 = vec3(1,2,3)
v2 = vec3(1)
v3 = v1 + v2 * 3
v4 = vec4(1,2,3,4)
v5 = v4.xyz
Support for ColorRGBA coming soon as well as some kind of support for Quaternions.
Download
So, if you are interesting in playing around, you can download it here:
http://code.google.com/p/jmonkeyplatform-contributions/source/browse/#svn%2Ftrunk%2FLemur%2Fextensions%2FScriptMonkey%2Frelease
Next Steps
Saving scenes/models. That’s the big one… no point in tweaking stuff if you can save it out again for later.
Now that I have the basic system in place, I plan to start building out the HUD-related scripting. I will add the ability to hook scripts on buttons in the hud and mouse events, etc… with another set of buttons to switch modes. I also have started for another project some blender-style Lemur-based manipulators that I will make available for clicked objects for moving/rotating.
My goal is to use this as a super-importer where a lot of scene management has to be done and having access to scripts and loops would be beneficial. It also helps me get around the fact that right now the only way to update the SDK blender support is to build the SDK from source… and for the blender importer that’s kind of crucial.
Note: some of my specific enhancements will be add-on scripts that I will put in the “scripts” startup folder and some will be enhancements to ScriptMonkey itself. I plan to make all of it available and hopefully such script snippets become a “thing” anyway.
Edit: removed the code blocks because they totally screw up formatting.