summaryrefslogtreecommitdiffstats
path: root/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-10-11 20:25:39 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-10-11 20:25:39 (GMT)
commitef551cb937956e2c13570ab3f8f119c48fa5656e (patch)
treefb12268c38f7bbdddd583859d8c615411048d071 /src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp
parent1924f35d1d21a59939110f7eae238052c37474e2 (diff)
downloaduscxml-ef551cb937956e2c13570ab3f8f119c48fa5656e.zip
uscxml-ef551cb937956e2c13570ab3f8f119c48fa5656e.tar.gz
uscxml-ef551cb937956e2c13570ab3f8f119c48fa5656e.tar.bz2
Reactivated plugin system
Diffstat (limited to 'src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp')
-rw-r--r--src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp365
1 files changed, 334 insertions, 31 deletions
diff --git a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp
index 2b77baf..d732e63 100644
--- a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp
+++ b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp
@@ -3,10 +3,36 @@
#include "uscxml/UUID.h"
#include <glog/logging.h>
+#include <osg/Shape>
+#include <osg/ShapeDrawable>
+#include <osg/Material>
+#include <osg/Depth>
+
#ifdef BUILD_AS_PLUGINS
#include <Pluma/Connector.hpp>
#endif
+#define OSG_SET_MATERIAL \
+osg::ref_ptr<osg::Material> mat = getMaterial(element); \
+if (mat) { \
+ osg::ref_ptr<osg::StateSet> nodeSS = geode->getOrCreateStateSet(); \
+\
+ nodeSS->setAttribute(mat.get()); \
+ nodeSS->setMode( GL_BLEND, osg::StateAttribute::ON ); \
+/* nodeSS->setRenderingHint( osg::StateSet::TRANSPARENT_BIN ); \
+ nodeSS->setMode( GL_DEPTH_TEST, osg::StateAttribute::ON ); \
+ osg::Depth* depth = new osg::Depth; \
+ depth->setWriteMask( false ); \
+ nodeSS->setAttributeAndModes( depth, osg::StateAttribute::ON ); \
+ nodeSS->setMode( GL_LIGHTING, osg::StateAttribute::OFF );*/ \
+}
+
+#define OSG_SET_COLOR \
+bool validColor = true; \
+osg::Vec4 color = getColor(element, "color", validColor); \
+if (validColor) \
+drawable->setColor(color);
+
namespace uscxml {
#ifdef BUILD_AS_PLUGINS
@@ -17,6 +43,12 @@ bool connect(pluma::Host& host) {
}
#endif
+#define OSG_TAG_HANDLE(tagName, procFunc) \
+} else if (boost::iequals(LOCALNAME(childs.item(i)), tagName) && \
+ validChildren.find(tagName) != validChildren.end()) { \
+ procFunc(childs.item(i));\
+
+
OSGInvoker::OSGInvoker() {
}
@@ -35,6 +67,9 @@ Data OSGInvoker::getDataModelVariables() {
}
void OSGInvoker::send(const SendRequest& req) {
+ if (boost::iequals(req.name, "intersect")) {
+
+ }
}
void OSGInvoker::cancel(const std::string sendId) {
@@ -43,6 +78,10 @@ void OSGInvoker::cancel(const std::string sendId) {
void OSGInvoker::invoke(const InvokeRequest& req) {
tthread::lock_guard<tthread::recursive_mutex> lock(_mutex);
+ setupColors();
+
+ std::cout << req.dom;
+
// register default event handlers
Arabica::DOM::Events::EventTarget<std::string> evTarget = Arabica::DOM::Events::EventTarget<std::string>(req.dom);
evTarget.addEventListener("DOMSubtreeModified", *this, false);
@@ -52,9 +91,37 @@ void OSGInvoker::invoke(const InvokeRequest& req) {
std::set<std::string> validChilds;
validChilds.insert("display");
- processChildren(validChilds, req.dom);
+
+ // this is somewhat unfortunate, if content contains a single child, we will get that, otherwise its parent (<content>)
+ if (boost::iequals(LOCALNAME(req.dom), "display")) {
+ processChildren(validChilds, req.dom.getParentNode());
+ } else {
+ processChildren(validChilds, req.dom);
+ }
}
+void OSGInvoker::setupColors() {
+ _colors["red"] = osg::Vec4(1.0, 0.0, 0.0, 1.0);
+ _colors["cyan"] = osg::Vec4(0.0, 1.0, 1.0, 1.0);
+ _colors["blue"] = osg::Vec4(0.0, 0.0, 1.0, 1.0);
+ _colors["darkblue"] = osg::Vec4(0.0, 0.0, 0.625, 1.0);
+ _colors["lightblue"] = osg::Vec4(0.675, 0.84375,0.89844,1.0);
+ _colors["purple"] = osg::Vec4(0.5, 0.0, 0.5, 1.0);
+ _colors["yellow"] = osg::Vec4(1.0, 1.0, 0.0, 1.0);
+ _colors["lime"] = osg::Vec4(0.0, 1.0, 0.0, 1.0);
+ _colors["magenta"] = osg::Vec4(1.0, 0.0, 1.0, 1.0);
+ _colors["white"] = osg::Vec4(1.0, 1.0, 1.0, 1.0);
+ _colors["silver"] = osg::Vec4(0.75, 0.75, 0.75, 1.0);
+ _colors["grey"] = osg::Vec4(0.5, 0.5, 0.5, 1.0);
+ _colors["gray"] = osg::Vec4(0.5, 0.5, 0.5, 1.0);
+ _colors["black"] = osg::Vec4(0.0, 0.0, 0.0, 1.0);
+ _colors["orange"] = osg::Vec4(1.0, 0.644, 0.0, 1.0);
+ _colors["brown"] = osg::Vec4(0.644, 0.164, 0.164, 1.0);
+ _colors["maroon"] = osg::Vec4(0.5, 0.0, 0.0, 1.0);
+ _colors["green"] = osg::Vec4(0.0, 0.5, 0.0, 1.0);
+ _colors["olive"] = osg::Vec4(0.5, 0.5, 0.0, 1.0);
+}
+
void OSGInvoker::runOnMainThread() {
_displays_t::iterator dispIter = _displays.begin();
if (_mutex.try_lock()) {
@@ -70,7 +137,7 @@ void OSGInvoker::handleEvent(Arabica::DOM::Events::Event<std::string>& event) {
// std::cout << "Handling Event!" << std::endl;
Arabica::DOM::Node<std::string> node(event.getTarget());
if (_nodes.find(node) != _nodes.end()) {
- osg::Node* osgNode = _nodes[node];
+ osg::ref_ptr<osg::Node> osgNode = _nodes[node];
if (false) {
} else if (boost::iequals(LOCALNAME(node), "rotation")) {
updateRotation(osgNode, event);
@@ -117,26 +184,39 @@ void OSGInvoker::processViewport(const Arabica::DOM::Node<std::string>& element)
unsigned int actualY = 0;
unsigned int actualWidth = 0;
unsigned int actualHeight = 0;
+
getViewport(element, actualX, actualY, actualWidth, actualHeight, compDisp);
-
osg::Viewport* viewPort = new osg::Viewport(actualX, actualY, actualWidth, actualHeight);
compDisp->addView(name, viewPort, sceneView);
+ bool hasBGColor;
+ osg::Vec4 bgColor = getColor(element, "bgcolor", hasBGColor);
+ if (hasBGColor) {
+ sceneView->getCamera()->setClearColor(bgColor);
+ } else {
+ sceneView->getCamera()->setClearColor(_colors["white"]);
+ }
+
std::set<std::string> validChilds;
validChilds.insert("camera");
validChilds.insert("translation");
validChilds.insert("rotation");
validChilds.insert("scale");
validChilds.insert("node");
+ validChilds.insert("sphere");
+ validChilds.insert("box");
+ validChilds.insert("capsule");
+ validChilds.insert("cone");
+ validChilds.insert("cylinder");
processChildren(validChilds, element);
}
void OSGInvoker::processCamera(const Arabica::DOM::Node<std::string>& element) {}
-void OSGInvoker::updateCamera(osg::Node* node, Arabica::DOM::Events::Event<std::string>& event) {}
+void OSGInvoker::updateCamera(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event) {}
void OSGInvoker::processTranslation(const Arabica::DOM::Node<std::string>& element) {
assert(_nodes.find(element.getParentNode()) != _nodes.end());
- osg::Node* node = _nodes[element.getParentNode()];
+ osg::ref_ptr<osg::Node> node = _nodes[element.getParentNode()];
double x = 0, y = 0, z = 0;
if (HAS_ATTR(element, "x"))
@@ -159,12 +239,17 @@ void OSGInvoker::processTranslation(const Arabica::DOM::Node<std::string>& eleme
validChilds.insert("rotation");
validChilds.insert("scale");
validChilds.insert("node");
+ validChilds.insert("sphere");
+ validChilds.insert("box");
+ validChilds.insert("capsule");
+ validChilds.insert("cone");
+ validChilds.insert("cylinder");
processChildren(validChilds, element);
}
void OSGInvoker::processRotation(const Arabica::DOM::Node<std::string>& element) {
assert(_nodes.find(element.getParentNode()) != _nodes.end());
- osg::Node* node = _nodes[element.getParentNode()];
+ osg::ref_ptr<osg::Node> node = _nodes[element.getParentNode()];
osg::Matrix rotation = rotationFromElement(element);
osg::MatrixTransform* transform = new osg::MatrixTransform();
@@ -177,11 +262,16 @@ void OSGInvoker::processRotation(const Arabica::DOM::Node<std::string>& element)
validChilds.insert("rotation");
validChilds.insert("scale");
validChilds.insert("node");
+ validChilds.insert("sphere");
+ validChilds.insert("box");
+ validChilds.insert("capsule");
+ validChilds.insert("cone");
+ validChilds.insert("cylinder");
processChildren(validChilds, element);
}
-void OSGInvoker::updateRotation(osg::Node* node, Arabica::DOM::Events::Event<std::string>& event) {
- osg::MatrixTransform* transform = static_cast<osg::MatrixTransform*>(node);
+void OSGInvoker::updateRotation(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event) {
+ osg::ref_ptr<osg::MatrixTransform> transform = static_cast<osg::MatrixTransform*>(node->asTransform());
if (false) {
} else if (boost::iequals(event.getType(), "DOMAttrModified")) {
osg::Matrix rotation = rotationFromElement(Arabica::DOM::Node<std::string>(event.getTarget()));
@@ -232,7 +322,7 @@ osg::Matrix OSGInvoker::rotationFromElement(const Arabica::DOM::Node<std::string
void OSGInvoker::processScale(const Arabica::DOM::Node<std::string>& element) {
assert(_nodes.find(element.getParentNode()) != _nodes.end());
- osg::Node* node = _nodes[element.getParentNode()];
+ osg::ref_ptr<osg::Node> node = _nodes[element.getParentNode()];
double x = 1, y = 1, z = 1;
if (HAS_ATTR(element, "x"))
@@ -255,6 +345,11 @@ void OSGInvoker::processScale(const Arabica::DOM::Node<std::string>& element) {
validChilds.insert("rotation");
validChilds.insert("scale");
validChilds.insert("node");
+ validChilds.insert("sphere");
+ validChilds.insert("box");
+ validChilds.insert("capsule");
+ validChilds.insert("cone");
+ validChilds.insert("cylinder");
processChildren(validChilds, element);
}
@@ -263,7 +358,7 @@ void OSGInvoker::processNode(const Arabica::DOM::Node<std::string>& element) {
assert(nodeIter != _nodes.end());
assert(_nodes.find(element.getParentNode()) != _nodes.end());
- osg::Node* parent = _nodes[element.getParentNode()];
+ osg::ref_ptr<osg::Node> parent = _nodes[element.getParentNode()];
std::string filename;
if (HAS_ATTR(element, "src")) {
@@ -290,33 +385,241 @@ void OSGInvoker::processNode(const Arabica::DOM::Node<std::string>& element) {
}
}
+void OSGInvoker::processSphere(const Arabica::DOM::Node<std::string>& element) {
+ assert(_nodes.find(element.getParentNode()) != _nodes.end());
+ osg::ref_ptr<osg::Node> parent = _nodes[element.getParentNode()];
+
+ float radius = 1;
+ osg::Vec3 center(0,0,0);
+
+ if (HAS_ATTR(element, "radius")) {
+ radius = strTo<float>(ATTR(element, "radius"));
+ }
+
+ osg::ref_ptr<osg::Sphere> sphere = new osg::Sphere(center, radius);
+ osg::ref_ptr<osg::ShapeDrawable> drawable = new osg::ShapeDrawable(sphere);
+ osg::ref_ptr<osg::Geode> geode = new osg::Geode();
+ geode->addDrawable(drawable);
+
+ OSG_SET_COLOR;
+ OSG_SET_MATERIAL;
+
+ _nodes[element] = geode;
+
+ parent->asGroup()->addChild(geode);
+}
+
+void OSGInvoker::updateSphere(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event) {
+}
+
+void OSGInvoker::processBox(const Arabica::DOM::Node<std::string>& element) {
+ assert(_nodes.find(element.getParentNode()) != _nodes.end());
+ osg::ref_ptr<osg::Node> parent = _nodes[element.getParentNode()];
+
+ float x = 1;
+ float y = 1;
+ float z = 1;
+ osg::Vec3 center(0,0,0);
+
+ if (HAS_ATTR(element, "x")) x = strTo<float>(ATTR(element, "x"));
+ if (HAS_ATTR(element, "y")) y = strTo<float>(ATTR(element, "y"));
+ if (HAS_ATTR(element, "z")) z = strTo<float>(ATTR(element, "z"));
+
+ osg::ref_ptr<osg::Box> box = new osg::Box(center, x, y, z);
+ osg::ref_ptr<osg::ShapeDrawable> drawable = new osg::ShapeDrawable(box);
+ osg::ref_ptr<osg::Geode> geode = new osg::Geode();
+ geode->addDrawable(drawable);
+
+ OSG_SET_COLOR;
+ OSG_SET_MATERIAL;
+
+ _nodes[element] = geode;
+
+ parent->asGroup()->addChild(geode);
+
+}
+void OSGInvoker::updateBox(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event) {
+}
+void OSGInvoker::processCapsule(const Arabica::DOM::Node<std::string>& element) {
+ assert(_nodes.find(element.getParentNode()) != _nodes.end());
+ osg::ref_ptr<osg::Node> parent = _nodes[element.getParentNode()];
+
+ float radius = 1;
+ float height = 1;
+ osg::Vec3 center(0,0,0);
+
+ if (HAS_ATTR(element, "radius")) radius = strTo<float>(ATTR(element, "radius"));
+ if (HAS_ATTR(element, "height")) height = strTo<float>(ATTR(element, "height"));
+
+ osg::ref_ptr<osg::Capsule> capsule = new osg::Capsule(center, radius, height);
+ osg::ref_ptr<osg::ShapeDrawable> drawable = new osg::ShapeDrawable(capsule);
+ osg::ref_ptr<osg::Geode> geode = new osg::Geode();
+ geode->addDrawable(drawable);
+
+ OSG_SET_COLOR;
+ OSG_SET_MATERIAL;
+
+ _nodes[element] = geode;
+ parent->asGroup()->addChild(geode);
+}
+void OSGInvoker::updateCapsule(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event) {
+}
+
+void OSGInvoker::processCone(const Arabica::DOM::Node<std::string>& element) {
+ assert(_nodes.find(element.getParentNode()) != _nodes.end());
+ osg::ref_ptr<osg::Node> parent = _nodes[element.getParentNode()];
+
+ float radius = 1;
+ float height = 1;
+ osg::Vec3 center(0,0,0);
+
+ if (HAS_ATTR(element, "radius")) radius = strTo<float>(ATTR(element, "radius"));
+ if (HAS_ATTR(element, "height")) height = strTo<float>(ATTR(element, "height"));
+
+ osg::ref_ptr<osg::Cone> cone = new osg::Cone(center, radius, height);
+ osg::ref_ptr<osg::ShapeDrawable> drawable = new osg::ShapeDrawable(cone);
+ osg::ref_ptr<osg::Geode> geode = new osg::Geode();
+ geode->addDrawable(drawable);
+
+ OSG_SET_COLOR;
+ OSG_SET_MATERIAL;
+
+ _nodes[element] = geode;
+
+ parent->asGroup()->addChild(geode);
+
+}
+void OSGInvoker::updateCone(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event) {
+}
+
+void OSGInvoker::processCylinder(const Arabica::DOM::Node<std::string>& element) {
+ assert(_nodes.find(element.getParentNode()) != _nodes.end());
+ osg::ref_ptr<osg::Node> parent = _nodes[element.getParentNode()];
+
+ float radius = 1;
+ float height = 1;
+ osg::Vec3 center(0,0,0);
+
+ if (HAS_ATTR(element, "radius")) radius = strTo<float>(ATTR(element, "radius"));
+ if (HAS_ATTR(element, "height")) height = strTo<float>(ATTR(element, "height"));
+
+ osg::ref_ptr<osg::Cylinder> cylinder = new osg::Cylinder(center, radius, height);
+ osg::ref_ptr<osg::ShapeDrawable> drawable = new osg::ShapeDrawable(cylinder);
+ osg::ref_ptr<osg::Geode> geode = new osg::Geode();
+ geode->addDrawable(drawable);
+
+ OSG_SET_COLOR;
+ OSG_SET_MATERIAL;
+
+ _nodes[element] = geode;
+
+ parent->asGroup()->addChild(geode);
+
+}
+void OSGInvoker::updateCylinder(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event) {
+}
+
+osg::Vec4 OSGInvoker::getColor(const Arabica::DOM::Node<std::string>& element, const std::string& attr, bool& valid) {
+ if (HAS_ATTR(element, attr)) {
+ std::string color = ATTR(element, attr);
+
+ // is this one of the predefined colors?
+ if (_colors.find(color) != _colors.end()) {
+ valid = true;
+ return _colors[color];
+ }
+
+ // otherwise try to parse as rgba values
+ int i;
+ osg::Vec4 colorVec = parseVec4(color, i);
+
+ if (i == 1) {
+ // only a single value was given, interpret as grey value
+ colorVec[1] = colorVec[2] = colorVec[0]; colorVec[3] = 1.0;
+ valid = true;
+ return colorVec;
+ }
+
+ if (i == 3) {
+ // three values were given, set opacity to max
+ colorVec[3] = 1.0;
+ valid = true;
+ return colorVec;
+ }
+ }
+
+ // return empty reference
+ valid = false;
+ return osg::Vec4();
+}
+
+osg::ref_ptr<osg::Material> OSGInvoker::getMaterial(const Arabica::DOM::Node<std::string>& element) {
+
+ osg::ref_ptr<osg::Material> nodeMat;
+
+ // material color
+ bool hasMatColor;
+ osg::Vec4 matColor = getColor(element, "materialcolor", hasMatColor);
+ if (hasMatColor) {
+ if (!nodeMat)
+ nodeMat = new osg::Material;
+ nodeMat->setDiffuse(osg::Material::FRONT, matColor);
+ nodeMat->setDiffuse(osg::Material::BACK, matColor);
+ }
+
+ // translucency
+ if (HAS_ATTR(element, "transparency")) {
+ std::string transparency = ATTR(element, "transparency");
+ float trans = strTo<float>(transparency);
+ if (!nodeMat)
+ nodeMat = new osg::Material;
+ nodeMat->setTransparency(osg::Material::FRONT, trans);
+ nodeMat->setTransparency(osg::Material::BACK, trans);
+ }
+
+ return nodeMat;
+}
+
+osg::Vec4 OSGInvoker::parseVec4(const std::string& coeffs, int& i) {
+
+ // otherwise try to parse as rgba values
+ std::string coeff;
+ std::stringstream coeffSS(coeffs);
+
+ osg::Vec4 vec;
+
+ i = 0;
+ while(std::getline(coeffSS, coeff, ',')) {
+ boost::trim(coeff);
+ if (coeff.length() == 0)
+ continue;
+ if (!isNumeric(coeff.c_str(), 10))
+ continue;
+
+ vec[i] = strTo<float>(coeff);
+ i++;
+ }
+ return vec;
+}
+
void OSGInvoker::processChildren(const std::set<std::string>& validChildren, const Arabica::DOM::Node<std::string>& element) {
Arabica::DOM::NodeList<std::string> childs = element.getChildNodes();
for (int i = 0; i < childs.getLength(); ++i) {
if (childs.item(i).getNodeType() != Arabica::DOM::Node_base::ELEMENT_NODE)
continue;
if (false) {
- } else if (boost::iequals(LOCALNAME(childs.item(i)), "node") &&
- validChildren.find("node") != validChildren.end()) {
- processNode(childs.item(i));
- } else if (boost::iequals(LOCALNAME(childs.item(i)), "translation") &&
- validChildren.find("translation") != validChildren.end()) {
- processTranslation(childs.item(i));
- } else if (boost::iequals(LOCALNAME(childs.item(i)), "rotation") &&
- validChildren.find("rotation") != validChildren.end()) {
- processRotation(childs.item(i));
- } else if (boost::iequals(LOCALNAME(childs.item(i)), "scale") &&
- validChildren.find("scale") != validChildren.end()) {
- processScale(childs.item(i));
- } else if (boost::iequals(LOCALNAME(childs.item(i)), "viewport") &&
- validChildren.find("viewport") != validChildren.end()) {
- processViewport(childs.item(i));
- } else if (boost::iequals(LOCALNAME(childs.item(i)), "camera") &&
- validChildren.find("camera") != validChildren.end()) {
- processCamera(childs.item(i));
- } else if (boost::iequals(LOCALNAME(childs.item(i)), "display") &&
- validChildren.find("display") != validChildren.end()) {
- processDisplay(childs.item(i));
+ OSG_TAG_HANDLE("node", processNode);
+ OSG_TAG_HANDLE("translation", processTranslation);
+ OSG_TAG_HANDLE("rotation", processRotation);
+ OSG_TAG_HANDLE("scale", processScale);
+ OSG_TAG_HANDLE("viewport", processViewport);
+ OSG_TAG_HANDLE("camera", processCamera);
+ OSG_TAG_HANDLE("display", processDisplay);
+ OSG_TAG_HANDLE("sphere", processSphere);
+ OSG_TAG_HANDLE("box", processBox);
+ OSG_TAG_HANDLE("cone", processCone);
+ OSG_TAG_HANDLE("capsule", processCapsule);
+ OSG_TAG_HANDLE("cylinder", processCylinder);
} else {
LOG(INFO) << "Unknown XML element " << TAGNAME(childs.item(i));
}