|
27 | 27 | #include <cover/coVRMSController.h> |
28 | 28 | #include <cover/coVRConfig.h> |
29 | 29 | #include <cover/VRViewer.h> |
| 30 | +#include <cover/VRSceneGraph.h> |
30 | 31 | #include <vrml97/vrml/VrmlNamespace.h> |
31 | 32 | #include <VrmlNodeGeoData.h> |
32 | 33 |
|
|
61 | 62 | #include <PluginUtil/PluginMessageTypes.h> |
62 | 63 | #include <../../../../3rdparty/easyexif/exif.h> |
63 | 64 | #include <stdio.h> |
| 65 | + |
| 66 | +using namespace vrui; |
| 67 | +using namespace opencover; |
| 68 | + |
64 | 69 | namespace opencover |
65 | 70 | { |
66 | 71 | namespace ui |
@@ -747,6 +752,45 @@ bool GeoDataLoader::init() |
747 | 752 |
|
748 | 753 | if (!geo->displayName.empty()) |
749 | 754 | location->setText(geo->displayName); }); |
| 755 | + |
| 756 | + |
| 757 | + editGroup = new ui::Group(geoDataMenu, "edit"); |
| 758 | + editGroup->setText("Edit"); |
| 759 | + editGroup->allowRelayout(true); |
| 760 | + editInteraction = new editTerrain(this); |
| 761 | + |
| 762 | + editButton = new ui::Button(editGroup, "editTerrain"); |
| 763 | + editButton->setText("editTerrain"); |
| 764 | + editButton->setState(false); |
| 765 | + editButton->setCallback([this](bool state) |
| 766 | + { |
| 767 | + if (state) |
| 768 | + { |
| 769 | + editInteraction->enableIntersection(); |
| 770 | + } |
| 771 | + else |
| 772 | + { |
| 773 | + editInteraction->disableIntersection(); |
| 774 | + } }); |
| 775 | + |
| 776 | + deleteSelected = new ui::Action(editGroup, "deleteSelected"); |
| 777 | + deleteSelected->setText("delete"); |
| 778 | + deleteSelected->setCallback([this]() |
| 779 | + { doDelete(); }); |
| 780 | + |
| 781 | + replace = new ui::Action(editGroup, "replace"); |
| 782 | + replace->setText("replace"); |
| 783 | + replace->setCallback([this]() |
| 784 | + { doReplace(); }); |
| 785 | + |
| 786 | + undo = new ui::Action(editGroup, "undo"); |
| 787 | + undo->setText("undo"); |
| 788 | + undo->setCallback([this]() |
| 789 | + { doUndo(); }); |
| 790 | + |
| 791 | + selectionName = new ui::Label(editGroup, "name"); |
| 792 | + selectionName->setText("nothing is selected"); |
| 793 | + |
750 | 794 | return true; |
751 | 795 | } |
752 | 796 |
|
@@ -895,6 +939,131 @@ bool GeoDataLoader::update() |
895 | 939 | float farValue = coVRConfig::instance()->farClip(); |
896 | 940 | float scale = ((farValue) / 20000) + 500; // scale the sphere so that it stays a bit closer than the far clipping plane. |
897 | 941 | skyRootNode->setMatrix(osg::Matrix::scale(scale, scale, scale) * osg::Matrix::rotate(northAngle, osg::Vec3(0, 0, 1)) * osg::Matrix::rotate(cover->getObjectsXform()->getMatrix().getRotate())); |
| 942 | + if (editInteraction->isRunning()) |
| 943 | + { |
| 944 | + |
| 945 | + // get the intersected node |
| 946 | + if (cover->getIntersectedNode()) |
| 947 | + { |
| 948 | + // position label with name |
| 949 | + //nameLabel_->setPosition(cover->getIntersectionHitPointWorld()); |
| 950 | + if (cover->getIntersectedNode() != oldIntersectedNode) |
| 951 | + { |
| 952 | + // get the node name |
| 953 | + string nodeName; |
| 954 | + // char *labelName = NULL; |
| 955 | + |
| 956 | + // show only node names under objects root |
| 957 | + // so check if node is under objects root |
| 958 | + osg::Node *currentNode = cover->getIntersectedNode(); |
| 959 | + while (currentNode != NULL) |
| 960 | + { |
| 961 | + if (currentNode == cover->getObjectsRoot()) |
| 962 | + { |
| 963 | + if (showGeodeName_) |
| 964 | + { |
| 965 | + // first look for a node description beginning with _SCGR_ |
| 966 | + std::vector<std::string> dl = cover->getIntersectedNode()->getDescriptions(); |
| 967 | + for (size_t i = 0; i < dl.size(); i++) |
| 968 | + { |
| 969 | + std::string descr = dl[i]; |
| 970 | + if (descr.find("_SCGR_") != string::npos) |
| 971 | + { |
| 972 | + nodeName = dl[i]; |
| 973 | + // fprintf(stderr,"found description %s\n", nodeName.c_str()); |
| 974 | + break; |
| 975 | + } |
| 976 | + } |
| 977 | + if (nodeName.empty()) |
| 978 | + { // if there is no description we take the node name |
| 979 | + nodeName = cover->getIntersectedNode()->getName(); |
| 980 | + // fprintf(stderr,"taking the node name %s\n", nodeName.c_str()); |
| 981 | + } |
| 982 | + } |
| 983 | + else // show name of the dcs above |
| 984 | + { |
| 985 | + osg::Node *parentDcs = cover->getIntersectedNode()->getParent(0); |
| 986 | + nodeName = parentDcs->getName(); |
| 987 | + if (nodeName.empty()) |
| 988 | + { |
| 989 | + // if the dcs has no name it could be a helper node |
| 990 | + if ((parentDcs->getNumDescriptions() > 0) && (parentDcs->getDescription(1) == "SELECTIONHELPER")) |
| 991 | + { |
| 992 | + nodeName = parentDcs->getParent(0)->getName(); |
| 993 | + } |
| 994 | + } |
| 995 | + } |
| 996 | + break; |
| 997 | + } |
| 998 | + if (currentNode->getNumParents() > 0) |
| 999 | + currentNode = currentNode->getParent(0); |
| 1000 | + else |
| 1001 | + currentNode = NULL; |
| 1002 | + } |
| 1003 | + |
| 1004 | + // show label |
| 1005 | + if (!nodeName.empty()) |
| 1006 | + { |
| 1007 | + std::string onam = nodeName; |
| 1008 | + // eliminate _SCGR_ |
| 1009 | + if (nodeName.find("_SCGR_") != string::npos) |
| 1010 | + { |
| 1011 | + nodeName = nodeName.substr(0, nodeName.rfind("_SCGR_")); |
| 1012 | + } |
| 1013 | + // eliminate 3D studio max name -faces |
| 1014 | + if (nodeName.find("-FACES") != string::npos) |
| 1015 | + { |
| 1016 | + nodeName = nodeName.substr(0, nodeName.rfind("-FACES")); |
| 1017 | + } |
| 1018 | + // eliminate 3D studio max name _faces |
| 1019 | + if (nodeName.find("_FACES") != string::npos) |
| 1020 | + { |
| 1021 | + nodeName = nodeName.substr(0, nodeName.rfind("_FACES")); |
| 1022 | + } |
| 1023 | + // eliminate numbers at the end |
| 1024 | + while ((nodeName.length() > 0) && (nodeName[nodeName.length() - 1] >= '0') && (nodeName[nodeName.length() - 1] <= '9')) |
| 1025 | + { |
| 1026 | + nodeName.erase(nodeName.length() - 1, 1); |
| 1027 | + } |
| 1028 | + |
| 1029 | + // replace underlines with blanks |
| 1030 | + if (nodeName.length() > 0 && nodeName[nodeName.length() - 1] == '_') |
| 1031 | + { |
| 1032 | + nodeName.erase(nodeName.length() - 1); |
| 1033 | + } |
| 1034 | + |
| 1035 | + // check if we now have an empty string (containing spaces only) |
| 1036 | + if (nodeName.length() > 0) |
| 1037 | + { |
| 1038 | + selectionName->setText(nodeName); |
| 1039 | + |
| 1040 | + // delete []labelName; |
| 1041 | + oldIntersectedNode = cover->getIntersectedNode(); |
| 1042 | + } |
| 1043 | + else |
| 1044 | + { |
| 1045 | + selectionName->setText("-"); |
| 1046 | + oldIntersectedNode = NULL; |
| 1047 | + } |
| 1048 | + } |
| 1049 | + else |
| 1050 | + { |
| 1051 | + selectionName->setText("-"); |
| 1052 | + oldIntersectedNode = NULL; |
| 1053 | + } |
| 1054 | + } |
| 1055 | + else |
| 1056 | + { |
| 1057 | + selectionName->setText("-"); |
| 1058 | + oldIntersectedNode = NULL; |
| 1059 | + } |
| 1060 | + } |
| 1061 | + else |
| 1062 | + { |
| 1063 | + selectionName->setText("-"); |
| 1064 | + oldIntersectedNode = NULL; |
| 1065 | + } |
| 1066 | + } |
898 | 1067 | return false; // don't request that scene be re-rendered |
899 | 1068 | } |
900 | 1069 | GeoDataLoader *GeoDataLoader::instance() |
@@ -1015,3 +1184,85 @@ for (int layerIt = 0; layerIt < poDS->GetLayerCount(); ++layerIt) |
1015 | 1184 | } |
1016 | 1185 |
|
1017 | 1186 | COVERPLUGIN(GeoDataLoader) |
| 1187 | + |
| 1188 | +void editTerrain::createGeometry() |
| 1189 | +{ |
| 1190 | + |
| 1191 | + osg::Sphere *mySphere = new osg::Sphere(osg::Vec3(0, 0, 0), 1.0); |
| 1192 | + osg::TessellationHints *hint = new osg::TessellationHints(); |
| 1193 | + hint->setDetailRatio(0.5); |
| 1194 | + osg::ShapeDrawable *mySphereDrawable = new osg::ShapeDrawable(mySphere, hint); |
| 1195 | + mySphereDrawable->setColor(osg::Vec4(0.6f, 0.6f, 0.6f, 1.0f)); |
| 1196 | + geometryNode = new osg::Geode(); |
| 1197 | + scaleTransform->addChild(geometryNode.get()); |
| 1198 | + moveTransform->addChild(scaleTransform.get()); |
| 1199 | + ((osg::Geode *)geometryNode.get())->addDrawable(mySphereDrawable); |
| 1200 | + geometryNode->setStateSet(VRSceneGraph::instance()->loadDefaultGeostate()); |
| 1201 | + geometryNode->setNodeMask(geometryNode->getNodeMask() | (Isect::Pick) | (Isect::Intersection)); |
| 1202 | +} |
| 1203 | + |
| 1204 | + |
| 1205 | +editTerrain::editTerrain(GeoDataLoader *g) |
| 1206 | + : vrui::coCombinedButtonInteraction(vrui::coInteraction::ButtonA, "editTerrain", vrui::coInteraction::InteractionPriority::Medium) |
| 1207 | +{ |
| 1208 | + gdl = g; |
| 1209 | + _selectedHl = new osg::StateSet(); |
| 1210 | + _intersectedHl = new osg::StateSet(); |
| 1211 | + |
| 1212 | + if (_standardHL) |
| 1213 | + { |
| 1214 | + // set default materials |
| 1215 | + osg::Material *selMaterial = new osg::Material(); |
| 1216 | + selMaterial->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1.0, 0.3, 0.0, 1.0f)); |
| 1217 | + selMaterial->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(1.0, 0.3, 0.0, 1.0f)); |
| 1218 | + selMaterial->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.1f, 0.1f, 0.1f, 1.0f)); |
| 1219 | + selMaterial->setShininess(osg::Material::FRONT_AND_BACK, 10.f); |
| 1220 | + selMaterial->setColorMode(osg::Material::OFF); |
| 1221 | + osg::Material *isectMaterial = new osg::Material(); |
| 1222 | + isectMaterial->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.6, 0.6, 0.0, 1.0f)); |
| 1223 | + isectMaterial->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.6, 0.6, 0.0, 1.0f)); |
| 1224 | + isectMaterial->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.1f, 0.1f, 0.1f, 1.0f)); |
| 1225 | + isectMaterial->setShininess(osg::Material::FRONT_AND_BACK, 10.f); |
| 1226 | + isectMaterial->setColorMode(osg::Material::OFF); |
| 1227 | + _selectedHl->setAttribute(selMaterial, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED); |
| 1228 | + _intersectedHl->setAttribute(isectMaterial, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED); |
| 1229 | + } |
| 1230 | + |
| 1231 | + _selectedHl->setAttributeAndModes(polymode, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON); |
| 1232 | + _selectedHl->setAttributeAndModes(polymode, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON); |
| 1233 | +} |
| 1234 | + |
| 1235 | +void editTerrain::enableIntersection() |
| 1236 | +{ |
| 1237 | + if (cover->debugLevel(4)) |
| 1238 | + fprintf(stderr, "coVRIntersectionInteractor(%s)::enableIntersection\n", _interactorName); |
| 1239 | + |
| 1240 | + coInteractionManager::the()->registerInteraction(this); |
| 1241 | +} |
| 1242 | + |
| 1243 | +void editTerrain::disableIntersection() |
| 1244 | +{ |
| 1245 | + if (cover->debugLevel(2)) |
| 1246 | + fprintf(stderr, "coVRIntersectionInteractor(%s)::disableIntersection\n", _interactorName); |
| 1247 | + |
| 1248 | + // interactor is normally unregistered in miss |
| 1249 | + // if we disable intersection miss is not called anymore |
| 1250 | + // therefore we make sure that the interactor is unregistered |
| 1251 | + if (registered) |
| 1252 | + { |
| 1253 | + coInteractionManager::the()->unregisterInteraction(this); |
| 1254 | + } |
| 1255 | + |
| 1256 | + resetState(); |
| 1257 | +} |
| 1258 | + |
| 1259 | +void GeoDataLoader::doDelete() |
| 1260 | +{ |
| 1261 | +} |
| 1262 | +void GeoDataLoader::doReplace() |
| 1263 | +{ |
| 1264 | +} |
| 1265 | +void GeoDataLoader::doUndo() |
| 1266 | +{ |
| 1267 | +} |
| 1268 | + |
0 commit comments