diff options
Diffstat (limited to 'apps/samples/vrml/vrml-server.pre-osgjs.scxml')
-rw-r--r-- | apps/samples/vrml/vrml-server.pre-osgjs.scxml | 333 |
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 && isNumber(query.pitch)) ? query.pitch : 0); + struct.roll = (('roll' in query && isNumber(query.roll)) ? query.roll : 0); + struct.yaw = (('yaw' in query && isNumber(query.yaw)) ? query.yaw : 0); + struct.zoom = (('zoom' in query && isNumber(query.zoom)) ? query.zoom : 1); + struct.x = (('x' in query && isNumber(query.x)) ? query.x : 0); + struct.y = (('y' in query && isNumber(query.y)) ? query.y : 0); + struct.z = (('z' in query && isNumber(query.z)) ? query.z : 0); + struct.width = (('width' in query && isNumber(query.width)) ? query.width : 640); + struct.height = (('height' in query && isNumber(query.height)) ? query.height : 480); + struct.autorotate = (('autorotate' in query && (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)) && 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 < 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 && _event.name !== 'file.deleted' && + (!(_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 && + _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 && 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 && + _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 && + _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 |