Open Source Platform
for interconnected virtual worlds

Interpreted Languages Working Group

From Rex community wiki

Contents

Goal

Enable use of higher level languages within the c++ written viewer for the two following purposes. For nitpickers, there is an explanation of the working group name.

1. Writing viewer modules: trusted code that is basically identical to the c++ components, can do things within the viewer framework and access the system for e.g. filesystem access and additional network connections. Python is good for this because the standard library features full operating system access, and there are bingings for all common external libraries such as gtk, qt, svn, databases and networking. This currently works, using the embedded Python interpreter, and is used to implement the (early, crude work-in-progress version) of world editing UI in the viewer and other plugins like a web server for serving live screenshots and a machine vision based headtracking camera/avatar control input. (TODO: add own pages for these)

2. Client side scripting: untrusted code from the network that can implement e.g. functionality specific to a region or an item. Similar to how Javascript is used to make custom UIs and behaviour on websites. Experimented with in Python now, without sandboxing -- final implementation will need either Python sandboxing or using Javascript which has no system access and can be restricted easily. An experimental QtScript module was made in September 2009 and it worked. During 2010 it was improved and taken into production. The last challenge now is to make the useful API safe again for loading untrusted code from the net, notes about that in Interpreted Languages Working Group/Javascript sandbox. (and older gui oriented plan is Interpreted Languages Working Group/Javascript support).

First the API code was written all by hand, using the Python C API, while options like SWIG, Boost-Py, Pyrex and friends were evaluated. Later when Qt was selected as the UI toolkit for Naali for other reasons, we learned that the metaobject system there works for also automatic exposing of C++ written classes which are QObjects. By making things QObjects with slots, signals and properties, they can be automatically exposed to both Python using PythonQt (note: that is not PyQt) and to Javascript using QtScript. We have started doing that and plan to do more so in the future.

Current status

The Python module implements ScriptingService and provides means to execute arbitary Python code (given as a string) and load Python modules from the disk. These are provided as console commands too, PyExec(print 'Hello World') and PyLoad(hello) (to import a module called hello.py).

Handling viewer events has been implemented by the PythonScriptModule listening to viewer events and forwarding those to the Python written modules. A Python written ModuleManager loads py modules and passes on the events. Current working version uses the Circuits library, so that the viewer events are sent forward as Circuits events, and own modules to the viewer are to be written as Circuits Components. There are some examples of this in the bin/pymodules directory.

PythonQt can be also used to load python modules from viewer c++ code and to instanciate classes and call methods/functions there. PythonQt automatically handles the data type conversions between Python and c++. This is done in the C++ written inventory module, which defines an abstract model in c++ with two implementations: a C++ impl for the legacy sludp protocol, and a Python one for Taiga (Cable Beach) WebDAV inventory (using a python written webdav librar).

Implementation issues and plans

Entity-Components

Module Manager - Autoloading python written modules and having passing events from the viewer to a separate event system there.

Ogre API - Made a little test with Python-Ogre as was very positively surprised to learn that it works in embedded contexts too. So this existing boost::py using lib gives us full access to Ogre, did a test where draw lines using ManualObject.

Earlier we discussed whether to implement all of the API in separate modules that have the api code for interpreted langs (PythonModule, QtScriptModule), or whether to have api code also in the modules that implement the functionality (like the renderer). The decision was to support dynamic langs in the actual modules too, and with Qt it is now done by having things as QObjects with slots, signals and properties Modules and API.

Next steps

There are many use cases identified for scripting (untrusted code coming over the wire ala javascript with the web), and with the dozen modules implemented in c++ now we also have a a source of information about the usage patterns and interactions among those trusted components. These must be now analyzed to plan the work further.

For now, the todo consists of the following:

basic api & internals work

  • wrap internal classes like Vector3 and Quaternion, that can't be QObjects in the internals, with QObject wrappers, which py & js need (for e.g. conversions from euler to quat and back)
  • generic e-c properties to expose everything for editing, e.g. setting colors of objects etc. feasible?
  • threaded task stuff?

namespace cleanup

  • Refactoring the naali-namespace for Python. At the moment, we have a working namespace 'rexviewer' implemented in c++, but it is not pythonic due to some shortcuts we have in the c py api code, and also the things exposed via pythonqt are available via the pythonqt module. The plan is to rename 'rexviewer' to '_naali' and write a naali.py that is a clean unified pythonic api for the plugins.

world editing

  • The manipulator arrows in EditGUI will be modified a tad bit. The implementation of the current arrows will be replaced with different manipulator objects for different axis', though the look 'n feel will remain the same as before. Separating the manipulator's parts into pieces allows us to use RayCasting on the different manipulators to get the axis for the entity's modification, i.e. width for scaling, x-axis for position and the angle for rotating. Also, all three manipulators can be active at the same time, but whats being manipulated is determined by the user's click.
  • Due to the previous statement, EditGUI's layout will be changed to consist of a Rotate, Move and Scale buttons that will enable the wanted operation for the selected entity.
  • Locks for manipulated objects.
  • Checking if you can actually manipulate the object.
  • "Keep aspect ratio" -type checkbox for scaling.
  • The mouse dragging of entities isn't working as intended at this time, though it works as a test/showcase but lacks subtlety. This will be addressed in the next sprint by adding an invisible layer for Raycasting, this way we can determine the cursors position on the screen vs the world. Thus getting the correct position for the dragged entity.
  • Also the mouse dragging's jitteringness will be looked into a bit more thoroughly.
  • undo - server side.