0
votes

I've been trying to create an openGL gluDisk like object in osgEarth. So far I've attempted to do the following (Edited, this is the correct answer):

void ViewDriver::drawCircZone(double lat, double lon, double innerRadius, double outerRadius, QColor color, double beginAngle, double endAngle){
    GeometryFactory g;
    osg::ref_ptr<osgEarth::Geometry> outerCircleGeom = g.createArc(osg::Vec3d(lat, lon, 0), convertFromMetersToMercDeg(outerRadius), beginAngle, endAngle);
    osg::ref_ptr<osgEarth::Geometry> innerCircleGeom = g.createArc(osg::Vec3d(lat, lon, 0), convertFromMetersToMercDeg(innerRadius), beginAngle, endAngle);

    osg::Vec3dArray* outerCircArray = outerCircleGeom->createVec3dArray();
    osg::Vec3dArray* innerCircArray = innerCircleGeom->createVec3dArray();

    Vec3dVector* diskVec = new Vec3dVector;

    for(int i = 0; i < outerCircArray->size() - 1; i++){
        diskVec->push_back((*outerCircArray)[i]);
    }
    //This is important for closing the shape and not giving it a Pac-Man-like mouth
    diskVec->push_back((*outerCircArray)[0]);

    //This is how you make a "hole", by iterating backwards 
    for(int i = innerCircArray->size() - 1; i >= 0; i--){
        diskVec->push_back((*innerCircArray)[i]);
    }

    osg::ref_ptr<osgEarth::Symbology::Ring> diskRing = new Ring(diskVec);
    diskRing->close();

    osg::ref_ptr<Feature> circFeature = new Feature(diskRing, view->getMapViewer()->geoSRS);

    Style circStyle;
    circStyle.getOrCreate<PolygonSymbol>()->outline() = true;
    circStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(color.red()/255.0, color.green()/255.0, color.blue()/255.0, 1.0);
    circStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_RELATIVE_TO_TERRAIN;
    circStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_DRAPE;

    osg::ref_ptr<FeatureNode> circNode = new FeatureNode(circFeature, circStyle);
    circNode->setDynamic(true);

    view->getMapNode()->addChild(circNode);
}

What stumped me originally was that I don't have a lot of graphics knowledge. Somewhere I read that when drawing outlines, do it in clockwise direction. When drawing outlines in counter clockwise direction they will "cut-out" or create a "hole" when combined with clockwise-drawn points. I was filling the "hole" outline with the smaller circle's point in a clockwise direction originally when testing that method which was why it didn't work.

1
Post at least the complete createDisk functionNadir
why are you setting the Z coordinate to 100 when copying the inner disk vertices?Nadir
Sometimes if I try to draw a shape at a z = 0, then the clipping with the map terrain occurs and the shape gets hidden underground even when I set the style to Clamp to the Terrain Elevation, I'm not sure why that occurs. I forgot to edit in, that I also do this for the inner and outer circle Geometries too. I'll add the entire function now that I can actually copy and paste it.Blanky

1 Answers

0
votes
void ViewDriver::drawCircZone(double lat, double lon, double innerRadius, double outerRadius, QColor color, double beginAngle, double endAngle){
        GeometryFactory g;
        osg::ref_ptr<osgEarth::Geometry> outerCircleGeom = g.createArc(osg::Vec3d(lat, lon, 0), convertFromMetersToMercDeg(outerRadius), beginAngle, endAngle);
        osg::ref_ptr<osgEarth::Geometry> innerCircleGeom = g.createArc(osg::Vec3d(lat, lon, 0), convertFromMetersToMercDeg(innerRadius), beginAngle, endAngle);

        osg::Vec3dArray* outerCircArray = outerCircleGeom->createVec3dArray();
        osg::Vec3dArray* innerCircArray = innerCircleGeom->createVec3dArray();

        Vec3dVector* diskVec = new Vec3dVector;

        for(int i = 0; i < outerCircArray->size() - 1; i++){
            diskVec->push_back((*outerCircArray)[i]);
        }
        //This is important for closing the shape and not giving it a Pac-Man-like mouth
        diskVec->push_back((*outerCircArray)[0]);

        for(int i = innerCircArray->size() - 1; i >= 0; i--){
            diskVec->push_back((*innerCircArray)[i]);
        }

        osg::ref_ptr<osgEarth::Symbology::Ring> diskRing = new Ring(diskVec);
        diskRing->close();

        osg::ref_ptr<Feature> circFeature = new Feature(diskRing, view->getMapViewer()->geoSRS);

        Style circStyle;
        circStyle.getOrCreate<PolygonSymbol>()->outline() = true;
        circStyle.getOrCreate<PolygonSymbol>()->fill()->color() = Color(color.red()/255.0, color.green()/255.0, color.blue()/255.0, 1.0);
        circStyle.getOrCreate<AltitudeSymbol>()->clamping() = AltitudeSymbol::CLAMP_RELATIVE_TO_TERRAIN;
        circStyle.getOrCreate<AltitudeSymbol>()->technique() = AltitudeSymbol::TECHNIQUE_DRAPE;

        osg::ref_ptr<FeatureNode> circNode = new FeatureNode(circFeature, circStyle);
        circNode->setDynamic(true);

        view->getMapNode()->addChild(circNode);
}