add glowLevel, and pulse to all overlays

This commit is contained in:
ZappoMan 2014-09-29 16:44:40 -07:00
parent a701bcea7b
commit bffd236640
13 changed files with 404 additions and 78 deletions

View file

@ -13,8 +13,11 @@
#include <QGLWidget>
#include <SharedUtil.h>
#include <StreamUtils.h>
#include "Application.h"
#include "Cube3DOverlay.h"
#include "renderer/GlowEffect.h"
Cube3DOverlay::Cube3DOverlay() {
}
@ -27,22 +30,44 @@ void Cube3DOverlay::render() {
return; // do nothing if we're not visible
}
const float MAX_COLOR = 255;
glColor4f(_color.red / MAX_COLOR, _color.green / MAX_COLOR, _color.blue / MAX_COLOR, _alpha);
glDisable(GL_LIGHTING);
glPushMatrix();
glTranslatef(_position.x + _size * 0.5f,
_position.y + _size * 0.5f,
_position.z + _size * 0.5f);
glLineWidth(_lineWidth);
if (_isSolid) {
glutSolidCube(_size);
} else {
glLineWidth(_lineWidth);
glutWireCube(_size);
float glowLevel = getGlowLevel();
Glower* glower = NULL;
if (glowLevel > 0.0f) {
glower = new Glower(glowLevel);
}
float alpha = getAlpha();
xColor color = getColor();
const float MAX_COLOR = 255;
glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
//glDisable(GL_LIGHTING);
// TODO: handle registration point??
glm::vec3 position = getPosition();
glm::vec3 center = getCenter();
glm::vec3 dimensions = getDimensions();
glm::quat rotation = getRotation();
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, dimensions.z);
if (_isSolid) {
Application::getInstance()->getDeferredLightingEffect()->renderSolidCube(1.0f);
} else {
glLineWidth(_lineWidth);
Application::getInstance()->getDeferredLightingEffect()->renderWireCube(1.0f);
}
glPopMatrix();
glPopMatrix();
if (glower) {
delete glower;
}
}

View file

@ -66,7 +66,9 @@ void ImageOverlay::render() {
glBindTexture(GL_TEXTURE_2D, _textureID);
}
const float MAX_COLOR = 255;
glColor4f(_color.red / MAX_COLOR, _color.green / MAX_COLOR, _color.blue / MAX_COLOR, _alpha);
xColor color = getColor();
float alpha = getAlpha();
glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
float imageWidth = _textureImage.width();
float imageHeight = _textureImage.height();
@ -106,6 +108,7 @@ void ImageOverlay::render() {
}
glVertex2f(_bounds.left(), _bounds.bottom());
glEnd();
if (_renderImage) {
glDisable(GL_TEXTURE_2D);
}

View file

@ -12,6 +12,7 @@
#include "InterfaceConfig.h"
#include "Line3DOverlay.h"
#include "renderer/GlowEffect.h"
Line3DOverlay::Line3DOverlay() {
@ -25,16 +26,29 @@ void Line3DOverlay::render() {
return; // do nothing if we're not visible
}
const float MAX_COLOR = 255;
float glowLevel = getGlowLevel();
Glower* glower = NULL;
if (glowLevel > 0.0f) {
glower = new Glower(glowLevel);
}
glDisable(GL_LIGHTING);
glLineWidth(_lineWidth);
glColor4f(_color.red / MAX_COLOR, _color.green / MAX_COLOR, _color.blue / MAX_COLOR, _alpha);
float alpha = getAlpha();
xColor color = getColor();
const float MAX_COLOR = 255;
glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
glBegin(GL_LINES);
glVertex3f(_position.x, _position.y, _position.z);
glVertex3f(_end.x, _end.y, _end.z);
glEnd();
glEnable(GL_LIGHTING);
if (glower) {
delete glower;
}
}
void Line3DOverlay::setProperties(const QScriptValue& properties) {

View file

@ -27,6 +27,13 @@ void LocalModelsOverlay::update(float deltatime) {
void LocalModelsOverlay::render() {
if (_visible) {
float glowLevel = getGlowLevel();
Glower* glower = NULL;
if (glowLevel > 0.0f) {
glower = new Glower(glowLevel);
}
glPushMatrix(); {
Application* app = Application::getInstance();
glm::vec3 oldTranslation = app->getViewMatrixTranslation();
@ -34,5 +41,10 @@ void LocalModelsOverlay::render() {
_entityTreeRenderer->render();
Application::getInstance()->setViewMatrixTranslation(oldTranslation);
} glPopMatrix();
if (glower) {
delete glower;
}
}
}

View file

@ -52,12 +52,25 @@ void LocalVoxelsOverlay::update(float deltatime) {
}
void LocalVoxelsOverlay::render() {
if (_visible && _size > 0 && _voxelSystem && _voxelSystem->isInitialized()) {
glm::vec3 dimensions = getDimensions();
float size = glm::length(dimensions);
if (_visible && size > 0 && _voxelSystem && _voxelSystem->isInitialized()) {
float glowLevel = getGlowLevel();
Glower* glower = NULL;
if (glowLevel > 0.0f) {
glower = new Glower(glowLevel);
}
glPushMatrix(); {
glTranslatef(_position.x, _position.y, _position.z);
glScalef(_size, _size, _size);
glScalef(dimensions.x, dimensions.y, dimensions.z);
_voxelSystem->render();
} glPopMatrix();
if (glower) {
delete glower;
}
}
}

View file

@ -43,45 +43,16 @@ void ModelOverlay::render() {
}
if (_model.isActive()) {
if (_model.isRenderable()) {
_model.render(_alpha);
}
bool displayModelBounds = Menu::getInstance()->isOptionChecked(MenuOption::DisplayModelBounds);
if (displayModelBounds) {
glm::vec3 unRotatedMinimum = _model.getUnscaledMeshExtents().minimum;
glm::vec3 unRotatedMaximum = _model.getUnscaledMeshExtents().maximum;
glm::vec3 unRotatedExtents = unRotatedMaximum - unRotatedMinimum;
float width = unRotatedExtents.x;
float height = unRotatedExtents.y;
float depth = unRotatedExtents.z;
Extents rotatedExtents = _model.getUnscaledMeshExtents();
rotatedExtents.rotate(_rotation);
glm::vec3 rotatedSize = rotatedExtents.maximum - rotatedExtents.minimum;
const glm::vec3& modelScale = _model.getScale();
glPushMatrix(); {
glTranslatef(_position.x, _position.y, _position.z);
// draw the rotated bounding cube
glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
glPushMatrix(); {
glScalef(rotatedSize.x * modelScale.x, rotatedSize.y * modelScale.y, rotatedSize.z * modelScale.z);
glutWireCube(1.0);
} glPopMatrix();
// draw the model relative bounding box
glm::vec3 axis = glm::axis(_rotation);
glRotatef(glm::degrees(glm::angle(_rotation)), axis.x, axis.y, axis.z);
glScalef(width * modelScale.x, height * modelScale.y, depth * modelScale.z);
glColor3f(0.0f, 1.0f, 0.0f);
glutWireCube(1.0);
} glPopMatrix();
float glowLevel = getGlowLevel();
Glower* glower = NULL;
if (glowLevel > 0.0f) {
glower = new Glower(glowLevel);
}
_model.render(getAlpha());
if (glower) {
delete glower;
}
}
}
}

View file

@ -23,6 +23,16 @@ Overlay::Overlay() :
_parent(NULL),
_isLoaded(true),
_alpha(DEFAULT_ALPHA),
_glowLevel(0.0f),
_pulse(0.0f),
_pulseMax(0.0f),
_pulseMin(0.0f),
_pulsePeriod(1.0f),
_pulseDirection(1.0f),
_lastPulseUpdate(usecTimestampNow()),
_glowLevelPulse(0.0f),
_alphaPulse(0.0f),
_colorPulse(0.0f),
_color(DEFAULT_OVERLAY_COLOR),
_visible(true),
_anchor(NO_ANCHOR)
@ -54,6 +64,34 @@ void Overlay::setProperties(const QScriptValue& properties) {
setAlpha(properties.property("alpha").toVariant().toFloat());
}
if (properties.property("glowLevel").isValid()) {
setGlowLevel(properties.property("glowLevel").toVariant().toFloat());
}
if (properties.property("pulseMax").isValid()) {
setPulseMax(properties.property("pulseMax").toVariant().toFloat());
}
if (properties.property("pulseMin").isValid()) {
setPulseMin(properties.property("pulseMin").toVariant().toFloat());
}
if (properties.property("pulsePeriod").isValid()) {
setPulsePeriod(properties.property("pulsePeriod").toVariant().toFloat());
}
if (properties.property("glowLevelPulse").isValid()) {
setGlowLevelPulse(properties.property("glowLevelPulse").toVariant().toFloat());
}
if (properties.property("alphaPulse").isValid()) {
setAlphaPulse(properties.property("alphaPulse").toVariant().toFloat());
}
if (properties.property("colorPulse").isValid()) {
setColorPulse(properties.property("colorPulse").toVariant().toFloat());
}
if (properties.property("visible").isValid()) {
setVisible(properties.property("visible").toVariant().toBool());
}
@ -65,3 +103,89 @@ void Overlay::setProperties(const QScriptValue& properties) {
}
}
}
xColor Overlay::getColor() {
if (_colorPulse == 0.0f) {
return _color;
}
float pulseLevel = updatePulse();
xColor result = _color;
if (_colorPulse < 0.0f) {
result.red *= (1.0f - pulseLevel);
result.green *= (1.0f - pulseLevel);
result.blue *= (1.0f - pulseLevel);
} else {
result.red *= pulseLevel;
result.green *= pulseLevel;
result.blue *= pulseLevel;
}
return result;
}
float Overlay::getAlpha() {
if (_alphaPulse == 0.0f) {
return _alpha;
}
float pulseLevel = updatePulse();
return (_alphaPulse >= 0.0f) ? _alpha * pulseLevel : _alpha * (1.0f - pulseLevel);
}
float Overlay::getGlowLevel() {
if (_glowLevelPulse == 0.0f) {
return _glowLevel;
}
float pulseLevel = updatePulse();
return (_glowLevelPulse >= 0.0f) ? _glowLevel * pulseLevel : _glowLevel * (1.0f - pulseLevel);
}
// glow level travels from min to max, then max to min in one period.
float Overlay::updatePulse() {
if (_pulsePeriod <= 0.0f) {
return _pulse;
}
quint64 now = usecTimestampNow();
quint64 elapsedUSecs = (now - _lastPulseUpdate);
float elapsedSeconds = (float)elapsedUSecs / (float)USECS_PER_SECOND;
float elapsedPeriods = elapsedSeconds / _pulsePeriod;
// we can safely remove any "full" periods, since those just rotate us back
// to our final glow level
while (elapsedPeriods > 1.0f) {
elapsedPeriods -= 1.0f;
}
_lastPulseUpdate = now;
float glowDistance = (_pulseMax - _pulseMin);
float glowDistancePerPeriod = glowDistance * 2.0f;
// if we're currently traveling from min to max
if (_pulseDirection > 0.0f) {
float glowDelta = glowDistancePerPeriod * elapsedPeriods;
// if by adding the glowDelta, we would pass our max, then calculate
// the distance from the max back to where we'd land...
if (_pulse + glowDelta >= _pulseMax) {
float glowDeltaToMax = (_pulse + glowDelta) - _pulseMax;
float glowDeltaFromMaxBack = glowDelta - glowDeltaToMax;
glowDelta = -glowDeltaFromMaxBack;
_pulseDirection = -1.0f;
}
_pulse += glowDelta;
} else {
float glowDelta = _pulseDirection * glowDistancePerPeriod * elapsedPeriods;
// if by subtracting the glowDelta, we would pass our min, then calculate
// the distance from the min back to where we'd land...
if (_pulse + glowDelta <= _pulseMin) {
float glowDeltaToMin = (_pulse + glowDelta) - _pulseMin;
float glowDeltaFromMinBack = glowDelta - glowDeltaToMin;
glowDelta = -glowDeltaFromMinBack;
_pulseDirection = 1.0f;
}
_pulse += glowDelta;
}
return _pulse;
}

View file

@ -42,22 +42,60 @@ public:
// getters
bool isLoaded() { return _isLoaded; }
bool getVisible() const { return _visible; }
const xColor& getColor() const { return _color; }
float getAlpha() const { return _alpha; }
xColor getColor();
float getAlpha();
float getGlowLevel();
Anchor getAnchor() const { return _anchor; }
float getPulseMax() const { return _pulseMax; }
float getPulseMin() const { return _pulseMin; }
float getPulsePeriod() const { return _pulsePeriod; }
float getPulseDirection() const { return _pulseDirection; }
float getGlowLevelPulse() const { return _glowLevelPulse; }
float getColorPulse() const { return _colorPulse; }
float getAlphaPulse() const { return _alphaPulse; }
// setters
void setVisible(bool visible) { _visible = visible; }
void setColor(const xColor& color) { _color = color; }
void setAlpha(float alpha) { _alpha = alpha; }
void setGlowLevel(float value) { _glowLevel = value; }
void setAnchor(Anchor anchor) { _anchor = anchor; }
void setPulseMax(float value) { _pulseMax = value; }
void setPulseMin(float value) { _pulseMin = value; }
void setPulsePeriod(float value) { _pulsePeriod = value; }
void setPulseDirection(float value) { _pulseDirection = value; }
void setGlowLevelPulse(float value) { _glowLevelPulse = value; }
void setColorPulse(float value) { _colorPulse = value; }
void setAlphaPulse(float value) { _alphaPulse = value; }
virtual void setProperties(const QScriptValue& properties);
protected:
float updatePulse();
QGLWidget* _parent;
bool _isLoaded;
float _alpha;
float _glowLevel;
float _pulse;
float _pulseMax;
float _pulseMin;
float _pulsePeriod;
float _pulseDirection;
quint64 _lastPulseUpdate;
float _glowLevelPulse; // ratio of the pulse to the glow level
float _alphaPulse; // ratio of the pulse to the alpha
float _colorPulse; // ratio of the pulse to the color
xColor _color;
bool _visible; // should the overlay be drawn at all
Anchor _anchor;

View file

@ -15,6 +15,7 @@
#include <SharedUtil.h>
#include "Sphere3DOverlay.h"
#include "renderer/GlowEffect.h"
Sphere3DOverlay::Sphere3DOverlay() {
}
@ -27,22 +28,46 @@ void Sphere3DOverlay::render() {
return; // do nothing if we're not visible
}
const int slices = 15;
float alpha = getAlpha();
xColor color = getColor();
const float MAX_COLOR = 255;
glColor4f(_color.red / MAX_COLOR, _color.green / MAX_COLOR, _color.blue / MAX_COLOR, _alpha);
glColor4f(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha);
glDisable(GL_LIGHTING);
glPushMatrix();
glTranslatef(_position.x,
_position.y,
_position.z);
glLineWidth(_lineWidth);
const int slices = 15;
if (_isSolid) {
glutSolidSphere(_size, slices, slices);
} else {
glutWireSphere(_size, slices, slices);
glm::vec3 position = getPosition();
glm::vec3 center = getCenter();
glm::vec3 dimensions = getDimensions();
//glm::vec3 halfDimensions = dimensions / 2.0f;
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, dimensions.z);
//Application::getInstance()->getDeferredLightingEffect()->renderSolidCube(1.0f);
if (_isSolid) {
glutSolidSphere(1.0f, slices, slices);
} else {
glutWireSphere(1.0f, slices, slices);
}
glPopMatrix();
glPopMatrix();
if (glower) {
delete glower;
}
}

View file

@ -28,13 +28,36 @@ TextOverlay::TextOverlay() :
TextOverlay::~TextOverlay() {
}
xColor TextOverlay::getBackgroundColor() {
if (_colorPulse == 0.0f) {
return _backgroundColor;
}
float pulseLevel = updatePulse();
xColor result = _backgroundColor;
if (_colorPulse < 0.0f) {
result.red *= (1.0f - pulseLevel);
result.green *= (1.0f - pulseLevel);
result.blue *= (1.0f - pulseLevel);
} else {
result.red *= pulseLevel;
result.green *= pulseLevel;
result.blue *= pulseLevel;
}
return result;
}
void TextOverlay::render() {
if (!_visible) {
return; // do nothing if we're not visible
}
const float MAX_COLOR = 255;
glColor4f(_backgroundColor.red / MAX_COLOR, _backgroundColor.green / MAX_COLOR, _backgroundColor.blue / MAX_COLOR, _alpha);
xColor backgroundColor = getBackgroundColor();
float alpha = getAlpha();
glColor4f(backgroundColor.red / MAX_COLOR, backgroundColor.green / MAX_COLOR, backgroundColor.blue / MAX_COLOR, alpha);
glBegin(GL_QUADS);
glVertex2f(_bounds.left(), _bounds.top());
@ -64,7 +87,6 @@ void TextOverlay::render() {
const int lineGap = 2;
lineOffset += lineGap;
}
}
void TextOverlay::setProperties(const QScriptValue& properties) {

View file

@ -43,6 +43,7 @@ public:
const QString& getText() const { return _text; }
int getLeftMargin() const { return _leftMargin; }
int getTopMargin() const { return _topMargin; }
xColor getBackgroundColor();
// setters
void setText(const QString& text) { _text = text; }

View file

@ -13,6 +13,7 @@
#include <QGLWidget>
#include <SharedUtil.h>
#include <StreamUtils.h>
#include "Volume3DOverlay.h"
@ -20,7 +21,7 @@ const float DEFAULT_SIZE = 1.0f;
const bool DEFAULT_IS_SOLID = false;
Volume3DOverlay::Volume3DOverlay() :
_size(DEFAULT_SIZE),
_dimensions(glm::vec3(DEFAULT_SIZE, DEFAULT_SIZE, DEFAULT_SIZE)),
_isSolid(DEFAULT_IS_SOLID)
{
}
@ -31,8 +32,75 @@ Volume3DOverlay::~Volume3DOverlay() {
void Volume3DOverlay::setProperties(const QScriptValue& properties) {
Base3DOverlay::setProperties(properties);
if (properties.property("size").isValid()) {
setSize(properties.property("size").toVariant().toFloat());
QScriptValue dimensions = properties.property("dimensions");
// if "dimensions" property was not there, check to see if they included aliases: scale
if (!dimensions.isValid()) {
dimensions = properties.property("scale");
if (!dimensions.isValid()) {
dimensions = properties.property("size");
}
}
if (dimensions.isValid()) {
bool validDimensions = false;
glm::vec3 newDimensions;
QScriptValue x = dimensions.property("x");
QScriptValue y = dimensions.property("y");
QScriptValue z = dimensions.property("z");
if (x.isValid() && y.isValid() && z.isValid()) {
newDimensions.x = x.toVariant().toFloat();
newDimensions.y = y.toVariant().toFloat();
newDimensions.z = z.toVariant().toFloat();
validDimensions = true;
} else {
QScriptValue width = dimensions.property("width");
QScriptValue height = dimensions.property("height");
QScriptValue depth = dimensions.property("depth");
if (width.isValid() && height.isValid() && depth.isValid()) {
newDimensions.x = width.toVariant().toFloat();
newDimensions.y = height.toVariant().toFloat();
newDimensions.z = depth.toVariant().toFloat();
validDimensions = true;
}
}
// size, scale, dimensions is special, it might just be a single scalar, check that here
if (!validDimensions && dimensions.isNumber()) {
float size = dimensions.toVariant().toFloat();
newDimensions.x = size;
newDimensions.y = size;
newDimensions.z = size;
validDimensions = true;
}
if (validDimensions) {
setDimensions(newDimensions);
}
}
QScriptValue rotation = properties.property("rotation");
if (rotation.isValid()) {
glm::quat newRotation;
// size, scale, dimensions is special, it might just be a single scalar, or it might be a vector, check that here
QScriptValue x = rotation.property("x");
QScriptValue y = rotation.property("y");
QScriptValue z = rotation.property("z");
QScriptValue w = rotation.property("w");
if (x.isValid() && y.isValid() && z.isValid() && w.isValid()) {
newRotation.x = x.toVariant().toFloat();
newRotation.y = y.toVariant().toFloat();
newRotation.z = z.toVariant().toFloat();
newRotation.w = w.toVariant().toFloat();
setRotation(newRotation);
}
}
if (properties.property("isSolid").isValid()) {

View file

@ -14,6 +14,10 @@
// include this before QGLWidget, which includes an earlier version of OpenGL
#include "InterfaceConfig.h"
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/gtx/extented_min_max.hpp>
#include <QGLWidget>
#include <QScriptValue>
@ -27,17 +31,23 @@ public:
~Volume3DOverlay();
// getters
float getSize() const { return _size; }
bool getIsSolid() const { return _isSolid; }
const glm::vec3& getPosition() const { return _position; }
const glm::vec3& getCenter() const { return _position; } // TODO: registration point!!
const glm::vec3& getDimensions() const { return _dimensions; }
const glm::quat& getRotation() const { return _rotation; }
// setters
void setSize(float size) { _size = size; }
void setSize(float size) { _dimensions = glm::vec3(size, size, size); }
void setIsSolid(bool isSolid) { _isSolid = isSolid; }
void setDimensions(const glm::vec3& value) { _dimensions = value; }
void setRotation(const glm::quat& value) { _rotation = value; }
virtual void setProperties(const QScriptValue& properties);
protected:
float _size;
glm::vec3 _dimensions;
glm::quat _rotation;
bool _isSolid;
};