void AtmospherePropertyGroup::debugDump() const { qDebug() << " AtmospherePropertyGroup: ---------------------------------------------"; qDebug() << " Center:" << getCenter() << " has changed:" << centerChanged(); qDebug() << " Inner Radius:" << getInnerRadius() << " has changed:" << innerRadiusChanged(); qDebug() << " Outer Radius:" << getOuterRadius() << " has changed:" << outerRadiusChanged(); qDebug() << " Mie Scattering:" << getMieScattering() << " has changed:" << mieScatteringChanged(); qDebug() << " Rayleigh Scattering:" << getRayleighScattering() << " has changed:" << rayleighScatteringChanged(); qDebug() << " Scattering Wavelengths:" << getScatteringWavelengths() << " has changed:" << scatteringWavelengthsChanged(); qDebug() << " Has Stars:" << getHasStars() << " has changed:" << hasStarsChanged(); }
void AtmospherePropertyGroup::appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, EntityPropertyFlags& propertiesDidntFit, int& propertyCount, OctreeElement::AppendState& appendState) const { bool successPropertyFits = true; APPEND_ENTITY_PROPERTY(PROP_ATMOSPHERE_CENTER, getCenter()); APPEND_ENTITY_PROPERTY(PROP_ATMOSPHERE_INNER_RADIUS, getInnerRadius()); APPEND_ENTITY_PROPERTY(PROP_ATMOSPHERE_OUTER_RADIUS, getOuterRadius()); APPEND_ENTITY_PROPERTY(PROP_ATMOSPHERE_MIE_SCATTERING, getMieScattering()); APPEND_ENTITY_PROPERTY(PROP_ATMOSPHERE_RAYLEIGH_SCATTERING, getRayleighScattering()); APPEND_ENTITY_PROPERTY(PROP_ATMOSPHERE_SCATTERING_WAVELENGTHS, getScatteringWavelengths()); APPEND_ENTITY_PROPERTY(PROP_ATMOSPHERE_HAS_STARS, getHasStars()); }
bool Circle3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face, glm::vec3& surfaceNormal) { // Scale the dimensions by the diameter glm::vec2 dimensions = getOuterRadius() * 2.0f * getDimensions(); bool intersects = findRayRectangleIntersection(origin, direction, getRotation(), getPosition(), dimensions, distance); if (intersects) { glm::vec3 hitPosition = origin + (distance * direction); glm::vec3 localHitPosition = glm::inverse(getRotation()) * (hitPosition - getPosition()); localHitPosition.x /= getDimensions().x; localHitPosition.y /= getDimensions().y; float distanceToHit = glm::length(localHitPosition); intersects = getInnerRadius() <= distanceToHit && distanceToHit <= getOuterRadius(); } return intersects; }
bool Circle3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face) { bool intersects = Planar3DOverlay::findRayIntersection(origin, direction, distance, face); if (intersects) { glm::vec3 hitAt = origin + (direction * distance); float distanceToHit = glm::distance(hitAt, _position); float maxDimension = glm::max(_dimensions.x, _dimensions.y); float innerRadius = maxDimension * getInnerRadius(); float outerRadius = maxDimension * getOuterRadius(); // TODO: this really only works for circles, we should be handling the ellipse case as well... if (distanceToHit < innerRadius || distanceToHit > outerRadius) { intersects = false; } } return intersects; }
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; } }
Vec3f CylinderDistribution3D::generate(void) const { Vec3f Result; switch(getSurfaceOrVolume()) { case SURFACE: { std::vector<Real32> Areas; //Min Cap Areas.push_back(0.5*osgAbs(getMaxTheta() - getMinTheta())*(getOuterRadius()*getOuterRadius() - getInnerRadius()*getInnerRadius())); //Max Cap Areas.push_back(Areas.back() + 0.5*osgAbs(getMaxTheta() - getMinTheta())*(getOuterRadius()*getOuterRadius() - getInnerRadius()*getInnerRadius())); //Inner Tube Areas.push_back(Areas.back() + getInnerRadius()*osgAbs(getMaxTheta() - getMinTheta()) * getHeight()); //Outer Tube Areas.push_back(Areas.back() + getOuterRadius()*osgAbs(getMaxTheta() - getMinTheta()) * getHeight()); bool HasTubeSides(osgAbs(getMaxTheta() - getMinTheta()) - 6.283185 < -0.000001); if(HasTubeSides) { //MinTheta Tube Side Areas.push_back(Areas.back() + (getOuterRadius() - getInnerRadius()) * getHeight()); //MaxTheta Tube Side Areas.push_back(Areas.back() + (getOuterRadius() - getInnerRadius()) * getHeight()); } Real32 PickEdge(RandomPoolManager::getRandomReal32(0.0,1.0)); if(PickEdge < Areas[0]/Areas.back()) { //Max Cap Real32 Temp(osgSqrt(RandomPoolManager::getRandomReal32(0.0,1.0))); Real32 Radius(getInnerRadius() + Temp*(getOuterRadius() - getInnerRadius())); Real32 Theta( RandomPoolManager::getRandomReal32(getMinTheta(),getMaxTheta()) ); Result = getCenter().subZero() + (Radius*osgSin(Theta))*getTangent() + (Radius*osgCos(Theta))*getBinormal() + (getHeight()/static_cast<Real32>(2.0))*getNormal(); } else if(PickEdge < Areas[1]/Areas.back()) { //Min Cap Real32 Temp(osgSqrt(RandomPoolManager::getRandomReal32(0.0,1.0))); Real32 Radius(getInnerRadius() + Temp*(getOuterRadius() - getInnerRadius())); Real32 Theta( RandomPoolManager::getRandomReal32(getMinTheta(),getMaxTheta()) ); Result = getCenter().subZero() + (Radius*osgSin(Theta))*getTangent() + (Radius*osgCos(Theta))*getBinormal() + (-getHeight()/static_cast<Real32>(2.0))*getNormal(); } else if(PickEdge < Areas[2]/Areas.back()) { //Inner Tube Real32 Theta( RandomPoolManager::getRandomReal32(getMinTheta(),getMaxTheta()) ); Real32 Height(RandomPoolManager::getRandomReal32(-getHeight()/2.0,getHeight()/2.0)); Result = getCenter().subZero() + getInnerRadius()*osgSin(Theta)*getTangent() + getInnerRadius()*osgCos(Theta)*getBinormal() + Height*getNormal(); } else if(PickEdge < Areas[3]/Areas.back()) { //Outer Tube Real32 Theta( RandomPoolManager::getRandomReal32(getMinTheta(),getMaxTheta()) ); Real32 Height(RandomPoolManager::getRandomReal32(-getHeight()/2.0,getHeight()/2.0)); Result = getCenter().subZero() + getOuterRadius()*osgSin(Theta)*getTangent() + getOuterRadius()*osgCos(Theta)*getBinormal() + Height*getNormal(); } else if(HasTubeSides && PickEdge < Areas[4]/Areas.back()) { //MinTheta Tube Side Real32 Temp(osgSqrt(RandomPoolManager::getRandomReal32(0.0,1.0))); Real32 Radius(getInnerRadius() + Temp*(getOuterRadius() - getInnerRadius())); Real32 Height(RandomPoolManager::getRandomReal32(-getHeight()/2.0,getHeight()/2.0)); Result = getCenter().subZero() + (Radius*osgSin(getMinTheta()))*getTangent() + (Radius*osgCos(getMinTheta()))*getBinormal() + Height*getNormal(); } else if(HasTubeSides && PickEdge < Areas[5]/Areas.back()) { //MaxTheta Tube Side Real32 Temp(osgSqrt(RandomPoolManager::getRandomReal32(0.0,1.0))); Real32 Radius(getInnerRadius() + Temp*(getOuterRadius() - getInnerRadius())); Real32 Height(RandomPoolManager::getRandomReal32(-getHeight()/2.0,getHeight()/2.0)); Result = getCenter().subZero() + (Radius*osgSin(getMaxTheta()))*getTangent() + (Radius*osgCos(getMaxTheta()))*getBinormal() + Height*getNormal(); } else { assert(false && "Should never reach this point"); } break; } case VOLUME: default: { //To get a uniform distribution across the disc get a uniformly distributed allong 0.0 - 1.0 //Then Take the square root of that. This gives a square root distribution from 0.0 - 1.0 //This square root distribution is used for the random radius because the area of a disc is //dependant on the square of the radius, i.e it is a quadratic function Real32 Temp(osgSqrt(RandomPoolManager::getRandomReal32(0.0,1.0))); Real32 Radius(getInnerRadius() + Temp*(getOuterRadius() - getInnerRadius())); Real32 Height(RandomPoolManager::getRandomReal32(-getHeight()/2.0,getHeight()/2.0)); Real32 Theta( RandomPoolManager::getRandomReal32(getMinTheta(),getMaxTheta()) ); Result = getCenter().subZero() + (Radius*osgSin(Theta))*getTangent() + (Radius*osgCos(Theta))*getBinormal() + Height*getNormal(); break; } } return Result; }
void Circle3DOverlay::render(RenderArgs* args) { if (!_visible) { return; // do nothing if we're not visible } float alpha = getAlpha(); if (alpha == 0.0) { return; // do nothing if our alpha is 0, we're not visible } 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 color = getColor(); const float MAX_COLOR = 255.0f; glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); glDisable(GL_LIGHTING); glm::vec3 position = getPosition(); glm::vec3 center = getCenter(); glm::vec2 dimensions = getDimensions(); glm::quat rotation = getRotation(); float glowLevel = getGlowLevel(); Glower* glower = NULL; if (glowLevel > 0.0f) { glower = new Glower(glowLevel); } glPushMatrix(); glTranslatef(position.x, position.y, position.z); glm::vec3 axis = glm::axis(rotation); glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); glPushMatrix(); glm::vec3 positionToCenter = center - position; glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z); glScalef(dimensions.x, dimensions.y, 1.0f); // Create the circle in the coordinates origin float outerRadius = getOuterRadius(); float innerRadius = getInnerRadius(); // only used in solid case float startAt = getStartAt(); float endAt = getEndAt(); glLineWidth(_lineWidth); // 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()) { glBegin(GL_QUAD_STRIP); float angle = startAt; float angleInRadians = glm::radians(angle); glm::vec2 firstInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius); glm::vec2 firstOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); glVertex2f(firstInnerPoint.x, firstInnerPoint.y); glVertex2f(firstOuterPoint.x, firstOuterPoint.y); while (angle < endAt) { angleInRadians = glm::radians(angle); glm::vec2 thisInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius); glm::vec2 thisOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); glVertex2f(thisOuterPoint.x, thisOuterPoint.y); glVertex2f(thisInnerPoint.x, thisInnerPoint.y); angle += SLICE_ANGLE; } // get the last slice portion.... angle = endAt; angleInRadians = glm::radians(angle); glm::vec2 lastInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius); glm::vec2 lastOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); glVertex2f(lastOuterPoint.x, lastOuterPoint.y); glVertex2f(lastInnerPoint.x, lastInnerPoint.y); glEnd(); } else { if (getIsDashedLine()) { glBegin(GL_LINES); } else { glBegin(GL_LINE_STRIP); } float angle = startAt; float angleInRadians = glm::radians(angle); glm::vec2 firstPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); glVertex2f(firstPoint.x, firstPoint.y); while (angle < endAt) { angle += SLICE_ANGLE; angleInRadians = glm::radians(angle); glm::vec2 thisPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); glVertex2f(thisPoint.x, thisPoint.y); if (getIsDashedLine()) { angle += SLICE_ANGLE / 2.0f; // short gap angleInRadians = glm::radians(angle); glm::vec2 dashStartPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); glVertex2f(dashStartPoint.x, dashStartPoint.y); } } // get the last slice portion.... angle = endAt; angleInRadians = glm::radians(angle); glm::vec2 lastOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); glVertex2f(lastOuterPoint.x, lastOuterPoint.y); glEnd(); } // 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()) { glBegin(GL_LINES); // draw our major tick marks if (getMajorTickMarksAngle() > 0.0f && getMajorTickMarksLength() != 0.0f) { xColor color = getMajorTickMarksColor(); glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); float tickMarkAngle = getMajorTickMarksAngle(); float angle = startAt - fmod(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(cos(angleInRadians) * startRadius, sin(angleInRadians) * startRadius); glm::vec2 thisPointB(cos(angleInRadians) * endRadius, sin(angleInRadians) * endRadius); glVertex2f(thisPointA.x, thisPointA.y); glVertex2f(thisPointB.x, thisPointB.y); angle += tickMarkAngle; } } // draw our minor tick marks if (getMinorTickMarksAngle() > 0.0f && getMinorTickMarksLength() != 0.0f) { xColor color = getMinorTickMarksColor(); glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); float tickMarkAngle = getMinorTickMarksAngle(); float angle = startAt - fmod(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(cos(angleInRadians) * startRadius, sin(angleInRadians) * startRadius); glm::vec2 thisPointB(cos(angleInRadians) * endRadius, sin(angleInRadians) * endRadius); glVertex2f(thisPointA.x, thisPointA.y); glVertex2f(thisPointB.x, thisPointB.y); angle += tickMarkAngle; } } glEnd(); } glPopMatrix(); glPopMatrix(); if (glower) { delete glower; } }
void Circle3DOverlay::render(RenderArgs* args) { if (!_visible) { return; // do nothing if we're not visible } float alpha = getAlpha(); if (alpha == 0.0) { 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 color = getColor(); const float MAX_COLOR = 255.0f; glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); glDisable(GL_LIGHTING); glm::vec3 position = getPosition(); glm::vec3 center = getCenter(); glm::vec2 dimensions = getDimensions(); glm::quat rotation = getRotation(); float glowLevel = getGlowLevel(); Glower* glower = NULL; if (glowLevel > 0.0f) { glower = new Glower(glowLevel); } glPushMatrix(); glTranslatef(position.x, position.y, position.z); glm::vec3 axis = glm::axis(rotation); glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); glPushMatrix(); glm::vec3 positionToCenter = center - position; glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z); glScalef(dimensions.x, dimensions.y, 1.0f); glLineWidth(_lineWidth); auto geometryCache = DependencyManager::get<GeometryCache>(); // 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) { QVector<glm::vec2> points; float angle = startAt; float angleInRadians = glm::radians(angle); glm::vec2 firstInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius); glm::vec2 firstOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); points << firstInnerPoint << firstOuterPoint; while (angle < endAt) { angleInRadians = glm::radians(angle); glm::vec2 thisInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius); glm::vec2 thisOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); points << thisOuterPoint << thisInnerPoint; angle += SLICE_ANGLE; } // get the last slice portion.... angle = endAt; angleInRadians = glm::radians(angle); glm::vec2 lastInnerPoint(cos(angleInRadians) * innerRadius, sin(angleInRadians) * innerRadius); glm::vec2 lastOuterPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); points << lastOuterPoint << lastInnerPoint; geometryCache->updateVertices(_quadVerticesID, points); } geometryCache->renderVertices(GL_QUAD_STRIP, _quadVerticesID); } else { if (_lineVerticesID == GeometryCache::UNKNOWN_ID) { _lineVerticesID = geometryCache->allocateID(); } if (geometryChanged) { QVector<glm::vec2> points; float angle = startAt; float angleInRadians = glm::radians(angle); glm::vec2 firstPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); points << firstPoint; while (angle < endAt) { angle += SLICE_ANGLE; angleInRadians = glm::radians(angle); glm::vec2 thisPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); points << thisPoint; if (getIsDashedLine()) { angle += SLICE_ANGLE / 2.0f; // short gap angleInRadians = glm::radians(angle); glm::vec2 dashStartPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); points << dashStartPoint; } } // get the last slice portion.... angle = endAt; angleInRadians = glm::radians(angle); glm::vec2 lastPoint(cos(angleInRadians) * outerRadius, sin(angleInRadians) * outerRadius); points << lastPoint; geometryCache->updateVertices(_lineVerticesID, points); } if (getIsDashedLine()) { geometryCache->renderVertices(GL_LINES, _lineVerticesID); } else { geometryCache->renderVertices(GL_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 - fmod(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(cos(angleInRadians) * startRadius, sin(angleInRadians) * startRadius); glm::vec2 thisPointB(cos(angleInRadians) * endRadius, sin(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 - fmod(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(cos(angleInRadians) * startRadius, sin(angleInRadians) * startRadius); glm::vec2 thisPointB(cos(angleInRadians) * endRadius, sin(angleInRadians) * endRadius); minorPoints << thisPointA << thisPointB; angle += tickMarkAngle; } } geometryCache->updateVertices(_majorTicksVerticesID, majorPoints); geometryCache->updateVertices(_minorTicksVerticesID, minorPoints); } xColor majorColor = getMajorTickMarksColor(); glColor4f(majorColor.red / MAX_COLOR, majorColor.green / MAX_COLOR, majorColor.blue / MAX_COLOR, alpha); geometryCache->renderVertices(GL_LINES, _majorTicksVerticesID); xColor minorColor = getMinorTickMarksColor(); glColor4f(minorColor.red / MAX_COLOR, minorColor.green / MAX_COLOR, minorColor.blue / MAX_COLOR, alpha); geometryCache->renderVertices(GL_LINES, _minorTicksVerticesID); } glPopMatrix(); glPopMatrix(); if (geometryChanged) { _lastStartAt = startAt; _lastEndAt = endAt; _lastInnerRadius = innerRadius; _lastOuterRadius = outerRadius; } if (glower) { delete glower; } }