summaryrefslogtreecommitdiffstats
path: root/apps/samples/vrml/vrml-server.pre-osgjs.scxml
diff options
context:
space:
mode:
Diffstat (limited to 'apps/samples/vrml/vrml-server.pre-osgjs.scxml')
-rw-r--r--apps/samples/vrml/vrml-server.pre-osgjs.scxml333
1 files changed, 333 insertions, 0 deletions
diff --git a/apps/samples/vrml/vrml-server.pre-osgjs.scxml b/apps/samples/vrml/vrml-server.pre-osgjs.scxml
new file mode 100644
index 0000000..e08afd4
--- /dev/null
+++ b/apps/samples/vrml/vrml-server.pre-osgjs.scxml
@@ -0,0 +1,333 @@
+<scxml datamodel="ecmascript" name="vrml">
+ <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/dump.js" />
+ <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/string.endsWith.js" />
+ <script src="http://uscxml.tk.informatik.tu-darmstadt.de/scripts/array.last.js" />
+ <script>
+ var wrls = {}; // information of the wrl, vrml files
+ var models = {}; // information of the osgb files
+
+ var pathDelim = ':'; // we need to flatten directories - this will seperate them in filenames
+
+ /**
+ * Transform a http request into a pose
+ */
+ function reqToStruct(req) {
+ var struct = {};
+
+ var query = (('query' in req) ? req.query : {});
+
+ struct.pitch = (('pitch' in query &amp;&amp; isNumber(query.pitch)) ? query.pitch : 0);
+ struct.roll = (('roll' in query &amp;&amp; isNumber(query.roll)) ? query.roll : 0);
+ struct.yaw = (('yaw' in query &amp;&amp; isNumber(query.yaw)) ? query.yaw : 0);
+ struct.zoom = (('zoom' in query &amp;&amp; isNumber(query.zoom)) ? query.zoom : 1);
+ struct.x = (('x' in query &amp;&amp; isNumber(query.x)) ? query.x : 0);
+ struct.y = (('y' in query &amp;&amp; isNumber(query.y)) ? query.y : 0);
+ struct.z = (('z' in query &amp;&amp; isNumber(query.z)) ? query.z : 0);
+ struct.width = (('width' in query &amp;&amp; isNumber(query.width)) ? query.width : 640);
+ struct.height = (('height' in query &amp;&amp; isNumber(query.height)) ? query.height : 480);
+ struct.autorotate = (('autorotate' in query &amp;&amp; (query.autorotate === 'on' || query.autorotate === 'off')) ? query.autorotate : 'on');
+
+ var fileComp = req.pathComponent[req.pathComponent.length - 1];
+ struct.file = fileComp.substr(0, fileComp.indexOf('.'));
+ struct.ext = fileComp.substr(fileComp.indexOf('.') + 1);
+
+ struct.key = _event.data.pathComponent.slice(1, _event.data.pathComponent.length - 1).join(pathDelim);
+ if (struct.key.length > 0)
+ struct.key += pathDelim;
+
+ // support for meta file "latest.ext"
+ if (struct.file === "latest") {
+ var latestStamp = 0;
+ for (var key in models) {
+ if (key.substring(0, struct.key.length) == struct.key) {
+ if (models[key].ctime > latestStamp) {
+ var name = models[key].strippedName;
+ struct.file = name.substring(name.lastIndexOf(pathDelim) + 1);
+ latestStamp = models[key].ctime;
+ }
+ }
+ }
+ }
+
+ struct.key += struct.file;
+
+ return struct;
+ }
+
+ function keyForFile(file) {
+ var key = file.relDir.replace(/\//g, pathDelim).substr(1) + file.strippedName;
+ return key;
+ }
+
+ function isSupportedFormat(extension) {
+ if (extension === "gif")
+ return true;
+ if (extension === "jpg")
+ return true;
+ if (extension === "jpeg")
+ return true;
+ if (extension === "png")
+ return true;
+ if (extension === "tif")
+ return true;
+ if (extension === "tiff")
+ return true;
+ if (extension === "bmp")
+ return true;
+ return false;
+ }
+
+ // list all available models in a summary format for the topmost request
+ function overviewList() {
+ var struct = {};
+ struct.models = {};
+ for (key in models) {
+ var model = models[key];
+ var group = models[key].group
+ var name = model.strippedName.split(pathDelim).last();
+ var entry = assign(struct, ['models'].concat(group.substr(1).split('/')).concat(name), {});
+ entry.url =
+ _ioprocessors['http'].location + model.relDir + model.strippedName.split(pathDelim).join('/') + '.png';
+ entry.path = model.relDir + model.strippedName.split(pathDelim).join('/') + '.png';
+ }
+ return struct;
+ }
+
+ // check whether a given string represents a number
+ function isNumber(n) {
+ return !isNaN(parseFloat(n)) &amp;&amp; isFinite(n);
+ }
+
+ // allow to set deep keys in an object
+ function assign(obj, path, value) {
+ if (typeof path === 'string')
+ path = path.split('.');
+ if (!(path instanceof Array))
+ return undefined;
+
+ lastKeyIndex = path.length-1;
+ for (var i = 0; i &lt; lastKeyIndex; ++ i) {
+ key = path[i];
+ if (key.length == 0)
+ continue;
+ if (!(key in obj))
+ obj[key] = {}
+ obj = obj[key];
+ }
+ obj[path[lastKeyIndex]] = value;
+ return obj[path[lastKeyIndex]];
+ }
+ </script>
+ <state id="main">
+ <!-- Stop processing if no vrml-path was given on command line -->
+ <transition target="final" cond="_x['args']['vrml-path'] == undefined || _x['args']['vrml-path'].length == 0">
+ <log expr="'No --vrml-path given'" />
+ </transition>
+
+ <!-- Stop processing if no tmp-path was given on command line -->
+ <transition target="final" cond="_x['args']['tmp-path'] == undefined || _x['args']['tmp-path'].length == 0">
+ <log expr="'No --tmp-path given'" />
+ </transition>
+
+ <!-- Stop processing if any error occurs -->
+ <transition target="final" event="error">
+ <log expr="'An error occured:'" />
+ <script>dump(_event);</script>
+ </transition>
+
+ <!-- Start the directory monitor for generated files -->
+ <invoke type="dirmon" id="dirmon.processed">
+ <param name="dir" expr="_x['args']['tmp-path']" />
+ <param name="recurse" expr="false" />
+ <param name="reportExisting" expr="true" />
+ <param name="suffix" expr="'osgb'" />
+ <!-- Called for every file we found -->
+ <finalize>
+ <script>
+ var key = keyForFile(_event.data.file);
+ // this is a binary 3D file converted from the wrls
+
+ if (_event.name === "file.deleted") {
+ delete models[key];
+ print("Removed a vanished osgb file at " + key + "\n");
+ } else {
+ models[key] = _event.data.file;
+ models[key].group = '/' + _event.data.file.name.split(pathDelim).slice(0,-1).join('/');
+ print("Inserted a new osgb file at " + key + "\n");
+ }
+ </script>
+ </finalize>
+ </invoke>
+
+ <!-- Start the directory monitor for wrl files -->
+ <invoke type="dirmon" id="dirmon.vrml">
+ <param name="dir" expr="_x['args']['vrml-path']" />
+ <param name="recurse" expr="true" />
+ <param name="suffix" expr="'vrml wrl'" />
+ <finalize>
+ <script>
+ _event.key = keyForFile(_event.data.file);
+ if (_event.name === "file.existing" || _event.name === "file.added") {
+ wrls[_event.key] = _event.data.file;
+ var dirMonFile = _event.data.file.relDir.substr(1) + _event.data.file.strippedName + ".osgb"
+ // we already procressed this file
+ if (_invokers['dirmon.processed'].file[dirMonFile]) {
+ models[_event.key] = _event.data.file;
+ }
+ print("Inserting wrl " + _event.data.file.path + " from " + _event.data.file.relDir + " at " + _event.key + "\n");
+ }
+ if (_event.name === "file.deleted") {
+ delete wrls[_event.key];
+ delete models[_event.key];
+ print("Deleting wrl " + _event.data.file.path + " from " + _event.data.file.relDir + " at " + _event.key + "\n");
+ }
+ </script>
+ <if cond="models &amp;&amp; _event.name !== 'file.deleted' &amp;&amp;
+ (!(_event.key in models) || wrls[_event.key].mtime > models[_event.key].mtime)">
+ <send target="#_osgvonvert.osgb">
+ <param name="source" expr="_event.data.file.path" />
+ <param name="dest" expr="_x['args']['tmp-path'] + '/' + _event.key + '.osgb'" />
+ </send>
+ </if>
+ </finalize>
+ </invoke>
+
+ <!-- Start the osgconvert invoker to transform 3D files -->
+ <invoke type="osgconvert" id="osgvonvert.osgb">
+ <param name="threads" expr="4" />
+ <finalize>
+ <script>
+ //dump(_event);
+ </script>
+ <if cond="'context' in _event.data">
+ <!-- this was generated in reply to a request -->
+ <if cond="_event.name.endsWith('success')">
+ <respond status="200" to="_event.data.context">
+ <header name="Connection" value="close" />
+ <header name="Content-Type" value="application/json" />
+ <header name="Access-Control-Allow-Origin" value="*" />
+ <header name="Content-Type" valueexpr="_event.data.content[_event.data.format].mimetype" />
+ <content expr="_event.data.content[_event.data.format]" />
+ </respond>
+ <else />
+ <respond status="404" to="_event.data.context">
+ <header name="Connection" value="close" />
+ </respond>
+ </if>
+ </if>
+ </finalize>
+ </invoke>
+
+ <!-- Start a nested SCXML interpreter to create movies from the images -->
+ <invoke type="scxml" id="scxml.ffmpeg" src="ffmpeg-server.invoked.scxml" autoforward="true">
+ <param name="modelDir" expr="_x['args']['tmp-path']" />
+ </invoke>
+
+ <!-- Idle here -->
+ <state id="idle">
+ <transition event="http.get" target="idle" cond="
+ _event.data.pathComponent.length >= 2 &amp;&amp;
+ _event.data.pathComponent[_event.data.pathComponent.length - 1].indexOf('.') !== -1">
+ <!-- request for a specific format http://host/vrml/relative/path/format?query=string -->
+ <script>
+ //dump(_invokers['dirmon.vrml']);
+ _event.fileStruct = reqToStruct(_event.data);
+ </script>
+ <if cond="_event.fileStruct.key in models &amp;&amp; isSupportedFormat(_event['fileStruct'].ext)">
+ <!-- There is such a file available as osgb -->
+ <send target="#_osgvonvert.osgb">
+ <param name="source" expr="models[_event['fileStruct'].key].path" />
+ <param name="format" expr="_event['fileStruct'].ext" />
+ <param name="pitch" expr="_event.fileStruct.pitch" />
+ <param name="roll" expr="_event.fileStruct.roll" />
+ <param name="yaw" expr="_event.fileStruct.yaw" />
+ <param name="zoom" expr="_event.fileStruct.zoom" />
+ <param name="x" expr="_event.fileStruct.x" />
+ <param name="y" expr="_event.fileStruct.y" />
+ <param name="z" expr="_event.fileStruct.z" />
+ <param name="width" expr="_event.fileStruct.width" />
+ <param name="height" expr="_event.fileStruct.height" />
+ <param name="autorotate" expr="_event.fileStruct.autorotate" />
+ <param name="context" expr="_event.origin" />
+ </send>
+ <else />
+ <!-- There is no such model -->
+ <respond status="404" to="_event.origin">
+ <header name="Connection" value="close" />
+ </respond>
+ </if>
+ </transition>
+
+ <!--
+ process request for JSON datastructures
+ -->
+ <transition event="http.get" target="idle" cond="
+ _event.data.pathComponent.length == 2 &amp;&amp;
+ _event.data.pathComponent[1] === 'models'">
+ <script>//dump(_event)</script>
+ <respond status="200" to="_event.origin">
+ <header name="Connection" value="close" />
+ <header name="Content-Type" value="application/json" />
+ <header name="Access-Control-Allow-Origin" value="*" />
+ <content expr="models" />
+ </respond>
+ </transition>
+
+ <transition event="http.get" target="idle" cond="
+ _event.data.pathComponent.length == 2 &amp;&amp;
+ _event.data.pathComponent[1] === 'wrls'">
+ <script>//dump(_event)</script>
+ <respond status="200" to="_event.origin">
+ <header name="Connection" value="close" />
+ <header name="Content-Type" value="application/json" />
+ <header name="Access-Control-Allow-Origin" value="*" />
+ <content expr="wrls" />
+ </respond>
+ </transition>
+
+ <!-- request for topmost list of all files -->
+ <transition event="http.get" target="idle" cond="
+ _event.data.pathComponent.length == 1">
+ <script>//dump(_event);</script>
+ <respond status="200" to="_event.origin">
+ <header name="Connection" value="close" />
+ <header name="Content-Type" value="application/json" />
+ <header name="Access-Control-Allow-Origin" value="*" />
+ <content expr="overviewList()" />
+ </respond>
+ </transition>
+
+ <!-- XHR CORS preflight response -->
+ <transition event="http.options" target="idle">
+ <script>//dump(_event);</script>
+ <respond status="200" to="_event.origin">
+ <header name="Access-Control-Allow-Origin" value="*" />
+ <header name="Access-Control-Allow-Methods" value="GET, OPTIONS" />
+ <header name="Access-Control-Allow-Headers" value="X-Requested-With" />
+ </respond>
+ </transition>
+
+ <transition event="render.done" target="idle">
+ <script>//dump(_event);</script>
+ <respond status="200" to="_event.data.context">
+ <header name="Connection" value="close" />
+ <header name="Content-Type" valueexpr="_event.data.mimetype" />
+ <header name="Content-Disposition" valueexpr="'attachment; filename=' + _event.data.filename" />
+ <content expr="_event.data.movie" />
+ </respond>
+ </transition>
+
+ <transition event="send.codecs" target="idle">
+ <script>//dump(_event);</script>
+ <respond status="200" to="_event.data.context">
+ <header name="Connection" value="close" />
+ <header name="Content-Type" valueexpr="_event.data.mimetype" />
+ <header name="Content-Disposition" valueexpr="'attachment; filename=' + _event.data.filename" />
+ <content expr="_event.data.codecs" />
+ </respond>
+ </transition>
+
+ </state>
+ </state>
+ <state id="final" final="true" />
+</scxml> \ No newline at end of file