void RenderableDebugableEntityItem::renderBoundingBox(EntityItem* entity, RenderArgs* args,
                                                      float puffedOut, glm::vec4& color) {
    Q_ASSERT(args->_batch);
    gpu::Batch& batch = *args->_batch;

    auto shapeTransform = entity->getTransformToCenter();
    if (puffedOut != 0.0f) {
        shapeTransform.postScale(1.0f + puffedOut);
    }
    batch.setModelTransform(Transform()); // we want to include the scale as well
    DependencyManager::get<DeferredLightingEffect>()->renderWireCubeInstance(batch, shapeTransform, color);
}
Exemplo n.º 2
0
void Circle3DOverlay::render(RenderArgs* args) {
    if (!_visible) {
        return; // do nothing if we're not visible
    }

    float alpha = getAlpha();

    if (alpha == 0.0f) {
        return; // do nothing if our alpha is 0, we're not visible
    }

    // Create the circle in the coordinates origin
    float outerRadius = getOuterRadius();
    float innerRadius = getInnerRadius(); // only used in solid case
    float startAt = getStartAt();
    float endAt = getEndAt();

    bool geometryChanged = (startAt != _lastStartAt || endAt != _lastEndAt ||
                                innerRadius != _lastInnerRadius || outerRadius != _lastOuterRadius);


    const float FULL_CIRCLE = 360.0f;
    const float SLICES = 180.0f;  // The amount of segment to create the circle
    const float SLICE_ANGLE = FULL_CIRCLE / SLICES;

    //const int slices = 15;
    xColor colorX = getColor();
    const float MAX_COLOR = 255.0f;
    glm::vec4 color(colorX.red / MAX_COLOR, colorX.green / MAX_COLOR, colorX.blue / MAX_COLOR, alpha);

    bool colorChanged = colorX.red != _lastColor.red || colorX.green != _lastColor.green || colorX.blue != _lastColor.blue;
    _lastColor = colorX;

    auto geometryCache = DependencyManager::get<GeometryCache>();
    
    Q_ASSERT(args->_batch);
    auto& batch = *args->_batch;
    batch._glLineWidth(_lineWidth);
    
    auto transform = _transform;
    transform.postScale(glm::vec3(getDimensions(), 1.0f));
    batch.setModelTransform(transform);
    DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch, false, false);
    
    // for our overlay, is solid means we draw a ring between the inner and outer radius of the circle, otherwise
    // we just draw a line...
    if (getIsSolid()) {
        if (_quadVerticesID == GeometryCache::UNKNOWN_ID) {
            _quadVerticesID = geometryCache->allocateID();
        }
        
        if (geometryChanged || colorChanged) {
            
            QVector<glm::vec2> points;
            
            float angle = startAt;
            float angleInRadians = glm::radians(angle);
            glm::vec2 mostRecentInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius);
            glm::vec2 mostRecentOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
            
            while (angle < endAt) {
                angleInRadians = glm::radians(angle);
                glm::vec2 thisInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius);
                glm::vec2 thisOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
                
                points << mostRecentInnerPoint << mostRecentOuterPoint << thisOuterPoint; // first triangle
                points << mostRecentInnerPoint << thisInnerPoint << thisOuterPoint; // second triangle
                
                angle += SLICE_ANGLE;

                mostRecentInnerPoint = thisInnerPoint;
                mostRecentOuterPoint = thisOuterPoint;
            }
            
            // get the last slice portion....
            angle = endAt;
            angleInRadians = glm::radians(angle);
            glm::vec2 lastInnerPoint(cosf(angleInRadians) * innerRadius, sinf(angleInRadians) * innerRadius);
            glm::vec2 lastOuterPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);

            points << mostRecentInnerPoint << mostRecentOuterPoint << lastOuterPoint; // first triangle
            points << mostRecentInnerPoint << lastInnerPoint << lastOuterPoint; // second triangle
            
            geometryCache->updateVertices(_quadVerticesID, points, color);
        }
        
        geometryCache->renderVertices(batch, gpu::TRIANGLES, _quadVerticesID);
        
    } else {
        if (_lineVerticesID == GeometryCache::UNKNOWN_ID) {
            _lineVerticesID = geometryCache->allocateID();
        }
        
        if (geometryChanged || colorChanged) {
            QVector<glm::vec2> points;
            
            float angle = startAt;
            float angleInRadians = glm::radians(angle);
            glm::vec2 firstPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
            points << firstPoint;
            
            while (angle < endAt) {
                angle += SLICE_ANGLE;
                angleInRadians = glm::radians(angle);
                glm::vec2 thisPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
                points << thisPoint;
                
                if (getIsDashedLine()) {
                    angle += SLICE_ANGLE / 2.0f; // short gap
                    angleInRadians = glm::radians(angle);
                    glm::vec2 dashStartPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
                    points << dashStartPoint;
                }
            }
            
            // get the last slice portion....
            angle = endAt;
            angleInRadians = glm::radians(angle);
            glm::vec2 lastPoint(cosf(angleInRadians) * outerRadius, sinf(angleInRadians) * outerRadius);
            points << lastPoint;
            
            geometryCache->updateVertices(_lineVerticesID, points, color);
        }
        
        if (getIsDashedLine()) {
            geometryCache->renderVertices(batch, gpu::LINES, _lineVerticesID);
        } else {
            geometryCache->renderVertices(batch, gpu::LINE_STRIP, _lineVerticesID);
        }
    }
    
    // draw our tick marks
    // for our overlay, is solid means we draw a ring between the inner and outer radius of the circle, otherwise
    // we just draw a line...
    if (getHasTickMarks()) {
        
        if (_majorTicksVerticesID == GeometryCache::UNKNOWN_ID) {
            _majorTicksVerticesID = geometryCache->allocateID();
        }
        if (_minorTicksVerticesID == GeometryCache::UNKNOWN_ID) {
            _minorTicksVerticesID = geometryCache->allocateID();
        }
        
        if (geometryChanged) {
            QVector<glm::vec2> majorPoints;
            QVector<glm::vec2> minorPoints;
            
            // draw our major tick marks
            if (getMajorTickMarksAngle() > 0.0f && getMajorTickMarksLength() != 0.0f) {
                
                float tickMarkAngle = getMajorTickMarksAngle();
                float angle = startAt - fmodf(startAt, tickMarkAngle) + tickMarkAngle;
                float angleInRadians = glm::radians(angle);
                float tickMarkLength = getMajorTickMarksLength();
                float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius;
                float endRadius = startRadius + tickMarkLength;
                
                while (angle <= endAt) {
                    angleInRadians = glm::radians(angle);
                    
                    glm::vec2 thisPointA(cosf(angleInRadians) * startRadius, sinf(angleInRadians) * startRadius);
                    glm::vec2 thisPointB(cosf(angleInRadians) * endRadius, sinf(angleInRadians) * endRadius);
                    
                    majorPoints << thisPointA << thisPointB;
                    
                    angle += tickMarkAngle;
                }
            }
            
            // draw our minor tick marks
            if (getMinorTickMarksAngle() > 0.0f && getMinorTickMarksLength() != 0.0f) {
                
                float tickMarkAngle = getMinorTickMarksAngle();
                float angle = startAt - fmodf(startAt, tickMarkAngle) + tickMarkAngle;
                float angleInRadians = glm::radians(angle);
                float tickMarkLength = getMinorTickMarksLength();
                float startRadius = (tickMarkLength > 0.0f) ? innerRadius : outerRadius;
                float endRadius = startRadius + tickMarkLength;
                
                while (angle <= endAt) {
                    angleInRadians = glm::radians(angle);
                    
                    glm::vec2 thisPointA(cosf(angleInRadians) * startRadius, sinf(angleInRadians) * startRadius);
                    glm::vec2 thisPointB(cosf(angleInRadians) * endRadius, sinf(angleInRadians) * endRadius);
                    
                    minorPoints << thisPointA << thisPointB;
                    
                    angle += tickMarkAngle;
                }
            }
            
            xColor majorColorX = getMajorTickMarksColor();
            glm::vec4 majorColor(majorColorX.red / MAX_COLOR, majorColorX.green / MAX_COLOR, majorColorX.blue / MAX_COLOR, alpha);
            
            geometryCache->updateVertices(_majorTicksVerticesID, majorPoints, majorColor);
            
            xColor minorColorX = getMinorTickMarksColor();
            glm::vec4 minorColor(minorColorX.red / MAX_COLOR, minorColorX.green / MAX_COLOR, minorColorX.blue / MAX_COLOR, alpha);
            
            geometryCache->updateVertices(_minorTicksVerticesID, minorPoints, minorColor);
        }
        
        geometryCache->renderVertices(batch, gpu::LINES, _majorTicksVerticesID);
        
        geometryCache->renderVertices(batch, gpu::LINES, _minorTicksVerticesID);
    }
    
    if (geometryChanged) {
        _lastStartAt = startAt;
        _lastEndAt = endAt;
        _lastInnerRadius = innerRadius;
        _lastOuterRadius = outerRadius;
    }
}
Exemplo n.º 3
0
void MayaCameraWriter::write()
{
    MFnCamera mfnCamera(mDagPath);

    mSamp.setFocalLength(mfnCamera.focalLength());
    mSamp.setLensSqueezeRatio(mfnCamera.lensSqueezeRatio());
    mSamp.setHorizontalAperture(mfnCamera.horizontalFilmAperture() * 2.54);
    mSamp.setVerticalAperture(mfnCamera.verticalFilmAperture() * 2.54);
    mSamp.setHorizontalFilmOffset(mfnCamera.horizontalFilmOffset() * 2.54);
    mSamp.setVerticalFilmOffset(mfnCamera.verticalFilmOffset() * 2.54);
    double overscan = mfnCamera.overscan() - 1.0;
    mSamp.setOverScanLeft(overscan);
    mSamp.setOverScanRight(overscan);
    mSamp.setOverScanTop(overscan);
    mSamp.setOverScanBottom(overscan);
    mSamp.setNearClippingPlane(mfnCamera.nearClippingPlane());
    mSamp.setFarClippingPlane(mfnCamera.farClippingPlane());
    mSamp.setFStop(mfnCamera.fStop());
    mSamp.setFocusDistance(mfnCamera.focusDistance());

    // should this be based on the shutterAngle?  or the settings passed in?

    if (mUseRenderShutter)
    {
        mSamp.setShutterOpen(mShutterOpen);
        mSamp.setShutterClose(mShutterClose);
    }
    else
    {
        MTime sec(1.0, MTime::kSeconds);
        mSamp.setShutterOpen(0.0);
        mSamp.setShutterClose(
            Alembic::AbcGeom::RadiansToDegrees(mfnCamera.shutterAngle()) /
            ( 360.0 * sec.as(MTime::uiUnit()) ));
    }

    // build up the film fit and post projection matrix
    if (mSchema.getNumSamples() == 0)
    {
        // film fit first
        std::string filmFitName = "filmFit";
        mFilmFit = mfnCamera.filmFit();
        switch (mFilmFit)
        {
            case MFnCamera::kFillFilmFit:
            {
                Alembic::AbcGeom::FilmBackXformOp fit(
                    Alembic::AbcGeom::kScaleFilmBackOperation, "filmFitFill");
                mSamp.addOp(fit);
            }
            break;

            case MFnCamera::kHorizontalFilmFit:
            {
                Alembic::AbcGeom::FilmBackXformOp fit(
                    Alembic::AbcGeom::kScaleFilmBackOperation, "filmFitHorz");
                mSamp.addOp(fit);

                Alembic::AbcGeom::FilmBackXformOp offset(
                    Alembic::AbcGeom::kTranslateFilmBackOperation,
                    "filmFitOffs");
                mSamp.addOp(offset);
            }
            break;

            case MFnCamera::kVerticalFilmFit:
            {
                Alembic::AbcGeom::FilmBackXformOp fit(
                    Alembic::AbcGeom::kScaleFilmBackOperation, "filmFitVert");
                mSamp.addOp(fit);

                Alembic::AbcGeom::FilmBackXformOp offset(
                    Alembic::AbcGeom::kTranslateFilmBackOperation,
                    "filmFitOffs");
                mSamp.addOp(offset);
            }
            break;

            case MFnCamera::kOverscanFilmFit:
            {
                Alembic::AbcGeom::FilmBackXformOp fit(
                    Alembic::AbcGeom::kScaleFilmBackOperation, "filmFitOver");
                mSamp.addOp(fit);
            }
            break;

            default:
            break;
        }

        Alembic::AbcGeom::FilmBackXformOp preScale(
            Alembic::AbcGeom::kScaleFilmBackOperation, "preScale");
        mSamp.addOp(preScale);

        Alembic::AbcGeom::FilmBackXformOp filmTranslate(
            Alembic::AbcGeom::kTranslateFilmBackOperation, "filmTranslate");
        mSamp.addOp(filmTranslate);

        // skip film roll for now

        Alembic::AbcGeom::FilmBackXformOp postScale(
            Alembic::AbcGeom::kScaleFilmBackOperation, "postScale");
        mSamp.addOp(postScale);

        Alembic::AbcGeom::FilmBackXformOp cameraScale(
            Alembic::AbcGeom::kScaleFilmBackOperation, "cameraScale");
        mSamp.addOp(cameraScale);

    }

    std::size_t filmBackIndex = 0;

    switch (mFilmFit)
    {
        case MFnCamera::kFillFilmFit:
        {
            if (mSamp.getLensSqueezeRatio() > 1.0)
            {
                mSamp[0].setChannelValue(0, 1.0/mSamp.getLensSqueezeRatio());
                mSamp[0].setChannelValue(1, 1.0);
            }
            else
            {
                mSamp[0].setChannelValue(0, 1.0);
                mSamp[0].setChannelValue(1, mSamp.getLensSqueezeRatio());
            }
            filmBackIndex = 1;
        }
        break;

        case MFnCamera::kHorizontalFilmFit:
        {
            if (mSamp.getLensSqueezeRatio() > 1.0)
            {
                mSamp[0].setChannelValue(0, 1.0);
                mSamp[0].setChannelValue(1, mSamp.getLensSqueezeRatio());
                mSamp[1].setChannelValue(0, 0.0);
                mSamp[1].setChannelValue(1, 2.0 *
                    mfnCamera.filmFitOffset()/
                    mfnCamera.horizontalFilmAperture() );
            }
            else
            {
                mSamp[0].setChannelValue(0, 1.0);
                mSamp[0].setChannelValue(1, 1.0);
                mSamp[1].setChannelValue(0, 0.0);
                mSamp[1].setChannelValue(1, 0.0);
            }
            filmBackIndex = 2;
        }
        break;

        case MFnCamera::kVerticalFilmFit:
        {
            if (1.0/mSamp.getLensSqueezeRatio() > 1.0)
            {
                mSamp[0].setChannelValue(0, 1.0/mSamp.getLensSqueezeRatio());
                mSamp[0].setChannelValue(1, 1.0);
                mSamp[1].setChannelValue(0, 2.0 *
                    mfnCamera.filmFitOffset() /
                    mfnCamera.horizontalFilmAperture() );
                mSamp[1].setChannelValue(1, 0.0);
            }
            else
            {
                mSamp[0].setChannelValue(0, 1.0);
                mSamp[0].setChannelValue(1, 1.0);
                mSamp[1].setChannelValue(0, 0.0);
                mSamp[1].setChannelValue(1, 0.0);
            }
            filmBackIndex = 2;
        }
        break;

        case MFnCamera::kOverscanFilmFit:
        {
            if (mSamp.getLensSqueezeRatio() < 1.0)
            {
                mSamp[0].setChannelValue(0, 1.0);
                mSamp[0].setChannelValue(1, mSamp.getLensSqueezeRatio());
            }
            else
            {
                mSamp[0].setChannelValue(0, 1.0/mSamp.getLensSqueezeRatio());
                mSamp[0].setChannelValue(1, 1.0);
            }
            filmBackIndex = 1;
        }
        break;

        default:
        break;
    }

    mSamp[filmBackIndex].setChannelValue(0, 1.0/mfnCamera.preScale());
    mSamp[filmBackIndex].setChannelValue(1, 1.0/mfnCamera.preScale());

    mSamp[filmBackIndex+1].setChannelValue(0, mfnCamera.filmTranslateH());
    mSamp[filmBackIndex+1].setChannelValue(1, mfnCamera.filmTranslateV());

    mSamp[filmBackIndex+2].setChannelValue(0, 1.0/mfnCamera.postScale());
    mSamp[filmBackIndex+2].setChannelValue(1, 1.0/mfnCamera.postScale());

    mSamp[filmBackIndex+3].setChannelValue(0, mfnCamera.cameraScale());
    mSamp[filmBackIndex+3].setChannelValue(1, mfnCamera.cameraScale());

    mSchema.set(mSamp);
}
Exemplo n.º 4
0
Transform Image3DOverlay::evalRenderTransform() {
    auto transform = Parent::evalRenderTransform();
    transform.postScale(glm::vec3(getDimensions(), 1.0f));
    return transform;
}
Exemplo n.º 5
0
void RenderableZoneEntityItem::render(RenderArgs* args) {
    Q_ASSERT(getType() == EntityTypes::Zone);

    if (_drawZoneBoundaries) {
        switch (getShapeType()) {
            case SHAPE_TYPE_COMPOUND: {
                PerformanceTimer perfTimer("zone->renderCompound");
                updateGeometry();
                if (_model && _model->needsFixupInScene()) {
                    // check to see if when we added our models to the scene they were ready, if they were not ready, then
                    // fix them up in the scene
                    render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene();
                    render::Transaction transaction;
                    _model->removeFromScene(scene, transaction);
                    render::Item::Status::Getters statusGetters;
                    makeEntityItemStatusGetters(getThisPointer(), statusGetters);
                    _model->addToScene(scene, transaction);

                    scene->enqueueTransaction(transaction);

                    _model->setVisibleInScene(getVisible(), scene);
                }
                break;
            }
            case SHAPE_TYPE_BOX:
            case SHAPE_TYPE_SPHERE: {
                PerformanceTimer perfTimer("zone->renderPrimitive");
                glm::vec4 DEFAULT_COLOR(1.0f, 1.0f, 1.0f, 1.0f);

                Q_ASSERT(args->_batch);
                gpu::Batch& batch = *args->_batch;

                bool success;
                auto shapeTransform = getTransformToCenter(success);
                if (!success) {
                    break;
                }
                auto geometryCache = DependencyManager::get<GeometryCache>();
                if (getShapeType() == SHAPE_TYPE_SPHERE) {
                    shapeTransform.postScale(SPHERE_ENTITY_SCALE);
                    batch.setModelTransform(shapeTransform);
                    geometryCache->renderWireSphereInstance(args, batch, DEFAULT_COLOR);
                } else {
                    batch.setModelTransform(shapeTransform);
                    geometryCache->renderWireCubeInstance(args, batch, DEFAULT_COLOR);
                }
                break;
            }
            default:
                // Not handled
                break;
        }
    }

    if ((!_drawZoneBoundaries || getShapeType() != SHAPE_TYPE_COMPOUND) &&
        _model && !_model->needsFixupInScene()) {
        // If the model is in the scene but doesn't need to be, remove it.
        render::ScenePointer scene = AbstractViewStateInterface::instance()->getMain3DScene();
        render::Transaction transaction;
        _model->removeFromScene(scene, transaction);
        scene->enqueueTransaction(transaction);
    }
}
Exemplo n.º 6
0
void Circle3DOverlay::render(RenderArgs* args) {
    if (!_visible) {
        return; // do nothing if we're not visible
    }

    float alpha = getAlpha();
    if (alpha == 0.0f) {
        return; // do nothing if our alpha is 0, we're not visible
    }

    bool geometryChanged = _dirty;
    _dirty = false;

    const float FULL_CIRCLE = 360.0f;
    const float SLICES = 180.0f;  // The amount of segment to create the circle
    const float SLICE_ANGLE = FULL_CIRCLE / SLICES;
    const float MAX_COLOR = 255.0f;

    auto geometryCache = DependencyManager::get<GeometryCache>();

    Q_ASSERT(args->_batch);
    auto& batch = *args->_batch;
    if (args->_pipeline) {
        batch.setPipeline(args->_pipeline->pipeline);
    }

    // FIXME: THe line width of _lineWidth is not supported anymore, we ll need a workaround

    auto transform = getTransform();
    transform.postScale(glm::vec3(getDimensions(), 1.0f));
    batch.setModelTransform(transform);

    // for our overlay, is solid means we draw a ring between the inner and outer radius of the circle, otherwise
    // we just draw a line...
    if (getIsSolid()) {
        if (!_quadVerticesID) {
            _quadVerticesID = geometryCache->allocateID();
        }

        if (geometryChanged) {
            QVector<glm::vec2> points;
            QVector<glm::vec4> colors;

            float pulseLevel = updatePulse();
            vec4 pulseModifier = vec4(1);
            if (_alphaPulse != 0.0f) {
                pulseModifier.a = (_alphaPulse >= 0.0f) ? pulseLevel : (1.0f - pulseLevel);
            }
            if (_colorPulse != 0.0f) {
                float pulseValue = (_colorPulse >= 0.0f) ? pulseLevel : (1.0f - pulseLevel);
                pulseModifier = vec4(vec3(pulseValue), pulseModifier.a);
            }
            vec4 innerStartColor = vec4(toGlm(_innerStartColor), _innerStartAlpha) * pulseModifier;
            vec4 outerStartColor = vec4(toGlm(_outerStartColor), _outerStartAlpha) * pulseModifier;
            vec4 innerEndColor = vec4(toGlm(_innerEndColor), _innerEndAlpha) * pulseModifier;
            vec4 outerEndColor = vec4(toGlm(_outerEndColor), _outerEndAlpha) * pulseModifier;

            if (_innerRadius <= 0) {
                _solidPrimitive = gpu::TRIANGLE_FAN;
                points << vec2();
                colors << innerStartColor;
                for (float angle = _startAt; angle <= _endAt; angle += SLICE_ANGLE) {
                    float range = (angle - _startAt) / (_endAt - _startAt);
                    float angleRadians = glm::radians(angle);
                    points << glm::vec2(cosf(angleRadians) * _outerRadius, sinf(angleRadians) * _outerRadius);
                    colors << glm::mix(outerStartColor, outerEndColor, range);
                }
            } else {
                _solidPrimitive = gpu::TRIANGLE_STRIP;
                for (float angle = _startAt; angle <= _endAt; angle += SLICE_ANGLE) {
                    float range = (angle - _startAt) / (_endAt - _startAt);

                    float angleRadians = glm::radians(angle);
                    points << glm::vec2(cosf(angleRadians) * _innerRadius, sinf(angleRadians) * _innerRadius);
                    colors << glm::mix(innerStartColor, innerEndColor, range);

                    points << glm::vec2(cosf(angleRadians) * _outerRadius, sinf(angleRadians) * _outerRadius);
                    colors << glm::mix(outerStartColor, outerEndColor, range);
                }
            }
            geometryCache->updateVertices(_quadVerticesID, points, colors);
        }
        
        geometryCache->renderVertices(batch, _solidPrimitive, _quadVerticesID);
        
    } else {
        if (!_lineVerticesID) {
            _lineVerticesID = geometryCache->allocateID();
        }
        
        if (geometryChanged) {
            QVector<glm::vec2> points;
            
            float angle = _startAt;
            float angleInRadians = glm::radians(angle);
            glm::vec2 firstPoint(cosf(angleInRadians) * _outerRadius, sinf(angleInRadians) * _outerRadius);
            points << firstPoint;
            
            while (angle < _endAt) {
                angle += SLICE_ANGLE;
                angleInRadians = glm::radians(angle);
                glm::vec2 thisPoint(cosf(angleInRadians) * _outerRadius, sinf(angleInRadians) * _outerRadius);
                points << thisPoint;
                
                if (getIsDashedLine()) {
                    angle += SLICE_ANGLE / 2.0f; // short gap
                    angleInRadians = glm::radians(angle);
                    glm::vec2 dashStartPoint(cosf(angleInRadians) * _outerRadius, sinf(angleInRadians) * _outerRadius);
                    points << dashStartPoint;
                }
            }
            
            // get the last slice portion....
            angle = _endAt;
            angleInRadians = glm::radians(angle);
            glm::vec2 lastPoint(cosf(angleInRadians) * _outerRadius, sinf(angleInRadians) * _outerRadius);
            points << lastPoint;
            geometryCache->updateVertices(_lineVerticesID, points, vec4(toGlm(getColor()), getAlpha()));
        }
        
        if (getIsDashedLine()) {
            geometryCache->renderVertices(batch, gpu::LINES, _lineVerticesID);
        } else {
            geometryCache->renderVertices(batch, gpu::LINE_STRIP, _lineVerticesID);
        }
    }
    
    // draw our tick marks
    // for our overlay, is solid means we draw a ring between the inner and outer radius of the circle, otherwise
    // we just draw a line...
    if (getHasTickMarks()) {
        
        if (_majorTicksVerticesID == GeometryCache::UNKNOWN_ID) {
            _majorTicksVerticesID = geometryCache->allocateID();
        }
        if (_minorTicksVerticesID == GeometryCache::UNKNOWN_ID) {
            _minorTicksVerticesID = geometryCache->allocateID();
        }
        
        if (geometryChanged) {
            QVector<glm::vec2> majorPoints;
            QVector<glm::vec2> minorPoints;
            
            // draw our major tick marks
            if (getMajorTickMarksAngle() > 0.0f && getMajorTickMarksLength() != 0.0f) {
                
                float tickMarkAngle = getMajorTickMarksAngle();
                float angle = _startAt - fmodf(_startAt, tickMarkAngle) + tickMarkAngle;
                float angleInRadians = glm::radians(angle);
                float tickMarkLength = getMajorTickMarksLength();
                float startRadius = (tickMarkLength > 0.0f) ? _innerRadius : _outerRadius;
                float endRadius = startRadius + tickMarkLength;
                
                while (angle <= _endAt) {
                    angleInRadians = glm::radians(angle);
                    
                    glm::vec2 thisPointA(cosf(angleInRadians) * startRadius, sinf(angleInRadians) * startRadius);
                    glm::vec2 thisPointB(cosf(angleInRadians) * endRadius, sinf(angleInRadians) * endRadius);
                    
                    majorPoints << thisPointA << thisPointB;
                    
                    angle += tickMarkAngle;
                }
            }
            
            // draw our minor tick marks
            if (getMinorTickMarksAngle() > 0.0f && getMinorTickMarksLength() != 0.0f) {
                
                float tickMarkAngle = getMinorTickMarksAngle();
                float angle = _startAt - fmodf(_startAt, tickMarkAngle) + tickMarkAngle;
                float angleInRadians = glm::radians(angle);
                float tickMarkLength = getMinorTickMarksLength();
                float startRadius = (tickMarkLength > 0.0f) ? _innerRadius : _outerRadius;
                float endRadius = startRadius + tickMarkLength;
                
                while (angle <= _endAt) {
                    angleInRadians = glm::radians(angle);
                    
                    glm::vec2 thisPointA(cosf(angleInRadians) * startRadius, sinf(angleInRadians) * startRadius);
                    glm::vec2 thisPointB(cosf(angleInRadians) * endRadius, sinf(angleInRadians) * endRadius);
                    
                    minorPoints << thisPointA << thisPointB;
                    
                    angle += tickMarkAngle;
                }
            }
            
            xColor majorColorX = getMajorTickMarksColor();
            glm::vec4 majorColor(majorColorX.red / MAX_COLOR, majorColorX.green / MAX_COLOR, majorColorX.blue / MAX_COLOR, alpha);
            
            geometryCache->updateVertices(_majorTicksVerticesID, majorPoints, majorColor);
            
            xColor minorColorX = getMinorTickMarksColor();
            glm::vec4 minorColor(minorColorX.red / MAX_COLOR, minorColorX.green / MAX_COLOR, minorColorX.blue / MAX_COLOR, alpha);
            
            geometryCache->updateVertices(_minorTicksVerticesID, minorPoints, minorColor);
        }
        
        geometryCache->renderVertices(batch, gpu::LINES, _majorTicksVerticesID);
        
        geometryCache->renderVertices(batch, gpu::LINES, _minorTicksVerticesID);
    }
}