diff --git a/calit2/Mugic/CMakeLists.txt b/calit2/Mugic/CMakeLists.txt index 4b2556cf..0c115a88 100644 --- a/calit2/Mugic/CMakeLists.txt +++ b/calit2/Mugic/CMakeLists.txt @@ -20,6 +20,8 @@ SET(PLUGIN_HEADERS shapes/LineShape.h shapes/RectangleShape.h shapes/TextShape.h + shapes/CubeShape.h + shapes/ModelShape.h ) ADD_LIBRARY(${LIB_NAME} @@ -41,6 +43,8 @@ ADD_LIBRARY(${LIB_NAME} shapes/LineShape.cpp shapes/RectangleShape.cpp shapes/TextShape.cpp + shapes/CubeShape.cpp + shapes/ModelShape.cpp ) FIND_PACKAGE(ZMQ REQUIRED) diff --git a/calit2/Mugic/CommandParser.cpp b/calit2/Mugic/CommandParser.cpp index 07fb7e3b..4ec1948a 100644 --- a/calit2/Mugic/CommandParser.cpp +++ b/calit2/Mugic/CommandParser.cpp @@ -7,6 +7,12 @@ #include "shapes/LineShape.h" #include "shapes/RectangleShape.h" #include "shapes/TextShape.h" +#include "shapes/CubeShape.h" +#include "shapes/ModelShape.h" +#include "shapes/CapsuleShape.h" +#include "shapes/SphereShape.h" +#include "shapes/ConeShape.h" +#include "shapes/CylinderShape.h" #include #include @@ -26,6 +32,12 @@ CommandParser::CommandParser(ThreadQueue* queue, MainNode* root) : _shapeDefinitions["line"] = new Factory(); _shapeDefinitions["rectangle"] = new Factory(); _shapeDefinitions["text"] = new Factory(); + _shapeDefinitions["cube"] = new Factory(); + _shapeDefinitions["capsule"] = new Factory(); + _shapeDefinitions["sphere"] = new Factory(); + _shapeDefinitions["cone"] = new Factory(); + _shapeDefinitions["cylinder"] = new Factory(); + _shapeDefinitions["model"] = new Factory(); // init mutex _mutex.lock(); @@ -88,6 +100,41 @@ void CommandParser::parseCommand(std::string command) _shapes[elementName]->update(command); } } + + //command to rotate an object + else if( commandType.compare("rotate") == 0 ) + { + //extract key and look up shape in map + if( _shapes.find(elementName) != _shapes.end() ) + { + //call rotation + rotate(elementName, command); + } + } + + //command to scale an object + else if( commandType.compare("scale") == 0 ) + { + //extract key and look up shape in map + if( _shapes.find(elementName) != _shapes.end() ) + { + //call scaling + scale(elementName, command); + } + } + + //command to translate an object + else if( commandType.compare("translate") == 0 ) + { + //extract key and look up shape in map + if( _shapes.find(elementName) != _shapes.end() ) + { + //call translation + translate(elementName, command); + } + } + + //command to delete all objects else if( commandType.compare("delete") == 0) { if(elementName.compare("all") == 0) @@ -99,6 +146,26 @@ void CommandParser::parseCommand(std::string command) remove(elementName); } } + + //reading in model files + else if( commandType.compare("model") == 0) + { + + //create a new object if it doesn't exist or override old one + remove(elementName); + + //create basic shape that holds the node + ModelShape* newShape = new ModelShape(command, elementName); + + //take the node within the new shape and add it to scenegraph + osg::MatrixTransform* matrix = new osg::MatrixTransform(); + matrix->addChild(newShape->getModelNode()); + _root->addElement(matrix); + + //get name from object, add to table + _shapes[newShape->BasicShape::getName()] = newShape; + } + /* else if( commandType.compare("var") == 0 && !elementName.empty()) // check for variable { @@ -121,7 +188,12 @@ void CommandParser::parseCommand(std::string command) osg::Geode* geode = new osg::Geode(); geode->setDataVariance(osg::Object::DYNAMIC); geode->addDrawable(newShape->asDrawable()); - _root->addElement(geode); + //_root->addElement(geode); + + //add in MatrixTransform for manipulations + osg::MatrixTransform* matrix = new osg::MatrixTransform(); + matrix->addChild(geode); + _root->addElement(matrix); // get name from object created and add to table _shapes[newShape->getName()] = newShape; @@ -137,11 +209,11 @@ void CommandParser::removeAll() { it = _shapes.begin(); - osg::Geode* geode = NULL; + osg::MatrixTransform* mat = NULL; // get geode drawable is attached too - if( (geode = it->second->getParent()) != NULL) + if( (mat = it->second->getMatrixParent()) != NULL) { - _root->removeElement(geode); + _root->removeElement(mat); } // remove old shape from map and scenegraph @@ -156,11 +228,11 @@ void CommandParser::remove(std::string elementName) std::map::iterator it = _shapes.find(elementName); if( it != _shapes.end() ) { - osg::Geode* geode = NULL; + osg::MatrixTransform* mat = NULL; // get geode drawable is attached too - if( (geode = it->second->getParent()) != NULL) + if( (mat = it->second->getMatrixParent()) != NULL) { - _root->removeElement(geode); + _root->removeElement(mat); } // remove old shape from map and scenegraph @@ -190,3 +262,206 @@ CommandParser::~CommandParser() join(); } + +void CommandParser::rotate(std::string elementName, std::string command) +{ + + std::string value; + float head, pitch, roll; + osg::MatrixTransform* matNode; + BasicShape* geoNode; + osg::Matrixd* rotationMat; + osg::Matrixd tempMat; + osg::Vec3d scaleVec; + osg::Vec3d transVec; + float degtorad = osg::PI/180.0; + + //find MatrixTransform parent + geoNode = _shapes[elementName]; + matNode = geoNode->getMatrixParent(); + + //search for pitch + value = getParameter(command, "pitch"); + if( !value.empty()) + { + //extract value from parameter + std::stringstream ss(value); + ss >> pitch; + } + else + pitch = 0.0; + + //search for roll + value = getParameter(command, "roll"); + if( !value.empty() ) + { + //extract value from parameter + std::stringstream ss(value); + ss >> roll; + } + else + roll = 0.0; + + //search for heading + value = getParameter(command, "head"); + if( !value.empty() ) + { + //extract value from parameter + std::stringstream ss(value); + ss >> head; + } + else + head = 0.0; + + //create new matrix to set + rotationMat = new osg::Matrixd(); + rotationMat->makeRotate(pitch*degtorad, osg::Vec3f(1, 0, 0), roll*degtorad, osg::Vec3f(0, 1, 0), head*degtorad, osg::Vec3f(0, 0, 1)); + tempMat = matNode->getMatrix(); + + scaleVec = tempMat.getScale(); + transVec = tempMat.getTrans(); + rotationMat->preMultScale(scaleVec); + rotationMat->postMultTranslate(transVec); + matNode->setMatrix(*rotationMat); + +} + +void CommandParser::scale(std::string elementName, std::string command) +{ + + std::string value; + float xscale, yscale, zscale; + osg::MatrixTransform* matNode; + BasicShape* geoNode; + osg::Matrixd* scaleMat; + osg::Matrixd tempMat; + osg::Quat rotateQuat; + osg::Vec3d transVec; + + //find MatrixTransform parent + geoNode = _shapes[elementName]; + matNode = geoNode->getMatrixParent(); + + //check whether it is uniform scale or not + value = getParameter(command, "factor"); + if( !value.empty() ) + { + //extract value from parameter + std::stringstream ss(value); + ss >> xscale; + yscale = xscale; + zscale = xscale; + } + else + { + //search for xscale + value = getParameter(command, "x"); + if( !value.empty() ) + { + //extract value from parameter + std::stringstream ss(value); + ss >> xscale; + } + else + xscale = 1.0; + + //search for yscale + value = getParameter(command, "y"); + if( !value.empty() ) + { + //extract value from parameter + std::stringstream ss(value); + ss >> yscale; + } + else + yscale = 1.0; + + //search for zscale + value = getParameter(command, "z"); + if( !value.empty() ) + { + //extract value from parameter + std::stringstream ss(value); + ss >> zscale; + } + else + zscale = 1.0; + } + + //create new matrix to set + scaleMat = new osg::Matrixd(); + scaleMat->makeScale(xscale, yscale, zscale); + tempMat = matNode->getMatrix(); + rotateQuat = tempMat.getRotate(); + transVec = tempMat.getTrans(); + scaleMat->postMultRotate(rotateQuat); + scaleMat->postMultTranslate(transVec); + matNode->setMatrix(*scaleMat); + +} + +void CommandParser::translate(std::string elementName, std::string command) +{ + + std::string value; + float xtrans, ytrans, ztrans; + osg::MatrixTransform* matNode; + BasicShape* geoNode; + osg::Matrixd* transMat; + osg::Matrixd rotateMat; + osg::Matrixd scaleMat; + osg::Matrixd tempMat; + osg::Quat rotateQuat; + osg::Vec3d scaleVec; + + //find MatrixTransform parent + geoNode = _shapes[elementName]; + matNode = geoNode->getMatrixParent(); + + //search for xtrans + value = getParameter(command, "x"); + if( !value.empty() ) + { + //extract value from parameter + std::stringstream ss(value); + ss >> xtrans; + } + else + xtrans = 0.0; + + //search for ytrans + value = getParameter(command, "y"); + if( !value.empty() ) + { + //extract value from parameter + std::stringstream ss(value); + ss >> ytrans; + } + else + ytrans = 0.0; + + //search for ztrans + value = getParameter(command, "z"); + if( !value.empty() ) + { + //extract value from parameter + std::stringstream ss(value); + ss >> ztrans; + } + else + ztrans = 0.0; + + //create new matrix to set + transMat = new osg::Matrixd(); + transMat->makeTranslate(xtrans, ytrans, ztrans); + tempMat = matNode->getMatrix(); + rotateQuat = tempMat.getRotate(); + scaleVec = tempMat.getScale(); + transMat->preMultRotate(rotateQuat); + transMat->preMultScale(scaleVec); + matNode->setMatrix(*transMat); + +} + + + diff --git a/calit2/Mugic/CommandParser.h b/calit2/Mugic/CommandParser.h index 7921c4d3..93c8587b 100644 --- a/calit2/Mugic/CommandParser.h +++ b/calit2/Mugic/CommandParser.h @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include "ThreadQueue.h" #include "MainNode.h" @@ -40,6 +42,11 @@ class CommandParser : public OpenThreads::Thread void remove(std::string elementName); void removeAll(); + //MatrixTransform manipulation commands + void rotate(std::string elementName, std::string command); + void scale(std::string elementName, std::string command); + void translate(std::string elementName, std::string command); + public: CommandParser(ThreadQueue* queue, MainNode* root); ~CommandParser(); diff --git a/calit2/Mugic/router/router b/calit2/Mugic/router/router new file mode 100755 index 00000000..f4045fd1 Binary files /dev/null and b/calit2/Mugic/router/router differ diff --git a/calit2/Mugic/shapes/BasicShape.h b/calit2/Mugic/shapes/BasicShape.h index 49cef591..cc81b0a9 100644 --- a/calit2/Mugic/shapes/BasicShape.h +++ b/calit2/Mugic/shapes/BasicShape.h @@ -9,7 +9,7 @@ namespace SimpleShape { - enum ShapeType {POINT, TRIANGLE, QUAD, RECTANGLE, CIRCLE, LINE, TEXT}; + enum ShapeType {POINT, TRIANGLE, QUAD, RECTANGLE, CIRCLE, LINE, TEXT, CUBE, CAPSULE, SPHERE, CONE, CYLINDER, MODEL}; } class BasicShape @@ -18,6 +18,7 @@ class BasicShape virtual void update(std::string command) = 0; virtual osg::Geode* getParent() = 0; + virtual osg::MatrixTransform* getMatrixParent() = 0; virtual osg::Drawable* asDrawable() = 0; SimpleShape::ShapeType getType() { return _type; }; std::string getName(); diff --git a/calit2/Mugic/shapes/CapsuleShape.cpp b/calit2/Mugic/shapes/CapsuleShape.cpp new file mode 100644 index 00000000..b4488e8c --- /dev/null +++ b/calit2/Mugic/shapes/CapsuleShape.cpp @@ -0,0 +1,195 @@ +/* Capsule Shape for Mugic */ + +#include "CapsuleShape.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +/*Constructor for Capsule*/ +CapsuleShape::CapsuleShape(std::string command, std::string name) +{ + + _type = SimpleShape::CAPSULE; + BasicShape::setName(name); + + //create capsule and add to geode as shape drawable + _capsule = new osg::Capsule(); + setShape(_capsule); + + setPosition(osg::Vec3(0.0, 0.0, 0.0), 1.0, 1.0); + setShapeColor(osg::Vec4(1.0, 1.0, 1.0, 1.0)); + update(command); + + osg::StateSet* state = getOrCreateStateSet(); + state -> setMode(GL_BLEND, osg::StateAttribute::ON); + + osg::Material* mat = new osg::Material(); + mat -> setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); + state -> setAttributeAndModes(mat, osg::StateAttribute::ON); + + setShaders("", ""); + +} + +/*Destructor*/ +CapsuleShape::~CapsuleShape() +{ +} + +/*set Position of Capsule - radius and height*/ +void CapsuleShape::setPosition(osg::Vec3 position, float radius, float height) +{ + + _capsule->setRadius(radius); + _capsule->setHeight(height); + _capsule->setCenter(position); + + _radius = radius; + _height = height; + _center = position; + + //for update purposes + dirtyDisplayList(); + +} + +/*set Color of Capsule*/ +void CapsuleShape::setShapeColor(osg::Vec4 color) +{ + + setColor(color); + _color = color; + + if(color[3] != 1.0) + getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + else + getOrCreateStateSet()->setRenderingHint(osg::StateSet::DEFAULT_BIN); + +} + +/*set Shaders for Capsule*/ +void CapsuleShape::setShaders(std::string vert_file, std::string frag_file) +{ + + if(vert_file.compare(_vertex_shader) == 0 && frag_file.compare(_fragment_shader) == 0) + return; + + osg::StateSet* state = getOrCreateStateSet(); + osg::Program* prog = new osg::Program(); + osg::Shader* vert = new osg::Shader(osg::Shader::VERTEX); + osg::Shader* frag = new osg::Shader(osg::Shader::FRAGMENT); + + _vertex_shader = vert_file; + _fragment_shader = frag_file; + + //try to load shader files + std::string file_path = cvr::ConfigManager::getEntry("dir", "Plugin.Mugic.Shader", ""); + if(!_vertex_shader.empty()) + { + + bool loaded = vert->loadShaderSourceFromFile(file_path + _vertex_shader); + if(!loaded) + { + std::cout << "could not load vertex shader." << std::endl; + _vertex_shader = ""; + } + else + { + prog->addShader(vert); + } + + } + + if(!_fragment_shader.empty()) + { + + bool loaded = frag->loadShaderSourceFromFile(file_path + _fragment_shader); + if(!loaded) + { + std::cout << "could not load fragment shader." << std::endl; + _fragment_shader = ""; + } + else + { + prog->addShader(frag); + } + + } + + state->setAttributeAndModes(prog, osg::StateAttribute::ON); + +} + +/*update capsule with passed command*/ +void CapsuleShape::update(std::string command) +{ + + OpenThreads::ScopedLock lock(_mutex); + _dirty = true; + + //check for changed values + addParameter(command, "radius"); + addParameter(command, "height"); + + addParameter(command, "x"); + addParameter(command, "y"); + addParameter(command, "z"); + + addParameter(command, "r1"); + addParameter(command, "g1"); + addParameter(command, "b1"); + addParameter(command, "a1"); + + addParameter(command, "vertex"); + addParameter(command, "fragment"); + +} + + +/*update*/ +void CapsuleShape::update() +{ + + OpenThreads::ScopedLock lock(_mutex); + if(!_dirty) + return; + + float radius = _radius; + float height = _height; + osg::Vec3 center = _center; + osg::Vec4 color = _color; + std::string vert = _vertex_shader; + std::string frag = _fragment_shader; + + setParameter("radius", radius); + setParameter("height", height); + + setParameter("x", center.x()); + setParameter("y", center.y()); + setParameter("z", center.z()); + + setParameter("r1", color[0]); + setParameter("g1", color[1]); + setParameter("b1", color[2]); + setParameter("a1", color[3]); + + setParameter("vertex", vert); + setParameter("fragment", frag); + + setPosition(center, radius, height); + setShapeColor(color); + setShaders(vert, frag); + dirtyBound(); + + //reset flag + _dirty = false; + +} + diff --git a/calit2/Mugic/shapes/CapsuleShape.h b/calit2/Mugic/shapes/CapsuleShape.h new file mode 100644 index 00000000..18de46d4 --- /dev/null +++ b/calit2/Mugic/shapes/CapsuleShape.h @@ -0,0 +1,24 @@ +#ifndef _CAPSULE_SHAPE_H_ +#define _CAPSULE_SHAPE_H_ + +#include "DrawableShape.h" + +class CapsuleShape : public DrawableShape +{ + + public: + CapsuleShape(std::string command = "", std::string name = ""); + virtual ~CapsuleShape(); + void update(std::string); + + protected: + CapsuleShape(); + void setPosition(osg::Vec3 position, float radius, float height); + void setShapeColor(osg::Vec4); + void setShaders(std::string, std::string); + void update(); + osg::Capsule* _capsule; //actual shape + +}; + +#endif diff --git a/calit2/Mugic/shapes/CircleShape.cpp b/calit2/Mugic/shapes/CircleShape.cpp index 4960fbe7..292e52cf 100644 --- a/calit2/Mugic/shapes/CircleShape.cpp +++ b/calit2/Mugic/shapes/CircleShape.cpp @@ -2,6 +2,9 @@ #include #include +#include +#include +#include #include #include @@ -16,13 +19,22 @@ CircleShape::CircleShape(std::string command, std::string name) _vertices = new osg::Vec3Array(_numFaces + 2); _colors = new osg::Vec4Array(_numFaces + 2); + _textures = new osg::Vec2Array (_numFaces + 2); + + //normal setup here + _normals = new osg::Vec3Array(1); + (*_normals)[0].set(0.0, -1.0, 0.0); setPosition(osg::Vec3(0.0, 0.0, 0.0), 1.0); - setColor(osg::Vec4(1.0, 0.0, 0.0, 1.0),osg::Vec4(0.0, 1.0, 0.0, 1.0)); + setColor(osg::Vec4(1.0, 1.0, 1.0, 1.0),osg::Vec4(1.0, 1.0, 1.0, 1.0)); + setTextureCoords(osg::Vec2(0.5, 0.5), 0.5); update(command); setVertexArray(_vertices); - setColorArray(_colors); + setColorArray(_colors); + setTexCoordArray(0, _textures); + setNormalArray(_normals); + setNormalBinding(osg::Geometry::BIND_OVERALL); setColorBinding(osg::Geometry::BIND_PER_VERTEX); addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN,0,_numFaces + 2)); @@ -32,6 +44,9 @@ CircleShape::CircleShape(std::string command, std::string name) //osg::Material* mat = new osg::Material(); //mat->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); //state->setAttributeAndModes(mat, osg::StateAttribute::ON); + + setTextureImage(""); + setShaders("", ""); } CircleShape::~CircleShape() @@ -71,6 +86,131 @@ void CircleShape::setColor(osg::Vec4 c0, osg::Vec4 c1) getOrCreateStateSet()->setRenderingHint(osg::StateSet::DEFAULT_BIN); } +void CircleShape::setTextureCoords(osg::Vec2 center, float radius) +{ + + //first texture coordinate is center of circle + if(center[0] < 1.0 && center[1] < 1.0 ) + { + if(center[0] > 0 && center[1] > 0) + { + (*_textures)[0].set(center[0], center[1]); + _texRadius = radius; + } + } + + //check whether radius goes out of bounds here + float xposadd, yposadd, xpossub, ypossub; + xposadd = center[0]+radius; + yposadd = center[1]+radius; + xpossub = center[0]-radius; + ypossub = center[1]-radius; + + if(xposadd > 1.0 || yposadd > 1.0 || xpossub < 0 || ypossub < 0) + return; + + //then calculate the other coordinates according to given radius + float portion = -osg::PI * 2 / _numFaces; + osg::Vec2d pos; + + for(int i = 1; i < _numFaces + 2; i++) + { + pos = center; + pos[0] += cos(portion * i) * radius; + pos[1] += sin(portion * i) * radius; + (*_textures)[i].set(pos[0], pos[1]); + } + +} + +void CircleShape::setTextureImage(std::string tex_name) +{ + + osg::StateSet* state = getOrCreateStateSet(); + osg::Texture2D* tex = new osg::Texture2D; + osg::Image* image = new osg::Image; + tex->setDataVariance(osg::Object::DYNAMIC); + + //Whether to load an image or not + if(tex_name.empty()) + { + _texture_name = ""; + tex->setImage(image); + state->setTextureAttributeAndModes(0, tex, osg::StateAttribute::OFF); + } + else + { + std::string file_path = cvr::ConfigManager::getEntry("dir", "Plugin.Mugic.Texture", ""); + _texture_name = file_path + tex_name; + image = osgDB::readImageFile(_texture_name); + + //testing + if(!image) + { + std::cout << "Image does not exist." << std::endl; + _texture_name = ""; + state->setTextureAttributeAndModes(0, tex, osg::StateAttribute::OFF); + return; + } + + tex->setImage(image); + state->setTextureAttributeAndModes(0, tex, osg::StateAttribute::ON); + } + +} + +void CircleShape::setShaders(std::string vert_file, std::string frag_file) +{ + + if(vert_file.compare(_vertex_shader) == 0 && frag_file.compare(_fragment_shader) == 0) + return; + + osg::StateSet* state = getOrCreateStateSet(); + osg::Program* prog = new osg::Program(); + osg::Shader* vert = new osg::Shader(osg::Shader::VERTEX); + osg::Shader* frag = new osg::Shader(osg::Shader::FRAGMENT); + + _vertex_shader = vert_file; + _fragment_shader = frag_file; + + //try to load shader files + std::string file_path = cvr::ConfigManager::getEntry("dir", "Plugin.Mugic.Shader", ""); + if(!_vertex_shader.empty()) + { + + bool loaded = vert->loadShaderSourceFromFile(file_path + _vertex_shader); + if(!loaded) + { + std::cout << "could not load vertex shader." << std::endl; + _vertex_shader = ""; + } + else + { + prog->addShader(vert); + } + + } + + if(!_fragment_shader.empty()) + { + + bool loaded = frag->loadShaderSourceFromFile(file_path + _fragment_shader); + if(!loaded) + { + std::cout << "could not load fragment shader." << std::endl; + _fragment_shader = ""; + } + else + { + prog->addShader(frag); + } + + } + + state->setAttributeAndModes(prog, osg::StateAttribute::ON); + +} + void CircleShape::update(std::string command) { OpenThreads::ScopedLock lock(_mutex); @@ -91,6 +231,12 @@ void CircleShape::update(std::string command) addParameter(command, "b2"); addParameter(command, "a2"); addParameter(command, "radius"); + addParameter(command, "texture"); + addParameter(command, "texcenters"); + addParameter(command, "texcentert"); + addParameter(command, "texrad"); + addParameter(command, "vertex"); + addParameter(command, "fragment"); } } @@ -104,6 +250,11 @@ void CircleShape::update() osg::Vec4 c1((*_colors)[0]); osg::Vec4 c2((*_colors)[1]); float radius = (*_vertices)[1].x() - (*_vertices)[0].x(); + osg::Vec2 texCenter((*_textures)[0]); + float texRad = _texRadius; + std::string tex_name = _texture_name; + std::string vert_name = _vertex_shader; + std::string frag_name = _fragment_shader; setParameter("x", p1.x()); setParameter("y", p1.y()); @@ -116,12 +267,22 @@ void CircleShape::update() setParameter("r2", c2.r()); setParameter("g2", c2.g()); setParameter("b2", c2.b()); - setParameter("a2", c2.a()); + setParameter("a2", c2.a()); + setParameter("texture", tex_name); + setParameter("texcenters", texCenter[0]); + setParameter("texcentert", texCenter[1]); + setParameter("texrad", texRad); + setParameter("vertex", vert_name); + setParameter("fragment", frag_name); setPosition(p1, radius); setColor(c1, c2); + setTextureCoords(texCenter, texRad); + setTextureImage(tex_name); + setShaders(vert_name, frag_name); _vertices->dirty(); _colors->dirty(); + _textures->dirty(); dirtyBound(); // reset flag diff --git a/calit2/Mugic/shapes/CircleShape.h b/calit2/Mugic/shapes/CircleShape.h index 8f6b1e9c..87054ee1 100644 --- a/calit2/Mugic/shapes/CircleShape.h +++ b/calit2/Mugic/shapes/CircleShape.h @@ -17,8 +17,12 @@ class CircleShape : public GeometryShape CircleShape(); void setPosition(osg::Vec3, float); void setColor(osg::Vec4, osg::Vec4); + void setTextureCoords(osg::Vec2, float); + void setTextureImage(std::string); + void setShaders(std::string, std::string); void update(); int _numFaces; + float _texRadius; }; #endif diff --git a/calit2/Mugic/shapes/ConeShape.cpp b/calit2/Mugic/shapes/ConeShape.cpp new file mode 100644 index 00000000..69daec6f --- /dev/null +++ b/calit2/Mugic/shapes/ConeShape.cpp @@ -0,0 +1,194 @@ +/* Cone Shape for Mugic */ + +#include "ConeShape.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +/* Constructor */ +ConeShape::ConeShape(std::string command, std::string name) +{ + + _type = SimpleShape::CONE; + BasicShape::setName(name); + + //create cone and add to geode as shape drawable + _cone = new osg::Cone(); + setShape(_cone); + + setPosition(osg::Vec3(0.0, 0.0, 0.0), 0.5, 1.0); + setShapeColor(osg::Vec4(1.0, 1.0, 1.0, 1.0)); + update(command); + + osg::StateSet* state = getOrCreateStateSet(); + state -> setMode(GL_BLEND, osg::StateAttribute::ON); + + osg::Material* mat = new osg::Material(); + mat -> setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); + state -> setAttributeAndModes(mat, osg::StateAttribute::ON); + + setShaders("", ""); + +} + +/* Destructor */ +ConeShape::~ConeShape() +{ +} + +/* set position of cone - radius and height */ +void ConeShape::setPosition(osg::Vec3 position, float radius, float height) +{ + + _cone->setRadius(radius); + _cone->setHeight(height); + _cone->setCenter(position); + + _radius = radius; + _height = height; + _center = position; + + //for update purposes + dirtyDisplayList(); + +} + +/* set color of cone */ +void ConeShape::setShapeColor(osg::Vec4 color) +{ + + setColor(color); + _color = color; + + if(color[3] != 1.0) + getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + else + getOrCreateStateSet()->setRenderingHint(osg::StateSet::DEFAULT_BIN); + +} + +/* set shaders for cone*/ +void ConeShape::setShaders(std::string vert_file, std::string frag_file) +{ + + if(vert_file.compare(_vertex_shader) == 0 && frag_file.compare(_fragment_shader) == 0) + return; + + osg::StateSet* state = getOrCreateStateSet(); + osg::Program* prog = new osg::Program(); + osg::Shader* vert = new osg::Shader(osg::Shader::VERTEX); + osg::Shader* frag = new osg::Shader(osg::Shader::FRAGMENT); + + _vertex_shader = vert_file; + _fragment_shader = frag_file; + + //try to load shader files + std::string file_path = cvr::ConfigManager::getEntry("dir", "Plugin.Mugic.Shader", ""); + if(!_vertex_shader.empty()) + { + + bool loaded = vert->loadShaderSourceFromFile(file_path + _vertex_shader); + if(!loaded) + { + std::cout << "could not load vertex shader." << std::endl; + _vertex_shader = ""; + } + else + { + prog->addShader(vert); + } + + } + + if(!_fragment_shader.empty()) + { + + bool loaded = frag->loadShaderSourceFromFile(file_path + _fragment_shader); + if(!loaded) + { + std::cout << "could not load fragment shader." << std::endl; + _fragment_shader = ""; + } + else + { + prog->addShader(frag); + } + + } + + state->setAttributeAndModes(prog, osg::StateAttribute::ON); + +} + +/* update with command */ +void ConeShape::update(std::string command) +{ + + OpenThreads::ScopedLock lock(_mutex); + _dirty = true; + + //check for changed values + addParameter(command, "radius"); + addParameter(command, "height"); + + addParameter(command, "x"); + addParameter(command, "y"); + addParameter(command, "z"); + + addParameter(command, "r1"); + addParameter(command, "g1"); + addParameter(command, "b1"); + addParameter(command, "a1"); + + addParameter(command, "vertex"); + addParameter(command, "fragment"); + +} + +/* update */ +void ConeShape::update() +{ + + OpenThreads::ScopedLock lock(_mutex); + if(!_dirty) + return; + + float radius = _radius; + float height = _height; + osg::Vec3 center = _center; + osg::Vec4 color = _color; + std::string vert = _vertex_shader; + std::string frag = _fragment_shader; + + setParameter("radius", radius); + setParameter("height", height); + + setParameter("x", center.x()); + setParameter("y", center.y()); + setParameter("z", center.z()); + + setParameter("r1", color[0]); + setParameter("g1", color[1]); + setParameter("b1", color[2]); + setParameter("a1", color[3]); + + setParameter("vertex", vert); + setParameter("fragment", frag); + + setPosition(center, radius, height); + setShapeColor(color); + setShaders(vert, frag); + dirtyBound(); + + //reset flag + _dirty = false; + +} + diff --git a/calit2/Mugic/shapes/ConeShape.h b/calit2/Mugic/shapes/ConeShape.h new file mode 100644 index 00000000..73913df4 --- /dev/null +++ b/calit2/Mugic/shapes/ConeShape.h @@ -0,0 +1,24 @@ +#ifndef _CONE_SHAPE_H_ +#define _CONE_SHAPE_H_ + +#include "DrawableShape.h" + +class ConeShape : public DrawableShape +{ + + public: + ConeShape(std::string command = "", std::string name = ""); + virtual ~ConeShape(); + void update(std::string); + + protected: + ConeShape(); + void setPosition(osg::Vec3 position, float radius, float height); + void setShapeColor(osg::Vec4); + void setShaders(std::string, std::string); + void update(); + osg::Cone* _cone; //actual shape + +}; + +#endif diff --git a/calit2/Mugic/shapes/CubeShape.cpp b/calit2/Mugic/shapes/CubeShape.cpp new file mode 100644 index 00000000..4f7e4aae --- /dev/null +++ b/calit2/Mugic/shapes/CubeShape.cpp @@ -0,0 +1,506 @@ +/* Cube Shape for Mugic */ + +#include "CubeShape.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* Constructor for Cube */ +CubeShape::CubeShape(std::string command, std::string name) +{ + + _type = SimpleShape::CUBE; + BasicShape::setName(name); + + _vertices = new osg::Vec3Array(24); + _colors = new osg::Vec4Array(24); + _textures = new osg::Vec2Array(24); + _normals = new osg::Vec3Array(24); + + setPosition( osg::Vec3(0.0, 0.0, 0.0), 1.0, 1.0, 1.0 ); + setColor( osg::Vec4(1.0, 1.0, 1.0, 1.0), osg::Vec4(1.0, 1.0, 1.0, 1.0), osg::Vec4(1.0, 1.0, 1.0, 1.0), osg::Vec4(1.0, 1.0, 1.0, 1.0), + osg::Vec4(1.0, 1.0, 1.0, 1.0), osg::Vec4(1.0, 1.0, 1.0, 1.0), osg::Vec4(1.0, 1.0, 1.0, 1.0), osg::Vec4(1.0, 1.0, 1.0, 1.0)); + setTextureCoords(); //only happens once + setNormals(); //also only happens once + update(command); + + setVertexArray(_vertices); + setColorArray(_colors); + setNormalArray(_normals); + setNormalBinding(osg::Geometry::BIND_PER_VERTEX); + setTexCoordArray(0, _textures); + setColorBinding(osg::Geometry::BIND_PER_VERTEX); + + //properly add all faces here using addPrimitiveSet - using indices for desired vertex combinations + unsigned short front_indices[] = {0, 1, 2, 3}; + unsigned short right_indices[] = {4, 5, 6, 7}; + unsigned short back_indices[] = {8, 9, 10, 11}; + unsigned short left_indices[] = {12, 13, 14, 15}; + unsigned short top_indices[] = {16, 17, 18, 19}; + unsigned short bottom_indices[] = {20, 21, 22, 23}; + + addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::QUADS, 4, front_indices )); + addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::QUADS, 4, right_indices)); + addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::QUADS, 4, back_indices)); + addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::QUADS, 4, left_indices)); + addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::QUADS, 4, top_indices)); + addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::QUADS, 4, bottom_indices)); + + osg::StateSet* state = getOrCreateStateSet(); + state -> setMode(GL_BLEND, osg::StateAttribute::ON); + + osg::Material* mat = new osg::Material(); + mat -> setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); + state -> setAttributeAndModes(mat, osg::StateAttribute::ON); + + setTextureImage(""); + setShaders("", ""); + +} + + +/* Destructor */ +CubeShape::~CubeShape() +{ +} + + +/* Set position of the Cube - need 8 vertices */ +void CubeShape::setPosition(osg::Vec3 p, float width, float height, float depth ) +{ + + //front face + (*_vertices)[0].set( p[0] - (width/2), p[1] - (depth/2), p[2] - (height/2) ); //bottom left front + (*_vertices)[1].set( p[0] + (width/2), p[1] - (depth/2), p[2] - (height/2) ); //bottom right front + (*_vertices)[2].set( p[0] + (width/2), p[1] - (depth/2), p[2] + (height/2) ); //top right front + (*_vertices)[3].set( p[0] - (width/2), p[1] - (depth/2), p[2] + (height/2) ); //top left front + + //right face + (*_vertices)[4].set( p[0] + (width/2), p[1] - (depth/2), p[2] - (height/2) ); //bottom right front + (*_vertices)[5].set( p[0] + (width/2), p[1] + (depth/2), p[2] - (height/2) ); //bottom right back + (*_vertices)[6].set( p[0] + (width/2), p[1] + (depth/2), p[2] + (height/2) ); //top right back + (*_vertices)[7].set( p[0] + (width/2), p[1] - (depth/2), p[2] + (height/2) ); //top right front + + //back face + (*_vertices)[8].set( p[0] + (width/2), p[1] + (depth/2), p[2] - (height/2) ); //bottom right back + (*_vertices)[9].set( p[0] - (width/2), p[1] + (depth/2), p[2] - (height/2) ); //bottom left back + (*_vertices)[10].set( p[0] - (width/2), p[1] + (depth/2), p[2] + (height/2) ); //top left back + (*_vertices)[11].set( p[0] + (width/2), p[1] + (depth/2), p[2] + (height/2) ); //top right back + + //left face + (*_vertices)[12].set( p[0] - (width/2), p[1] + (depth/2), p[2] - (height/2) ); //bottom left back + (*_vertices)[13].set( p[0] - (width/2), p[1] - (depth/2), p[2] - (height/2) ); //bottom left front + (*_vertices)[14].set( p[0] - (width/2), p[1] - (depth/2), p[2] + (height/2) ); //top left front + (*_vertices)[15].set( p[0] - (width/2), p[1] + (depth/2), p[2] + (height/2) ); //top left back + + //top face + + (*_vertices)[16].set( p[0] - (width/2), p[1] - (width/2), p[2] + (height/2) ); //top left front + (*_vertices)[17].set( p[0] + (width/2), p[1] - (width/2), p[2] + (height/2) ); //top right front + (*_vertices)[18].set( p[0] + (width/2), p[1] + (depth/2), p[2] + (height/2) ); //top right back + (*_vertices)[19].set( p[0] - (width/2), p[1] + (depth/2), p[2] + (height/2) ); //top left back + + //bottom face + (*_vertices)[20].set( p[0] - (width/2), p[1] + (depth/2), p[2] - (height/2) ); //bottom left back + (*_vertices)[21].set( p[0] + (width/2), p[1] + (depth/2), p[2] - (height/2) ); //bottom right back + (*_vertices)[22].set( p[0] + (width/2), p[1] - (depth/2), p[2] - (height/2) ); //bottom right front + (*_vertices)[23].set( p[0] - (width/2), p[1] - (depth/2), p[2] - (height/2) ); //bottom left front + +} + +/* set Color of the Cube - can set for each vertex */ +void CubeShape::setColor(osg::Vec4 c0, osg::Vec4 c1, osg::Vec4 c2, osg::Vec4 c3, + osg::Vec4 c4, osg::Vec4 c5, osg::Vec4 c6, osg::Vec4 c7) +{ + + //front face + (*_colors)[0].set( c0[0], c0[1], c0[2], c0[3] ); //bottom left front + (*_colors)[1].set( c1[0], c1[1], c1[2], c1[3] ); //bottom right front + (*_colors)[2].set( c5[0], c5[1], c5[2], c5[3] ); //top right front + (*_colors)[3].set( c4[0], c4[1], c4[2], c4[3] ); //top left front + + //right face + (*_colors)[4].set( c1[0], c1[1], c1[2], c1[3] ); //bottom right front + (*_colors)[5].set( c2[0], c2[1], c2[2], c2[3] ); //bottom right back + + (*_colors)[6].set( c6[0], c6[1], c6[2], c6[3] ); //topenscenegraph setting normalsop right back + (*_colors)[7].set( c5[0], c5[1], c5[2], c5[3] ); //top right front + + //back face + (*_colors)[8].set( c2[0], c2[1], c2[2], c2[3] ); //bottom right back + (*_colors)[9].set( c3[0], c3[1], c3[2], c3[3] ); //bottom left back + (*_colors)[10].set( c7[0], c7[1], c7[2], c7[3] ); //top left back + (*_colors)[11].set( c6[0], c6[1], c6[2], c6[3] ); //top right back + + //left face + (*_colors)[12].set( c3[0], c3[1], c3[2], c3[3] ); //bottom left back + (*_colors)[13].set( c0[0], c0[1], c0[2], c0[3] ); //bottom left front + (*_colors)[14].set( c4[0], c4[1], c4[2], c4[3] ); //top left front + (*_colors)[15].set( c7[0], c7[1], c7[2], c7[3] ); //top left back + + //top face + (*_colors)[16].set( c4[0], c4[1], c4[2], c4[3] ); //top left front + (*_colors)[17].set( c5[0], c5[1], c5[2], c5[3] ); //top right front + (*_colors)[18].set( c6[0], c6[1], c6[2], c6[3] ); //top right back + (*_colors)[19].set( c7[0], c7[1], c7[2], c7[3] ); //top left back + + //bottom face + (*_colors)[20].set( c3[0], c3[1], c3[2], c3[3] ); //bottom left back + (*_colors)[21].set( c2[0], c2[1], c2[2], c2[3] ); //bottom right back + (*_colors)[22].set( c1[0], c1[1], c1[2], c1[3] ); //openscenegraph setting normalsbottom right front + (*_colors)[23].set( c0[0], c0[1], c0[2], c0[3] ); //bottom left front + + //if w is not 1.0, then opacity in effect? + if( c0[3] != 1.0 || c1[3] != 1.0 || c2[3] != 1.0 || c3[3] != 1.0 || + c4[3] != 1.0 || c5[3] != 1.0 || c6[3] != 1.0 || c7[3] != 1.0) + getOrCreateStateSet() -> setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + else + getOrCreateStateSet() -> setRenderingHint(osg::StateSet::DEFAULT_BIN); + +} + +void CubeShape::setNormals() +{ + + //front face + (*_normals)[0].set(0.0, -1.0, 0.0); + (*_normals)[1].set(0.0, -1.0, 0.0); + (*_normals)[2].set(0.0, -1.0, 0.0); + (*_normals)[3].set(0.0, -1.0, 0.0); + + //right face + (*_normals)[4].set(1.0, 0.0, 0.0); + (*_normals)[5].set(1.0, 0.0, 0.0); + (*_normals)[6].set(1.0, 0.0, 0.0); + (*_normals)[7].set(1.0, 0.0, 0.0); + + //back face + (*_normals)[8].set(0.0, 1.0, 0.0); + (*_normals)[9].set(0.0, 1.0, 0.0); + (*_normals)[10].set(0.0, 1.0, 0.0); + (*_normals)[11].set(0.0, 1.0, 0.0); + + //left face + (*_normals)[12].set(-1.0, 0.0, 0.0); + (*_normals)[13].set(-1.0, 0.0, 0.0); + (*_normals)[14].set(-1.0, 0.0, 0.0); + (*_normals)[15].set(-1.0, 0.0, 0.0); + + //top face + (*_normals)[16].set(0.0, 0.0, 1.0); + (*_normals)[17].set(0.0, 0.0, 1.0); + (*_normals)[18].set(0.0, 0.0, 1.0); + (*_normals)[19].set(0.0, 0.0, 1.0); + + //bottom face + (*_normals)[20].set(0.0, 0.0, -1.0); + (*_normals)[21].set(0.0, 0.0, -1.0); + (*_normals)[22].set(0.0, 0.0, -1.0); + (*_normals)[23].set(0.0, 0.0, -1.0); + +} + +void CubeShape::setTextureCoords() +{ + + //this is only set once, for convenience sake + //front faceube texturing + (*_textures)[0].set( 0.3333333, 0.5 ); //bottom left front + (*_textures)[1].set( 0.6666666, 0.5 ); //bottom right front + (*_textures)[2].set( 0.6666666, 0.75 ); //top right front + (*_textures)[3].set( 0.3333333, 0.75 ); //top left front + + //right face + (*_textures)[4].set( 0.6666666, 0.5 ); //bottom right front + (*_textures)[5].set( 1.0, 0.5 ); //bottom right back + (*_textures)[6].set( 1.0, 0.75 ); //top right back + (*_textures)[7].set( 0.6666666, 0.75 ); //top right front + + //back face + + (*_textures)[8].set( 0.6666666, 0.25 ); //bottom right back + (*_textures)[9].set( 0.3333333, 0.25 ); //bottom left back + (*_textures)[10].set( 0.3333333, 0.0 ); //top left back + (*_textures)[11].set( 0.6666666, 0.0 ); //top right back + + //left face + (*_textures)[12].set( 0.0, 0.5 ); //bottom left back + (*_textures)[13].set( 0.3333333, 0.5 ); //bottom left front + (*_textures)[14].set( 0.3333333, 0.75 ); //top left front + (*_textures)[15].set( 0.0, 0.75 ); //top left back + + //top face + (*_textures)[16].set( 0.3333333, 0.75 ); //top left front + (*_textures)[17].set( 0.6666666, 0.75 ); //top right front + (*_textures)[18].set( 0.6666666, 1.0 ); //top right back + (*_textures)[19].set( 0.3333333, 1.0 ); //top left back + + //bottom face + (*_textures)[20].set( 0.3333333, 0.25 ); //bottom left back + (*_textures)[21].set( 0.6666666, 0.25 ); //bottom right back + (*_textures)[22].set( 0.6666666, 0.5 ); //bottom right front + (*_textures)[23].set( 0.3333333, 0.5 ); //bottom left front + +} + +void CubeShape::setTextureImage(std::string tex_name) +{ + + + osg::StateSet* state = getOrCreateStateSet(); + osg::Texture2D* tex = new osg::Texture2D; + osg::Image* image = new osg::Image; + tex->setDataVariance(osg::Object::DYNAMIC); + + //Whether to load an image or not + if(tex_name.empty()) + { + _texture_name = ""; + tex->setImage(image); + state->setTextureAttributeAndModes(0, tex, osg::StateAttribute::OFF); + } + else + { + std::string file_path = cvr::ConfigManager::getEntry("dir", "Plugin.Mugic.Texture", ""); + _texture_name = file_path + tex_name; + image = osgDB::readImageFile(_texture_name); + + //testing + if(!image) + { + std::cout << "Image does not exist." << std::endl; + _texture_name = ""; + state->setTextureAttributeAndModes(0, tex, osg::StateAttribute::OFF); + return; + } + + tex->setImage(image); + state->setTextureAttributeAndModes(0, tex, osg::StateAttribute::ON); + } + +} + +void CubeShape::setShaders(std::string vert_file, std::string frag_file) +{ + + if(vert_file.compare(_vertex_shader) == 0 && frag_file.compare(_fragment_shader) == 0) + return; + + osg::StateSet* state = getOrCreateStateSet(); + osg::Program* prog = new osg::Program(); + osg::Shader* vert = new osg::Shader(osg::Shader::VERTEX); + osg::Shader* frag = new osg::Shader(osg::Shader::FRAGMENT); + + _vertex_shader = vert_file; + _fragment_shader = frag_file; + + //try to load shader files + std::string file_path = cvr::ConfigManager::getEntry("dir", "Plugin.Mugic.Shader", ""); + if(!_vertex_shader.empty()) + { + + bool loaded = vert->loadShaderSourceFromFile(file_path + _vertex_shader); + if(!loaded) + { + std::cout << "could not load vertex shader." << std::endl; + _vertex_shader = ""; + } + else + { + prog->addShader(vert); + } + + } + + if(!_fragment_shader.empty()) + { + + bool loaded = frag->loadShaderSourceFromFile(file_path + _fragment_shader); + if(!loaded) + { + std::cout << "could not load fragment shader." << std::endl; + _fragment_shader = ""; + } + else + { + prog->addShader(frag); + } + + } + + state->setAttributeAndModes(prog, osg::StateAttribute::ON); + +} + +/* update Cube with passed command */ +void CubeShape::update(std::string command) +{ + + OpenThreads::ScopedLock lock(_mutex); + _dirty = true; + + //check for changed values + addParameter(command, "x"); + addParameter(command, "y"); + addParameter(command, "z"); + + addParameter(command, "width"); + addParameter(command, "height"); + addParameter(command, "depth"); + + addParameter(command, "r1"); + addParameter(command, "g1"); + addParameter(command, "b1"); + addParameter(command, "a1"); + + addParameter(command, "r2"); + addParameter(command, "g2"); + addParameter(command, "b2"); + addParameter(command, "a2"); + + addParameter(command, "r3"); + addParameter(command, "g3"); + addParameter(command, "b3"); + addParameter(command, "a3"); + + addParameter(command, "r4"); + addParameter(command, "g4"); + addParameter(command, "b4"); + addParameter(command, "a4"); + + addParameter(command, "r5"); + addParameter(command, "g5"); + addParameter(command, "b5"); + addParameter(command, "a5"); + + addParameter(command, "r6"); + addParameter(command, "g6"); + addParameter(command, "b6"); + addParameter(command, "a6"); + + addParameter(command, "r7"); + addParameter(command, "g7"); + addParameter(command, "b7"); + addParameter(command, "a7"); + + addParameter(command, "r8"); + addParameter(command, "g8"); + addParameter(command, "b8"); + addParameter(command, "a8"); + + addParameter(command, "texture"); + + addParameter(command, "vertex"); + addParameter(command, "fragment"); + +} + +/* update Cube if parameters have changed recently */ +void CubeShape::update() +{ + + OpenThreads::ScopedLock lock(_mutex); + if(!_dirty) + return; + + osg::Vec3 p1( (*_vertices)[0] ); + osg::Vec4 c1( (*_colors)[0] ); + osg::Vec4 c2( (*_colors)[1] ); + osg::Vec4 c3( (*_colors)[2] ); + osg::Vec4 c4( (*_colors)[3] ); + osg::Vec4 c5( (*_colors)[4] ); + osg::Vec4 c6( (*_colors)[5] ); + osg::Vec4 c7( (*_colors)[6] ); + osg::Vec4 c8( (*_colors)[7] ); + + float width = (*_vertices)[1].x() - (*_vertices)[0].x(); + float height = (*_vertices)[3].z() - (*_vertices)[0].z(); + float depth = (*_vertices)[5].y() - (*_vertices)[0].y(); + + std::string tex_name = _texture_name; + std::string vert_name = _vertex_shader; + std::string frag_name = _fragment_shader; + + //adjust center position + p1.x() = p1.x() + (width/2); + p1.y() = p1.y() + (depth/2); + p1.z() = p1.z() + (height/2); + + setParameter("x", p1.x()); + setParameter("y", p1.y()); + setParameter("z", p1.z()); + + setParameter("width", width); + setParameter("height", height); + setColor( c1, c2, c3, c4, c5, c6, c7, c8 ); + setParameter("depth", depth); + + setParameter("r1", c1.r()); + setParameter("g1", c1.g()); + setParameter("b1", c1.b()); + setParameter("a1", c1.a()); + + setParameter("r2", c2.r()); + setParameter("g2", c2.g()); + setParameter("b2", c2.b()); + setParameter("a2", c2.a()); + + setParameter("r3", c3.r()); + setParameter("g3", c3.g()); + setParameter("b3", c3.b()); + setParameter("a3", c3.a()); + + setParameter("r4", c4.r()); + setParameter("g4", c4.g()); + setParameter("b4", c4.b()); + setParameter("a4", c4.a()); + + setParameter("r5", c5.r()); + setParameter("g5", c5.g()); + setParameter("b5", c5.b()); + setParameter("a5", c5.a()); + + setParameter("r6", c6.r()); + setParameter("g6", c6.g()); + setParameter("b6", c6.b()); + setParameter("a6", c6.a()); + + setParameter("r7", c7.r()); + setParameter("g7", c7.g()); + setParameter("b7", c7.b()); + setParameter("a7", c7.a()); + + setParameter("r8", c8.r()); + setParameter("g8", c8.g()); + setParameter("b8", c8.b()); + setParameter("a8", c8.a()); + + setParameter("texture", tex_name); + + setParameter("vertex", vert_name); + setParameter("fragment", frag_name); + + setPosition( p1, width, height, depth ); + //std::cout << width << " " << height << " " << depth << "\n"; + setColor( c1, c2, c3, c4, c5, c6, c7, c8 ); + setTextureImage(tex_name); + setShaders(vert_name, frag_name); + _vertices -> dirty(); + _colors -> dirty(); + _textures -> dirty(); + dirtyBound(); + + //reset flag + _dirty = false; + +} + diff --git a/calit2/Mugic/shapes/CubeShape.h b/calit2/Mugic/shapes/CubeShape.h new file mode 100644 index 00000000..3c5bea38 --- /dev/null +++ b/calit2/Mugic/shapes/CubeShape.h @@ -0,0 +1,28 @@ +#ifndef _CUBESHAPE_H_ +#define _CUBESHAPE_H_ + +/* Cube Shape for Mugic */ + +#include "GeometryShape.h" +#include + +class CubeShape : public GeometryShape +{ + public: + CubeShape( std::string command = "", std::string name = "" ); + virtual ~CubeShape(); + void update( std::string ); + + protected: + CubeShape(); + void setPosition( osg::Vec3, float width, float height, float depth); + void setColor( osg::Vec4, osg::Vec4, osg::Vec4, osg::Vec4, osg::Vec4, osg::Vec4, osg::Vec4, osg::Vec4 ); + void setNormals(); + void setTextureCoords(); + void setTextureImage(std::string); + void setShaders(std::string, std::string); + void update(); + +}; + +#endif diff --git a/calit2/Mugic/shapes/CylinderShape.cpp b/calit2/Mugic/shapes/CylinderShape.cpp new file mode 100644 index 00000000..be3fbe70 --- /dev/null +++ b/calit2/Mugic/shapes/CylinderShape.cpp @@ -0,0 +1,194 @@ +/* Cylinder Shape for Mugic */ + +#include "CylinderShape.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +/* Constructor */ +CylinderShape::CylinderShape(std::string command, std::string name) +{ + + _type = SimpleShape::CYLINDER; + BasicShape::setName(name); + + //create cylinder and add to geode as shape drawable + _cylinder = new osg::Cylinder(); + setShape(_cylinder); + + setPosition(osg::Vec3(0.0, 0.0, 0.0), 0.5, 1.0); + setShapeColor(osg::Vec4(1.0, 1.0, 1.0, 1.0)); + update(command); + + osg::StateSet* state = getOrCreateStateSet(); + state -> setMode(GL_BLEND, osg::StateAttribute::ON); + + osg::Material* mat = new osg::Material(); + mat -> setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); + state -> setAttributeAndModes(mat, osg::StateAttribute::ON); + + setShaders("", ""); + +} + +/* destructor */ +CylinderShape::~CylinderShape() +{ +} + +/* set position of cylinder - radius and height */ +void CylinderShape::setPosition(osg::Vec3 position, float radius, float height) +{ + + _cylinder->setRadius(radius); + _cylinder->setHeight(height); + _cylinder->setCenter(position); + + _radius = radius; + _height = height; + _center = position; + + //for update purposes + dirtyDisplayList(); + +} + +/* set color of cylinder */ +void CylinderShape::setShapeColor(osg::Vec4 color) +{ + + setColor(color); + _color = color; + + if(color[3] != 1.0) + getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + else + getOrCreateStateSet()->setRenderingHint(osg::StateSet::DEFAULT_BIN); + +} + +/* set shaders of cylinder */ +void CylinderShape::setShaders(std::string vert_file, std::string frag_file) +{ + + if(vert_file.compare(_vertex_shader) == 0 && frag_file.compare(_fragment_shader) == 0) + return; + + osg::StateSet* state = getOrCreateStateSet(); + osg::Program* prog = new osg::Program(); + osg::Shader* vert = new osg::Shader(osg::Shader::VERTEX); + osg::Shader* frag = new osg::Shader(osg::Shader::FRAGMENT); + + _vertex_shader = vert_file; + _fragment_shader = frag_file; + + //try to load shader files + std::string file_path = cvr::ConfigManager::getEntry("dir", "Plugin.Mugic.Shader", ""); + if(!_vertex_shader.empty()) + { + + bool loaded = vert->loadShaderSourceFromFile(file_path + _vertex_shader); + if(!loaded) + { + std::cout << "could not load vertex shader." << std::endl; + _vertex_shader = ""; + } + else + { + prog->addShader(vert); + } + + } + + if(!_fragment_shader.empty()) + { + + bool loaded = frag->loadShaderSourceFromFile(file_path + _fragment_shader); + if(!loaded) + { + std::cout << "could not load fragment shader." << std::endl; + _fragment_shader = ""; + } + else + { + prog->addShader(frag); + } + + } + + state->setAttributeAndModes(prog, osg::StateAttribute::ON); + +} + +/* update with command */ +void CylinderShape::update(std::string command) +{ + + OpenThreads::ScopedLock lock(_mutex); + _dirty = true; + + //check for changed values + addParameter(command, "radius"); + addParameter(command, "height"); + + addParameter(command, "x"); + addParameter(command, "y"); + addParameter(command, "z"); + + addParameter(command, "r1"); + addParameter(command, "g1"); + addParameter(command, "b1"); + addParameter(command, "a1"); + + addParameter(command, "vertex"); + addParameter(command, "fragment"); + +} + +/* update */ +void CylinderShape::update() +{ + + OpenThreads::ScopedLock lock(_mutex); + if(!_dirty) + return; + + float radius = _radius; + float height = _height; + osg::Vec3 center = _center; + osg::Vec4 color = _color; + std::string vert = _vertex_shader; + std::string frag = _fragment_shader; + + setParameter("radius", radius); + setParameter("height", height); + + setParameter("x", center.x()); + setParameter("y", center.y()); + setParameter("z", center.z()); + + setParameter("r1", color[0]); + setParameter("g1", color[1]); + setParameter("b1", color[2]); + setParameter("a1", color[3]); + + setParameter("vertex", vert); + setParameter("fragment", frag); + + setPosition(center, radius, height); + setShapeColor(color); + setShaders(vert, frag); + dirtyBound(); + + //reset flag + _dirty = false; + +} + diff --git a/calit2/Mugic/shapes/CylinderShape.h b/calit2/Mugic/shapes/CylinderShape.h new file mode 100644 index 00000000..1e8156fb --- /dev/null +++ b/calit2/Mugic/shapes/CylinderShape.h @@ -0,0 +1,24 @@ +#ifndef _CYLINDER_SHAPE_H_ +#define _CYLINDER_SHAPE_H_ + +#include "DrawableShape.h" + +class CylinderShape : public DrawableShape +{ + + public: + CylinderShape(std::string command = "", std::string name = ""); + virtual ~CylinderShape(); + void update(std::string); + + protected: + CylinderShape(); + void setPosition(osg::Vec3 position, float radius, float height); + void setShapeColor(osg::Vec4); + void setShaders(std::string, std::string); + void update(); + osg::Cylinder* _cylinder; //actual shape + +}; + +#endif diff --git a/calit2/Mugic/shapes/DrawableShape.cpp b/calit2/Mugic/shapes/DrawableShape.cpp new file mode 100644 index 00000000..bf3ca7eb --- /dev/null +++ b/calit2/Mugic/shapes/DrawableShape.cpp @@ -0,0 +1,36 @@ +#include "DrawableShape.h" + +#include +#include +#include + +using namespace std; + +DrawableShape::DrawableShape() +{ + + setUpdateCallback(new DrawableUpdateCallback()); + +} + +osg::MatrixTransform* DrawableShape::getMatrixParent() +{ + return (osg::ShapeDrawable::getParent(0)->asGeode())->osg::Node::getParent(0)->asTransform()->asMatrixTransform(); +} + +osg::Geode* DrawableShape::getParent() +{ + return osg::ShapeDrawable::getParent(0)->asGeode(); +} + +osg::Drawable* DrawableShape::asDrawable() +{ + return dynamic_cast(this); +} + +DrawableShape::~DrawableShape() +{ + OpenThreads::ScopedLock lock(_mutex); + setUpdateCallback(NULL); + _dirty = false; +} diff --git a/calit2/Mugic/shapes/DrawableShape.h b/calit2/Mugic/shapes/DrawableShape.h new file mode 100644 index 00000000..d82ddef0 --- /dev/null +++ b/calit2/Mugic/shapes/DrawableShape.h @@ -0,0 +1,43 @@ +#ifndef _DRAWABLE_SHAPE_H_ +#define _DRAWABLE_SHAPE_H_ + +#include "BasicShape.h" +#include +#include +#include +#include + +class DrawableShape : public BasicShape, public osg::ShapeDrawable +{ + + public: + virtual void update(std::string command) = 0; + osg::MatrixTransform* getMatrixParent(); + osg::Geode* getParent(); + osg::Drawable* asDrawable(); + + struct DrawableUpdateCallback : public osg::Drawable::UpdateCallback + { + virtual void update(osg::NodeVisitor*, osg::Drawable* drawable) + { + DrawableShape* shape = dynamic_cast (drawable); + if( shape ) + shape->update(); + } + }; + + protected: + DrawableShape(); + virtual ~DrawableShape(); + float _radius; + float _height; + osg::Vec3 _center; + osg::Vec4 _color; + std::string _vertex_shader; + std::string _fragment_shader; + + virtual void update() = 0; + +}; + +#endif diff --git a/calit2/Mugic/shapes/GeometryShape.cpp b/calit2/Mugic/shapes/GeometryShape.cpp index 0d72d60a..a81d81c4 100644 --- a/calit2/Mugic/shapes/GeometryShape.cpp +++ b/calit2/Mugic/shapes/GeometryShape.cpp @@ -16,6 +16,11 @@ GeometryShape::GeometryShape() setUpdateCallback(new GeometryUpdateCallback()); } +osg::MatrixTransform* GeometryShape::getMatrixParent() +{ + return (osg::Geometry::getParent(0)->asGeode())->osg::Node::getParent(0)->asTransform()->asMatrixTransform(); +} + osg::Geode* GeometryShape::getParent() { return osg::Geometry::getParent(0)->asGeode(); diff --git a/calit2/Mugic/shapes/GeometryShape.h b/calit2/Mugic/shapes/GeometryShape.h index 6d3708b2..dd439cd6 100644 --- a/calit2/Mugic/shapes/GeometryShape.h +++ b/calit2/Mugic/shapes/GeometryShape.h @@ -5,12 +5,14 @@ #include #include #include +#include class GeometryShape : public BasicShape, public osg::Geometry { public: virtual void update(std::string command) = 0; + osg::MatrixTransform* getMatrixParent(); osg::Geode* getParent(); osg::Drawable* asDrawable(); @@ -30,6 +32,11 @@ class GeometryShape : public BasicShape, public osg::Geometry virtual ~GeometryShape(); osg::Vec3Array* _vertices; osg::Vec4Array* _colors; + osg::Vec3Array* _normals; //normals for proper lighting/shading + osg::Vec2Array* _textures; //for texture coordinates + std::string _texture_name; //path to texture + std::string _vertex_shader; //path to vertex shader + std::string _fragment_shader; //path to fragment shader virtual void update() = 0; }; diff --git a/calit2/Mugic/shapes/ModelShape.cpp b/calit2/Mugic/shapes/ModelShape.cpp new file mode 100644 index 00000000..bcbc5d53 --- /dev/null +++ b/calit2/Mugic/shapes/ModelShape.cpp @@ -0,0 +1,178 @@ +#include "ModelShape.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +ModelShape::ModelShape(std::string command, std::string name) +{ + + _type = SimpleShape::MODEL; + + BasicShape::setName(name); + + //extract file name from command + std::string substring, value, searchParam; + searchParam.append("file").append("="); + size_t found = command.find(searchParam); + if(found != std::string::npos) + { + // extract value + substring = command.substr(found + searchParam.size()); + std::stringstream ss(substring); + ss >> value; + } + + //read in the model and return a node + setModel(value); + setShaders("", ""); + update(command); + +} + +ModelShape::~ModelShape() +{ +} + +void ModelShape::setModel(std::string file) +{ + + std::string file_path = cvr::ConfigManager::getEntry("dir", "Plugin.Mugic.Model", ""); + std::string def = "pawn.wrl"; + + //Check whether file name given + if(file.empty()) + { + //give default? + std::cout << "No model file specified; reading in default model" << std::endl; + _modelNode = osgDB::readNodeFile(file_path + def); + } + else + { + _modelNode = osgDB::readNodeFile(file_path + file); + + //testing + if(_modelNode == NULL) + { + std::cout << "Could not load model. Either does not exist or is incorrect file name." << std::endl; + std::cout << "reading in default model..." << std::endl; + _modelNode = osgDB::readNodeFile(file_path + def); + + return; + } + } + + //set node state + osg::StateSet* state = new osg::StateSet(); + state->setMode(GL_BLEND, osg::StateAttribute::ON); + osg::Material* mat = new osg::Material(); + mat->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); + state->setAttributeAndModes(mat, osg::StateAttribute::ON); + _modelNode->setStateSet(state); + +} + +osg::Node* ModelShape::getModelNode() +{ + return _modelNode; +} + +osg::MatrixTransform* ModelShape::getMatrixParent() +{ + return _modelNode->osg::Node::getParent(0)->asTransform()->asMatrixTransform(); +} + +void ModelShape::setShaders(std::string vert_file, std::string frag_file) +{ + std::cout << "inside setShader call" << std::endl; + + if(vert_file.compare(_vertex_shader) == 0 && frag_file.compare(_fragment_shader) == 0) + return; + + osg::StateSet* state = _modelNode->getOrCreateStateSet(); + osg::Program* prog = new osg::Program(); + osg::Shader* vert = new osg::Shader(osg::Shader::VERTEX); + osg::Shader* frag = new osg::Shader(osg::Shader::FRAGMENT); + + _vertex_shader = vert_file; + _fragment_shader = frag_file; + + //try to load shader files + std::string file_path = cvr::ConfigManager::getEntry("dir", "Plugin.Mugic.Shader", ""); + if(!_vertex_shader.empty()) + { + + bool loaded = vert->loadShaderSourceFromFile(file_path + _vertex_shader); + if(!loaded) + { + std::cout << "could not load vertex shader." << std::endl; + _vertex_shader = ""; + } + else + { + std::cout << "adding vertex shader" << std::endl; + prog->addShader(vert); + } + + } + + if(!_fragment_shader.empty()) + { + + bool loaded = frag->loadShaderSourceFromFile(file_path + _fragment_shader); + if(!loaded) + { + std::cout << "could not load fragment shader." << std::endl; + _fragment_shader = ""; + } + else + { + prog->addShader(frag); + } + + } + + state->setAttributeAndModes(prog, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); + +} + +//only update shaders +void ModelShape::update(std::string command) +{ + + OpenThreads::ScopedLock lock(_mutex); + _dirty = true; + + //check for changed values + addParameter(command, "vertex"); + addParameter(command, "fragment"); + +} + +void ModelShape::update() +{ + + OpenThreads::ScopedLock lock(_mutex); + if(!_dirty) + return; + + std::string vert_name = _vertex_shader; + std::string frag_name = _fragment_shader; + + setParameter("vertex", vert_name); + setParameter("fragment", frag_name); + + setShaders(vert_name, frag_name); + dirtyBound(); + + //reset flag + _dirty = false; + +} diff --git a/calit2/Mugic/shapes/ModelShape.h b/calit2/Mugic/shapes/ModelShape.h new file mode 100644 index 00000000..be95e1dc --- /dev/null +++ b/calit2/Mugic/shapes/ModelShape.h @@ -0,0 +1,29 @@ +#ifndef _MODELSHAPE_ +#define _MODELSHAPE_ + +#include "GeometryShape.h" + +#include +#include +#include + +class ModelShape : public GeometryShape +{ +public: + ModelShape(std::string command = "", std::string name = ""); + virtual ~ModelShape(); + void update(std::string); + osg::MatrixTransform* getMatrixParent(); + osg::Node* getModelNode(); + +protected: + ModelShape(); + void setModel(std::string); + void setShaders(std::string, std::string); + void update(); + osg::Node* _modelNode; //actual model node + + +}; + +#endif diff --git a/calit2/Mugic/shapes/QuadShape.cpp b/calit2/Mugic/shapes/QuadShape.cpp index 1dc7cf07..47ac1808 100644 --- a/calit2/Mugic/shapes/QuadShape.cpp +++ b/calit2/Mugic/shapes/QuadShape.cpp @@ -2,9 +2,13 @@ #include #include +#include +#include +#include #include #include +#include QuadShape::QuadShape(std::string command, std::string name) { @@ -14,13 +18,16 @@ QuadShape::QuadShape(std::string command, std::string name) _vertices = new osg::Vec3Array(4); _colors = new osg::Vec4Array(4); + _textures = new osg::Vec2Array(4); - setPosition(osg::Vec3(0.0, 0.0, 0.0), osg::Vec3(1.0, 0.0, 0.0), osg::Vec3(1.0, 0.0, 1.0), osg::Vec3(0.0, 0.0, 1.0)); - setColor(osg::Vec4(1.0, 0.0, 0.0, 1.0),osg::Vec4(0.0, 1.0, 0.0, 1.0),osg::Vec4(0.0, 0.0, 1.0, 1.0), osg::Vec4(0.0, 1.0, 1.0, 1.0)); + setPosition(osg::Vec3(-0.5, 0.0, -0.5), osg::Vec3(0.5, 0.0, -0.5), osg::Vec3(0.5, 0.0, 0.5), osg::Vec3(-0.5, 0.0, 0.5)); + setColor(osg::Vec4(1.0, 1.0, 1.0, 1.0),osg::Vec4(1.0, 1.0, 1.0, 1.0),osg::Vec4(1.0, 1.0, 1.0, 1.0), osg::Vec4(1.0, 1.0, 1.0, 1.0)); + setTextureCoords(osg::Vec2(0.0, 0.0), osg::Vec2(1.0, 0.0), osg::Vec2(1.0, 1.0), osg::Vec2(0.0, 1.0)); update(command); setVertexArray(_vertices); - setColorArray(_colors); + setColorArray(_colors); + setTexCoordArray(0, _textures); setColorBinding(osg::Geometry::BIND_PER_VERTEX); addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4)); @@ -29,6 +36,9 @@ QuadShape::QuadShape(std::string command, std::string name) state->setMode(GL_BLEND, osg::StateAttribute::ON); mat->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); state->setAttributeAndModes(mat, osg::StateAttribute::ON); + + setTextureImage(""); + setShaders("", ""); } QuadShape::~QuadShape() @@ -57,6 +67,105 @@ void QuadShape::setColor(osg::Vec4 c0, osg::Vec4 c1, osg::Vec4 c2, osg::Vec4 c3) } +void QuadShape::setTextureCoords(osg::Vec2 t1, osg::Vec2 t2, osg::Vec2 t3, osg::Vec2 t4) +{ + + //set texture coordinates + (*_textures)[0].set(t1[0], t1[1]); + (*_textures)[1].set(t2[0], t2[1]); + (*_textures)[2].set(t3[0], t3[1]); + (*_textures)[3].set(t4[0], t4[1]); + +} + +void QuadShape::setTextureImage(std::string tex_name) +{ + + osg::StateSet* state = getOrCreateStateSet(); + osg::Texture2D* tex = new osg::Texture2D; + osg::Image* image = new osg::Image; + tex->setDataVariance(osg::Object::DYNAMIC); + + //Whether to load an image or not + if(tex_name.empty()) + { + _texture_name = ""; + tex->setImage(image); + state->setTextureAttributeAndModes(0, tex, osg::StateAttribute::OFF); + } + else + { + std::string file_path = cvr::ConfigManager::getEntry("dir", "Plugin.Mugic.Texture", ""); + _texture_name = file_path + tex_name; + image = osgDB::readImageFile(_texture_name); + + //testing + if(!image) + { + std::cout << "Image does not exist." << std::endl; + _texture_name = ""; + state->setTextureAttributeAndModes(0, tex, osg::StateAttribute::OFF); + return; + } + + tex->setImage(image); + state->setTextureAttributeAndModes(0, tex, osg::StateAttribute::ON); + } + +} + +void QuadShape::setShaders(std::string vert_file, std::string frag_file) +{ + + if(vert_file.compare(_vertex_shader) == 0 && frag_file.compare(_fragment_shader) == 0) + return; + + osg::StateSet* state = getOrCreateStateSet(); + osg::Program* prog = new osg::Program(); + osg::Shader* vert = new osg::Shader(osg::Shader::VERTEX); + osg::Shader* frag = new osg::Shader(osg::Shader::FRAGMENT); + + _vertex_shader = vert_file; + _fragment_shader = frag_file; + + //try to load shader files + std::string file_path = cvr::ConfigManager::getEntry("dir", "Plugin.Mugic.Shader", ""); + if(!_vertex_shader.empty()) + { + + bool loaded = vert->loadShaderSourceFromFile(file_path + _vertex_shader); + if(!loaded) + { + std::cout << "could not load vertex shader." << std::endl; + _vertex_shader = ""; + } + else + { + prog->addShader(vert); + } + + } + + if(!_fragment_shader.empty()) + { + + bool loaded = frag->loadShaderSourceFromFile(file_path + _fragment_shader); + if(!loaded) + { + std::cout << "could not load fragment shader." << std::endl; + _fragment_shader = ""; + } + else + { + prog->addShader(frag); + } + + } + + state->setAttributeAndModes(prog, osg::StateAttribute::ON); + +} + void QuadShape::update(std::string command) { OpenThreads::ScopedLock lock(_mutex); @@ -94,6 +203,19 @@ void QuadShape::update(std::string command) addParameter(command, "g4"); addParameter(command, "b4"); addParameter(command, "a4"); + + addParameter(command, "texture"); + addParameter(command, "t1s"); + addParameter(command, "t1t"); + addParameter(command, "t2s"); + addParameter(command, "t2t"); + addParameter(command, "t3s"); + addParameter(command, "t3t"); + addParameter(command, "t4s"); + addParameter(command, "t4t"); + + addParameter(command, "vertex"); + addParameter(command, "fragment"); } void QuadShape::update() @@ -104,6 +226,13 @@ void QuadShape::update() osg::Vec3 p1((*_vertices)[0]); osg::Vec4 c1((*_colors)[0]); + osg::Vec2 t1((*_textures)[0]); + osg::Vec2 t2((*_textures)[1]); + osg::Vec2 t3((*_textures)[2]); + osg::Vec2 t4((*_textures)[3]); + std::string tex_name = _texture_name; + std::string vert_name = _vertex_shader; + std::string frag_name = _fragment_shader; setParameter("x1", p1.x()); setParameter("y1", p1.y()); @@ -144,13 +273,30 @@ void QuadShape::update() setParameter("r4", c4.r()); setParameter("g4", c4.g()); setParameter("b4", c4.b()); - setParameter("a4", c4.a()); + setParameter("a4", c4.a()); + + setParameter("texture", tex_name); + setParameter("t1s", t1[0]); + setParameter("t1t", t1[1]); + setParameter("t2s", t2[0]); + setParameter("t2t", t2[1]); + setParameter("t3s", t3[0]); + setParameter("t3t", t3[1]); + setParameter("t4s", t4[0]); + setParameter("t4t", t4[1]); + + setParameter("vertex", vert_name); + setParameter("fragment", frag_name); setPosition(p1, p2, p3, p4); setColor(c1, c2 ,c3, c4); + setTextureCoords(t1, t2, t3, t4); + setTextureImage(tex_name); + setShaders(vert_name, frag_name); _colors->dirty(); _vertices->dirty(); + _textures->dirty(); dirtyBound(); // reset flag diff --git a/calit2/Mugic/shapes/QuadShape.h b/calit2/Mugic/shapes/QuadShape.h index 9f419657..77054593 100644 --- a/calit2/Mugic/shapes/QuadShape.h +++ b/calit2/Mugic/shapes/QuadShape.h @@ -18,6 +18,9 @@ class QuadShape : public GeometryShape QuadShape(); void setPosition(osg::Vec3, osg::Vec3, osg::Vec3, osg::Vec3); void setColor(osg::Vec4, osg::Vec4, osg::Vec4, osg::Vec4); + void setTextureCoords(osg::Vec2, osg::Vec2, osg::Vec2, osg::Vec2); + void setTextureImage(std::string); + void setShaders(std::string, std::string); void update(); }; diff --git a/calit2/Mugic/shapes/RectangleShape.cpp b/calit2/Mugic/shapes/RectangleShape.cpp index ea521cdd..22d431e5 100644 --- a/calit2/Mugic/shapes/RectangleShape.cpp +++ b/calit2/Mugic/shapes/RectangleShape.cpp @@ -2,6 +2,9 @@ #include #include +#include +#include +#include #include #include @@ -15,13 +18,22 @@ RectangleShape::RectangleShape(std::string command, std::string name) _vertices = new osg::Vec3Array(4); _colors = new osg::Vec4Array(4); + _textures = new osg::Vec2Array(4); + //normals setup here + _normals = new osg::Vec3Array(1); + (*_normals)[0].set(0.0, -1.0, 0.0); + setPosition(osg::Vec3(0.0, 0.0, 0.0), 1.0, 1.0); - setColor(osg::Vec4(1.0, 0.0, 0.0, 1.0)); + setColor(osg::Vec4(1.0, 1.0, 1.0, 1.0)); + setTextureCoords(osg::Vec2(0.0, 0.0), osg::Vec2(1.0, 0.0), osg::Vec2(1.0, 1.0), osg::Vec2(0.0, 1.0)); update(command); setVertexArray(_vertices); - setColorArray(_colors); + setColorArray(_colors); + setTexCoordArray(0, _textures); + setNormalArray(_normals); + setNormalBinding(osg::Geometry::BIND_OVERALL); setColorBinding(osg::Geometry::BIND_OVERALL); addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4)); @@ -30,6 +42,11 @@ RectangleShape::RectangleShape(std::string command, std::string name) osg::Material* mat = new osg::Material(); mat->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); state->setAttributeAndModes(mat, osg::StateAttribute::ON); + + //additional texture setup + setTextureImage(""); + setShaders("", ""); + } RectangleShape::~RectangleShape() @@ -38,10 +55,10 @@ RectangleShape::~RectangleShape() void RectangleShape::setPosition(osg::Vec3 p, float width, float height) { - (*_vertices)[0].set(p[0], p[1], p[2]); - (*_vertices)[1].set(p[0] + width, p[1], p[2]); - (*_vertices)[2].set(p[0] + width, p[1], p[2] + height); - (*_vertices)[3].set(p[0], p[1], p[2] + height); + (*_vertices)[0].set(p[0] - (width/2), p[1], p[2] - (height/2)); + (*_vertices)[1].set(p[0] + (width/2), p[1], p[2] - (height/2)); + (*_vertices)[2].set(p[0] + (width/2), p[1], p[2] + (height/2)); + (*_vertices)[3].set(p[0] - (width/2), p[1], p[2] + (height/2)); } void RectangleShape::setColor(osg::Vec4 c0) @@ -55,6 +72,105 @@ void RectangleShape::setColor(osg::Vec4 c0) } +void RectangleShape::setTextureCoords(osg::Vec2 t1, osg::Vec2 t2, osg::Vec2 t3, osg::Vec2 t4) +{ + + //set texture coordinates + (*_textures)[0].set(t1[0], t1[1]); + (*_textures)[1].set(t2[0], t2[1]); + (*_textures)[2].set(t3[0], t3[1]); + (*_textures)[3].set(t4[0], t4[1]); + +} + +void RectangleShape::setTextureImage(std::string tex_name) +{ + + osg::StateSet* state = getOrCreateStateSet(); + osg::Texture2D* tex = new osg::Texture2D; + osg::Image* image = new osg::Image; + tex->setDataVariance(osg::Object::DYNAMIC); + + //Whether to load an image or not + if(tex_name.empty()) + { + _texture_name = ""; + tex->setImage(image); + state->setTextureAttributeAndModes(0, tex, osg::StateAttribute::OFF); + } + else + { + std::string file_path = cvr::ConfigManager::getEntry("dir", "Plugin.Mugic.Texture", ""); + _texture_name = file_path + tex_name; + image = osgDB::readImageFile(_texture_name); + + //testing + if(!image) + { + std::cout << "Image does not exist." << std::endl; + _texture_name = ""; + state->setTextureAttributeAndModes(0, tex, osg::StateAttribute::OFF); + return; + } + + tex->setImage(image); + state->setTextureAttributeAndModes(0, tex, osg::StateAttribute::ON); + } + +} + +void RectangleShape::setShaders(std::string vert_file, std::string frag_file) +{ + + if(vert_file.compare(_vertex_shader) == 0 && frag_file.compare(_fragment_shader) == 0) + return; + + osg::StateSet* state = getOrCreateStateSet(); + osg::Program* prog = new osg::Program(); + osg::Shader* vert = new osg::Shader(osg::Shader::VERTEX); + osg::Shader* frag = new osg::Shader(osg::Shader::FRAGMENT); + + _vertex_shader = vert_file; + _fragment_shader = frag_file; + + //try to load shader files + std::string file_path = cvr::ConfigManager::getEntry("dir", "Plugin.Mugic.Shader", ""); + if(!_vertex_shader.empty()) + { + + bool loaded = vert->loadShaderSourceFromFile(file_path + _vertex_shader); + if(!loaded) + { + std::cout << "could not load vertex shader." << std::endl; + _vertex_shader = ""; + } + else + { + prog->addShader(vert); + } + + } + + if(!_fragment_shader.empty()) + { + + bool loaded = frag->loadShaderSourceFromFile(file_path + _fragment_shader); + if(!loaded) + { + std::cout << "could not load fragment shader." << std::endl; + _fragment_shader = ""; + } + else + { + prog->addShader(frag); + } + + } + + state->setAttributeAndModes(prog, osg::StateAttribute::ON); + +} + void RectangleShape::update(std::string command) { OpenThreads::ScopedLock lock(_mutex); @@ -70,6 +186,18 @@ void RectangleShape::update(std::string command) addParameter(command, "g"); addParameter(command, "b"); addParameter(command, "a"); + + addParameter(command, "texture"); + addParameter(command, "t1s"); + addParameter(command, "t1t"); + addParameter(command, "t2s"); + addParameter(command, "t2t"); + addParameter(command, "t3s"); + addParameter(command, "t3t"); + addParameter(command, "t4s"); + addParameter(command, "t4t"); + addParameter(command, "vertex"); + addParameter(command, "fragment"); } void RectangleShape::update() @@ -80,8 +208,22 @@ void RectangleShape::update() osg::Vec3 p1((*_vertices)[0]); osg::Vec4 c1((*_colors)[0]); + + std::string tex_name = _texture_name; + osg::Vec2 t1((*_textures)[0]); + osg::Vec2 t2((*_textures)[1]); + osg::Vec2 t3((*_textures)[2]); + osg::Vec2 t4((*_textures)[3]); + float width = (*_vertices)[1].x() - (*_vertices)[0].x(); float height = (*_vertices)[2].z() - (*_vertices)[1].z(); + + std::string vert_name = _vertex_shader; + std::string frag_name = _fragment_shader; + + //adjust center point + p1.x() = p1.x() + (width/2); + p1.z() = p1.z() + (height/2); setParameter("x", p1.x()); setParameter("y", p1.y()); @@ -93,10 +235,27 @@ void RectangleShape::update() setParameter("b", c1.b()); setParameter("a", c1.a()); + setParameter("texture", tex_name); + setParameter("t1s", t1[0]); + setParameter("t1t", t1[1]); + setParameter("t2s", t2[0]); + setParameter("t2t", t2[1]); + setParameter("t3s", t3[0]); + setParameter("t3t", t3[1]); + setParameter("t4s", t4[0]); + setParameter("t4t", t4[1]); + + setParameter("vertex", vert_name); + setParameter("fragment", frag_name); + setPosition(p1, width, height); setColor(c1); + setTextureCoords(t1, t2, t3, t4); + setTextureImage(tex_name); + setShaders(vert_name, frag_name); _vertices->dirty(); _colors->dirty(); + _textures->dirty(); dirtyBound(); // reset flag diff --git a/calit2/Mugic/shapes/RectangleShape.h b/calit2/Mugic/shapes/RectangleShape.h index 38815bd5..361ae031 100644 --- a/calit2/Mugic/shapes/RectangleShape.h +++ b/calit2/Mugic/shapes/RectangleShape.h @@ -3,6 +3,7 @@ #include "GeometryShape.h" +#include #include class RectangleShape : public GeometryShape @@ -17,6 +18,9 @@ class RectangleShape : public GeometryShape RectangleShape(); void setPosition(osg::Vec3, float width, float height); void setColor(osg::Vec4); + void setTextureCoords(osg::Vec2, osg::Vec2, osg::Vec2, osg::Vec2); + void setTextureImage(std::string); + void setShaders(std::string, std::string); void update(); }; diff --git a/calit2/Mugic/shapes/SphereShape.cpp b/calit2/Mugic/shapes/SphereShape.cpp new file mode 100644 index 00000000..7c2c9d27 --- /dev/null +++ b/calit2/Mugic/shapes/SphereShape.cpp @@ -0,0 +1,190 @@ +/* Sphere Shape for Mugic */ + +#include "SphereShape.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +/*Constructor for Sphere*/ +SphereShape::SphereShape(std::string command, std::string name) +{ + + _type = SimpleShape::SPHERE; + BasicShape::setName(name); + + //create sphere and add to geode as shape drawable + _sphere = new osg::Sphere(); + setShape(_sphere); + + setPosition(osg::Vec3(0.0, 0.0, 0.0), 1.0); + setShapeColor(osg::Vec4(1.0, 1.0, 1.0, 1.0)); + update(command); + + osg::StateSet* state = getOrCreateStateSet(); + state -> setMode(GL_BLEND, osg::StateAttribute::ON); + + osg::Material* mat = new osg::Material(); + mat -> setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); + state -> setAttributeAndModes(mat, osg::StateAttribute::ON); + + setShaders("", ""); + + +} + +/*Destructor*/ +SphereShape::~SphereShape() +{ +} + +/*Set position of Sphere - radius */ +void SphereShape::setPosition(osg::Vec3 position, float radius) +{ + + _sphere->setRadius(radius); + _sphere->setCenter(position); + + _radius = radius; + _center = position; + + //for update purposes + dirtyDisplayList(); + +} + +/*Set color of sphere*/ +void SphereShape::setShapeColor(osg::Vec4 color) +{ + + setColor(color); + _color = color; + + if(color[3] != 1.0) + getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + else + getOrCreateStateSet()->setRenderingHint(osg::StateSet::DEFAULT_BIN); + +} + +/*set Shaders for Sphere*/ +void SphereShape::setShaders(std::string vert_file, std::string frag_file) +{ + + if(vert_file.compare(_vertex_shader) == 0 && frag_file.compare(_fragment_shader) == 0) + return; + + osg::StateSet* state = getOrCreateStateSet(); + osg::Program* prog = new osg::Program(); + osg::Shader* vert = new osg::Shader(osg::Shader::VERTEX); + osg::Shader* frag = new osg::Shader(osg::Shader::FRAGMENT); + + _vertex_shader = vert_file; + _fragment_shader = frag_file; + + //try to load shader files + std::string file_path = cvr::ConfigManager::getEntry("dir", "Plugin.Mugic.Shader", ""); + if(!_vertex_shader.empty()) + { + + bool loaded = vert->loadShaderSourceFromFile(file_path + _vertex_shader); + if(!loaded) + { + std::cout << "could not load vertex shader." << std::endl; + _vertex_shader = ""; + } + else + { + prog->addShader(vert); + } + + } + + if(!_fragment_shader.empty()) + { + + bool loaded = frag->loadShaderSourceFromFile(file_path + _fragment_shader); + if(!loaded) + { + std::cout << "could not load fragment shader." << std::endl; + _fragment_shader = ""; + } + else + { + prog->addShader(frag); + } + + } + + state->setAttributeAndModes(prog, osg::StateAttribute::ON); + +} + +/*update sphere with passed command*/ +void SphereShape::update(std::string command) +{ + + OpenThreads::ScopedLock lock(_mutex); + _dirty = true; + + //check for changed values + addParameter(command, "radius"); + + addParameter(command, "x"); + addParameter(command, "y"); + addParameter(command, "z"); + + addParameter(command, "r1"); + addParameter(command, "g1"); + addParameter(command, "b1"); + addParameter(command, "a1"); + + addParameter(command, "vertex"); + addParameter(command, "fragment"); + +} + +/*update*/ +void SphereShape::update() +{ + + OpenThreads::ScopedLock lock(_mutex); + if(!_dirty) + return; + + float radius = _radius; + osg::Vec3 center = _center; + osg::Vec4 color = _color; + std::string vert = _vertex_shader; + std::string frag = _fragment_shader; + + setParameter("radius", radius); + + setParameter("x", center.x()); + setParameter("y", center.y()); + setParameter("z", center.z()); + + setParameter("r1", color[0]); + setParameter("g1", color[1]); + setParameter("b1", color[2]); + setParameter("a1", color[3]); + + setParameter("vertex", vert); + setParameter("fragment", frag); + + setPosition(center, radius); + setShapeColor(color); + setShaders(vert, frag); + dirtyBound(); + + //reset flag + _dirty = false; + +} + diff --git a/calit2/Mugic/shapes/SphereShape.h b/calit2/Mugic/shapes/SphereShape.h new file mode 100644 index 00000000..cecf21ac --- /dev/null +++ b/calit2/Mugic/shapes/SphereShape.h @@ -0,0 +1,24 @@ +#ifndef _SPHERE_SHAPE_H_ +#define _SPHERE_SHAPE_H_ + +#include "DrawableShape.h" + +class SphereShape : public DrawableShape +{ + + public: + SphereShape(std::string command = "", std::string name = ""); + virtual ~SphereShape(); + void update(std::string); + + protected: + SphereShape(); + void setPosition(osg::Vec3 position, float radius); + void setShapeColor(osg::Vec4); + void setShaders(std::string, std::string); + void update(); + osg::Sphere* _sphere; //actual shape + +}; + +#endif diff --git a/calit2/Mugic/shapes/TextShape.cpp b/calit2/Mugic/shapes/TextShape.cpp index e0a87edd..fed09fc9 100644 --- a/calit2/Mugic/shapes/TextShape.cpp +++ b/calit2/Mugic/shapes/TextShape.cpp @@ -36,6 +36,11 @@ osg::Geode* TextShape::getParent() return osgText::Text::getParent(0)->asGeode(); } +osg::MatrixTransform* TextShape::getMatrixParent() +{ + return (osgText::Text::getParent(0)->asGeode())->osg::Node::getParent(0)->asTransform()->asMatrixTransform(); +} + osg::Drawable* TextShape::asDrawable() { return dynamic_cast(this); diff --git a/calit2/Mugic/shapes/TextShape.h b/calit2/Mugic/shapes/TextShape.h index 962e9d0d..c4e7b314 100644 --- a/calit2/Mugic/shapes/TextShape.h +++ b/calit2/Mugic/shapes/TextShape.h @@ -14,6 +14,7 @@ class TextShape : public BasicShape, public osgText::Text virtual ~TextShape(); void update(std::string); osg::Geode* getParent(); + osg::MatrixTransform* getMatrixParent(); osg::Drawable* asDrawable(); struct TextUpdateCallback : public osg::Drawable::UpdateCallback diff --git a/calit2/Mugic/shapes/TriangleShape.cpp b/calit2/Mugic/shapes/TriangleShape.cpp index 45d35496..7ce7e888 100644 --- a/calit2/Mugic/shapes/TriangleShape.cpp +++ b/calit2/Mugic/shapes/TriangleShape.cpp @@ -2,9 +2,13 @@ #include #include +#include +#include +#include #include #include +#include TriangleShape::TriangleShape(std::string command, std::string name) { @@ -14,13 +18,22 @@ TriangleShape::TriangleShape(std::string command, std::string name) _vertices = new osg::Vec3Array(3); _colors = new osg::Vec4Array(3); + _textures = new osg::Vec2Array(3); + + //setup normals here + _normals = new osg::Vec3Array(1); + (*_normals)[0].set(0.0, -1.0, 0.0); - setPosition(osg::Vec3(0.0, 0.0, 0.0), osg::Vec3(1.0, 0.0, 0.0), osg::Vec3(1.0, 0.0, 1.0)); - setColor(osg::Vec4(1.0, 0.0, 0.0, 1.0),osg::Vec4(0.0, 1.0, 0.0, 1.0),osg::Vec4(0.0, 0.0, 1.0, 1.0)); + setPosition(osg::Vec3(-0.5, 0.0, -0.5), osg::Vec3(0.5, 0.0, -0.5), osg::Vec3(0.0, 0.0, 0.5)); + setColor(osg::Vec4(1.0, 1.0, 1.0, 1.0),osg::Vec4(1.0, 1.0, 1.0, 1.0),osg::Vec4(1.0, 1.0, 1.0, 1.0)); + setTextureCoords(osg::Vec2(0.0, 0.0), osg::Vec2(1.0, 0.0), osg::Vec2(0.5, 1.0)); update(command); setVertexArray(_vertices); - setColorArray(_colors); + setColorArray(_colors); + setTexCoordArray(0, _textures); + setNormalArray(_normals); + setNormalBinding(osg::Geometry::BIND_OVERALL); setColorBinding(osg::Geometry::BIND_PER_VERTEX); addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES,0,3)); @@ -29,6 +42,10 @@ TriangleShape::TriangleShape(std::string command, std::string name) state->setMode(GL_BLEND, osg::StateAttribute::ON); mat->setColorMode(osg::Material::AMBIENT_AND_DIFFUSE); state->setAttributeAndModes(mat, osg::StateAttribute::ON); + + //additional texture setup + setTextureImage(""); + setShaders("", ""); } TriangleShape::~TriangleShape() @@ -55,6 +72,103 @@ void TriangleShape::setColor(osg::Vec4 c0, osg::Vec4 c1, osg::Vec4 c2) } +void TriangleShape::setTextureCoords(osg::Vec2 t1, osg::Vec2 t2, osg::Vec2 t3) +{ + + (*_textures)[0].set(t1[0], t1[1]); + (*_textures)[1].set(t2[0], t2[1]); + (*_textures)[2].set(t3[0], t3[1]); + +} + +void TriangleShape::setTextureImage(std::string tex_name) +{ + + osg::StateSet* state = getOrCreateStateSet(); + osg::Texture2D* tex = new osg::Texture2D; + osg::Image* image = new osg::Image; + tex->setDataVariance(osg::Object::DYNAMIC); + + //Whether to load an image or not + if(tex_name.empty()) + { + _texture_name = ""; + tex->setImage(image); + state->setTextureAttributeAndModes(0, tex, osg::StateAttribute::OFF); + } + else + { + std::string file_path = cvr::ConfigManager::getEntry("dir", "Plugin.Mugic.Texture", ""); + _texture_name = file_path + tex_name; + image = osgDB::readImageFile(_texture_name); + + //testing + if(!image) + { + std::cout << "Image does not exist." << std::endl; + _texture_name = ""; + state->setTextureAttributeAndModes(0, tex, osg::StateAttribute::OFF); + return; + } + + tex->setImage(image); + state->setTextureAttributeAndModes(0, tex, osg::StateAttribute::ON); + } + +} + +void TriangleShape::setShaders(std::string vert_file, std::string frag_file) +{ + + if(vert_file.compare(_vertex_shader) == 0 && frag_file.compare(_fragment_shader) == 0) + return; + + osg::StateSet* state = getOrCreateStateSet(); + osg::Program* prog = new osg::Program(); + osg::Shader* vert = new osg::Shader(osg::Shader::VERTEX); + osg::Shader* frag = new osg::Shader(osg::Shader::FRAGMENT); + + _vertex_shader = vert_file; + _fragment_shader = frag_file; + + //try to load shader files + std::string file_path = cvr::ConfigManager::getEntry("dir", "Plugin.Mugic.Shader", ""); + if(!_vertex_shader.empty()) + { + + bool loaded = vert->loadShaderSourceFromFile(file_path + _vertex_shader); + if(!loaded) + { + std::cout << "could not load vertex shader." << std::endl; + _vertex_shader = ""; + } + else + { + prog->addShader(vert); + } + + } + + if(!_fragment_shader.empty()) + { + + bool loaded = frag->loadShaderSourceFromFile(file_path + _fragment_shader); + if(!loaded) + { + std::cout << "could not load fragment shader." << std::endl; + _fragment_shader = ""; + } + else + { + prog->addShader(frag); + } + + } + + state->setAttributeAndModes(prog, osg::StateAttribute::ON); + +} + void TriangleShape::update(std::string command) { OpenThreads::ScopedLock lock(_mutex); @@ -84,6 +198,17 @@ void TriangleShape::update(std::string command) addParameter(command, "g3"); addParameter(command, "b3"); addParameter(command, "a3"); + + addParameter(command, "texture"); + addParameter(command, "t1s"); + addParameter(command, "t1t"); + addParameter(command, "t2s"); + addParameter(command, "t2t"); + addParameter(command, "t3s"); + addParameter(command, "t3t"); + + addParameter(command, "vertex"); + addParameter(command, "fragment"); } void TriangleShape::update() @@ -94,6 +219,12 @@ void TriangleShape::update() osg::Vec3 p1((*_vertices)[0]); osg::Vec4 c1((*_colors)[0]); + osg::Vec2 t1((*_textures)[0]); + osg::Vec2 t2((*_textures)[1]); + osg::Vec2 t3((*_textures)[2]); + std::string tex_name = _texture_name; + std::string vert_name = _vertex_shader; + std::string frag_name = _fragment_shader; setParameter("x1", p1.x()); setParameter("y1", p1.y()); @@ -125,11 +256,26 @@ void TriangleShape::update() setParameter("b3", c3.b()); setParameter("a3", c3.a()); + setParameter("texture", tex_name); + setParameter("t1s", t1[0]); + setParameter("t1t", t1[1]); + setParameter("t2s", t2[0]); + setParameter("t2t", t2[1]); + setParameter("t3s", t3[0]); + setParameter("t3t", t3[0]); + + setParameter("vertex", vert_name); + setParameter("fragment", frag_name); + setPosition(p1, p2, p3); setColor(c1, c2 ,c3); + setTextureCoords(t1, t2, t3); + setTextureImage(tex_name); + setShaders(vert_name, frag_name); - _colors->dirty(); - _vertices->dirty(); + _colors->dirty(); + _vertices->dirty(); + _textures->dirty(); dirtyBound(); // reset flag diff --git a/calit2/Mugic/shapes/TriangleShape.h b/calit2/Mugic/shapes/TriangleShape.h index 92f95c70..8169beea 100644 --- a/calit2/Mugic/shapes/TriangleShape.h +++ b/calit2/Mugic/shapes/TriangleShape.h @@ -18,6 +18,9 @@ class TriangleShape : public GeometryShape TriangleShape(); void setPosition(osg::Vec3, osg::Vec3, osg::Vec3); void setColor(osg::Vec4, osg::Vec4, osg::Vec4); + void setTextureCoords(osg::Vec2, osg::Vec2, osg::Vec2); + void setTextureImage(std::string); + void setShaders(std::string, std::string); void update(); }; #endif diff --git a/calit2/Mugic/zhelpers.h b/calit2/Mugic/zhelpers.h index 8e55cf0e..cfbbc33f 100644 --- a/calit2/Mugic/zhelpers.h +++ b/calit2/Mugic/zhelpers.h @@ -22,7 +22,7 @@ #include #include #include -#include +#include // Version checking, and patch up missing constants to match 2.1 #if ZMQ_VERSION_MAJOR == 2