added 3D cube overlay support

This commit is contained in:
ZappoMan 2014-02-16 11:36:06 -08:00
parent cb1c659e2e
commit 5abf908874
14 changed files with 389 additions and 54 deletions

View file

@ -39,7 +39,7 @@ for (s = 0; s < numberOfSwatches; s++) {
height: 54,
subImage: { x: imageFromX, y: imageFromY, width: 30, height: 54 },
imageURL: "http://highfidelity-public.s3-us-west-1.amazonaws.com/images/testing-swatches.svg",
backgroundColor: swatchColors[s],
color: swatchColors[s],
alpha: 1
});
}
@ -49,11 +49,10 @@ var text = Overlays.addOverlay("text", {
y: 100,
width: 150,
height: 50,
backgroundColor: { red: 0, green: 0, blue: 0},
color: { red: 0, green: 0, blue: 0},
textColor: { red: 255, green: 0, blue: 0},
topMargin: 4,
leftMargin: 4,
alpha: 0.7,
text: "Here is some text.\nAnd a second line."
});
@ -64,8 +63,7 @@ var toolA = Overlays.addOverlay("image", {
height: 40,
subImage: { x: 0, y: 0, width: 62, height: 40 },
imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/hifi-interface-tools.svg",
backgroundColor: { red: 255, green: 255, blue: 255},
alpha: 0.7,
color: { red: 255, green: 255, blue: 255},
visible: false
});
@ -73,7 +71,7 @@ var slider = Overlays.addOverlay("image", {
// alternate form of expressing bounds
bounds: { x: 100, y: 300, width: 158, height: 35},
imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/slider.png",
backgroundColor: { red: 255, green: 255, blue: 255},
color: { red: 255, green: 255, blue: 255},
alpha: 1
});
@ -86,22 +84,39 @@ var thumb = Overlays.addOverlay("image", {
width: 18,
height: 17,
imageURL: "https://s3-us-west-1.amazonaws.com/highfidelity-public/images/thumb.png",
backgroundColor: { red: 255, green: 255, blue: 255},
color: { red: 255, green: 255, blue: 255},
alpha: 1
});
// 270x 109
// 109... 109/2 = 54,1,54
// 270... 39 to 66 = 28 x 9 swatches with
// unselected:
// 38,0,28,54
// selected:
// 38,55,28,54
//http://highfidelity-public.s3-us-west-1.amazonaws.com/images/swatches.svg
// 123456789*123456789*123456789*
// 0123456789*123456789*123456789*
// our 3D cube that moves around...
var cubePosition = { x: 2, y: 0, z: 2 };
var cubeSize = 5;
var cubeMove = 0.1;
var minCubeX = 1;
var maxCubeX = 20;
var solidCubePosition = { x: 0, y: 5, z: 0 };
var solidCubeSize = 2;
var minSolidCubeX = 0;
var maxSolidCubeX = 10;
var solidCubeMove = 0.05;
var cube = Overlays.addOverlay("cube", {
position: cubePosition,
size: cubeSize,
color: { red: 255, green: 0, blue: 0},
alpha: 1,
solid: false
});
var solidCube = Overlays.addOverlay("cube", {
position: solidCubePosition,
size: solidCubeSize,
color: { red: 0, green: 255, blue: 0},
alpha: 1,
solid: true
});
function scriptEnding() {
Overlays.deleteOverlay(toolA);
@ -127,6 +142,21 @@ function update() {
}
Overlays.editOverlay(toolA, { visible: toolAVisible } );
}
// move our 3D cube
cubePosition.x += cubeMove;
cubePosition.z += cubeMove;
if (cubePosition.x > maxCubeX || cubePosition.x < minCubeX) {
cubeMove = cubeMove * -1;
}
Overlays.editOverlay(cube, { position: cubePosition } );
solidCubePosition.x += solidCubeMove;
solidCubePosition.z += solidCubeMove;
if (solidCubePosition.x > maxSolidCubeX || solidCubePosition.x < minSolidCubeX) {
solidCubeMove = solidCubeMove * -1;
}
Overlays.editOverlay(solidCube, { position: solidCubePosition } );
}
Script.willSendVisualDataCallback.connect(update);

View file

@ -2842,6 +2842,9 @@ void Application::displaySide(Camera& whichCamera, bool selfAvatarOnly) {
// give external parties a change to hook in
emit renderingInWorldInterface();
// render JS/scriptable overlays
_overlays.render3D();
}
}
@ -2988,7 +2991,7 @@ void Application::displayOverlay() {
_pieMenu.render();
}
_overlays.render();
_overlays.render2D();
glPopMatrix();
}

View file

@ -0,0 +1,98 @@
//
// Cube3DOverlay.cpp
// interface
//
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
//
// include this before QGLWidget, which includes an earlier version of OpenGL
#include "InterfaceConfig.h"
#include <QGLWidget>
#include <SharedUtil.h>
#include "Cube3DOverlay.h"
#include "TextRenderer.h"
const glm::vec3 DEFAULT_POSITION = glm::vec3(0.0f, 0.0f, 0.0f);
const float DEFAULT_SIZE = 1.0f;
const float DEFAULT_LINE_WIDTH = 1.0f;
const bool DEFAULT_isSolid = false;
Cube3DOverlay::Cube3DOverlay() :
_position(DEFAULT_POSITION),
_size(DEFAULT_SIZE),
_lineWidth(DEFAULT_LINE_WIDTH),
_isSolid(DEFAULT_isSolid)
{
}
Cube3DOverlay::~Cube3DOverlay() {
}
void Cube3DOverlay::render() {
if (!_visible) {
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 {
glutWireCube(_size);
}
glPopMatrix();
}
void Cube3DOverlay::setProperties(const QScriptValue& properties) {
Overlay::setProperties(properties);
QScriptValue position = properties.property("position");
if (position.isValid()) {
QScriptValue x = position.property("x");
QScriptValue y = position.property("y");
QScriptValue z = position.property("z");
if (x.isValid() && y.isValid() && z.isValid()) {
glm::vec3 newPosition;
newPosition.x = x.toVariant().toFloat();
newPosition.y = y.toVariant().toFloat();
newPosition.z = z.toVariant().toFloat();
setPosition(newPosition);
}
}
if (properties.property("size").isValid()) {
setSize(properties.property("size").toVariant().toFloat());
}
if (properties.property("lineWidth").isValid()) {
setLineWidth(properties.property("lineWidth").toVariant().toFloat());
}
if (properties.property("isSolid").isValid()) {
setIsSolid(properties.property("isSolid").toVariant().toBool());
}
if (properties.property("isWire").isValid()) {
setIsSolid(!properties.property("isWire").toVariant().toBool());
}
if (properties.property("solid").isValid()) {
setIsSolid(properties.property("solid").toVariant().toBool());
}
if (properties.property("wire").isValid()) {
setIsSolid(!properties.property("wire").toVariant().toBool());
}
}

View file

@ -0,0 +1,57 @@
//
// Cube3DOverlay.h
// interface
//
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
//
#ifndef __interface__Cube3DOverlay__
#define __interface__Cube3DOverlay__
// include this before QGLWidget, which includes an earlier version of OpenGL
#include "InterfaceConfig.h"
#include <QGLWidget>
#include <QImage>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QRect>
#include <QScriptValue>
#include <QString>
#include <QUrl>
#include <SharedUtil.h>
#include "Overlay.h"
class Cube3DOverlay : public Overlay {
Q_OBJECT
public:
Cube3DOverlay();
~Cube3DOverlay();
virtual void render();
// getters
const glm::vec3& getPosition() const { return _position; }
float getSize() const { return _size; }
float getLineWidth() const { return _lineWidth; }
bool getIsSolid() const { return _isSolid; }
// setters
void setPosition(const glm::vec3& position) { _position = position; }
void setSize(float size) { _size = size; }
void setLineWidth(float lineWidth) { _lineWidth = lineWidth; }
void setIsSolid(bool isSolid) { _isSolid = isSolid; }
virtual void setProperties(const QScriptValue& properties);
private:
glm::vec3 _position;
float _size;
float _lineWidth;
bool _isSolid;
};
#endif /* defined(__interface__Cube3DOverlay__) */

View file

@ -61,7 +61,7 @@ void ImageOverlay::render() {
glBindTexture(GL_TEXTURE_2D, _textureID);
}
const float MAX_COLOR = 255;
glColor4f(_backgroundColor.red / MAX_COLOR, _backgroundColor.green / MAX_COLOR, _backgroundColor.blue / MAX_COLOR, _alpha);
glColor4f(_color.red / MAX_COLOR, _color.green / MAX_COLOR, _color.blue / MAX_COLOR, _alpha);
float imageWidth = _textureImage.width();
float imageHeight = _textureImage.height();
@ -107,7 +107,7 @@ void ImageOverlay::render() {
}
void ImageOverlay::setProperties(const QScriptValue& properties) {
Overlay::setProperties(properties);
Overlay2D::setProperties(properties);
QScriptValue subImageBounds = properties.property("subImage");
if (subImageBounds.isValid()) {

View file

@ -23,8 +23,9 @@
#include <SharedUtil.h>
#include "Overlay.h"
#include "Overlay2D.h"
class ImageOverlay : public Overlay {
class ImageOverlay : public Overlay2D {
Q_OBJECT
public:

View file

@ -19,7 +19,7 @@
Overlay::Overlay() :
_parent(NULL),
_alpha(DEFAULT_ALPHA),
_backgroundColor(DEFAULT_BACKGROUND_COLOR),
_color(DEFAULT_BACKGROUND_COLOR),
_visible(true)
{
}
@ -69,15 +69,15 @@ void Overlay::setProperties(const QScriptValue& properties) {
//qDebug() << "set bounds to " << getBounds();
}
QScriptValue color = properties.property("backgroundColor");
QScriptValue color = properties.property("color");
if (color.isValid()) {
QScriptValue red = color.property("red");
QScriptValue green = color.property("green");
QScriptValue blue = color.property("blue");
if (red.isValid() && green.isValid() && blue.isValid()) {
_backgroundColor.red = red.toVariant().toInt();
_backgroundColor.green = green.toVariant().toInt();
_backgroundColor.blue = blue.toVariant().toInt();
_color.red = red.toVariant().toInt();
_color.green = green.toVariant().toInt();
_color.blue = blue.toVariant().toInt();
}
}

View file

@ -37,7 +37,7 @@ public:
int getWidth() const { return _bounds.width(); }
int getHeight() const { return _bounds.height(); }
const QRect& getBounds() const { return _bounds; }
const xColor& getBackgroundColor() const { return _backgroundColor; }
const xColor& getColor() const { return _color; }
float getAlpha() const { return _alpha; }
// setters
@ -47,7 +47,7 @@ public:
void setWidth(int width) { _bounds.setWidth(width); }
void setHeight(int height) { _bounds.setHeight(height); }
void setBounds(const QRect& bounds) { _bounds = bounds; }
void setBackgroundColor(const xColor& color) { _backgroundColor = color; }
void setColor(const xColor& color) { _color = color; }
void setAlpha(float alpha) { _alpha = alpha; }
virtual void setProperties(const QScriptValue& properties);
@ -56,7 +56,7 @@ protected:
QGLWidget* _parent;
QRect _bounds; // where on the screen to draw
float _alpha;
xColor _backgroundColor;
xColor _color;
bool _visible; // should the overlay be drawn at all
};

View file

@ -0,0 +1,63 @@
//
// Overlay2D.cpp
// interface
//
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
//
// include this before QGLWidget, which includes an earlier version of OpenGL
#include "InterfaceConfig.h"
#include <QSvgRenderer>
#include <QPainter>
#include <QGLWidget>
#include <SharedUtil.h>
#include "Overlay2D.h"
Overlay2D::Overlay2D() {
}
Overlay2D::~Overlay2D() {
}
void Overlay2D::setProperties(const QScriptValue& properties) {
Overlay::setProperties(properties);
QScriptValue bounds = properties.property("bounds");
if (bounds.isValid()) {
QRect boundsRect;
boundsRect.setX(bounds.property("x").toVariant().toInt());
boundsRect.setY(bounds.property("y").toVariant().toInt());
boundsRect.setWidth(bounds.property("width").toVariant().toInt());
boundsRect.setHeight(bounds.property("height").toVariant().toInt());
setBounds(boundsRect);
} else {
QRect oldBounds = getBounds();
QRect newBounds = oldBounds;
if (properties.property("x").isValid()) {
newBounds.setX(properties.property("x").toVariant().toInt());
} else {
newBounds.setX(oldBounds.x());
}
if (properties.property("y").isValid()) {
newBounds.setY(properties.property("y").toVariant().toInt());
} else {
newBounds.setY(oldBounds.y());
}
if (properties.property("width").isValid()) {
newBounds.setWidth(properties.property("width").toVariant().toInt());
} else {
newBounds.setWidth(oldBounds.width());
}
if (properties.property("height").isValid()) {
newBounds.setHeight(properties.property("height").toVariant().toInt());
} else {
newBounds.setHeight(oldBounds.height());
}
setBounds(newBounds);
//qDebug() << "set bounds to " << getBounds();
}
}

View file

@ -0,0 +1,51 @@
//
// Overlay2D.h
// interface
//
// Copyright (c) 2014 High Fidelity, Inc. All rights reserved.
//
#ifndef __interface__Overlay2D__
#define __interface__Overlay2D__
// include this before QGLWidget, which includes an earlier version of OpenGL
#include "InterfaceConfig.h"
#include <QGLWidget>
#include <QRect>
#include <QScriptValue>
#include <QString>
#include <SharedUtil.h> // for xColor
#include "Overlay.h"
class Overlay2D : public Overlay {
Q_OBJECT
public:
Overlay2D();
~Overlay2D();
// getters
int getX() const { return _bounds.x(); }
int getY() const { return _bounds.y(); }
int getWidth() const { return _bounds.width(); }
int getHeight() const { return _bounds.height(); }
const QRect& getBounds() const { return _bounds; }
// setters
void setX(int x) { _bounds.setX(x); }
void setY(int y) { _bounds.setY(y); }
void setWidth(int width) { _bounds.setWidth(width); }
void setHeight(int height) { _bounds.setHeight(height); }
void setBounds(const QRect& bounds) { _bounds = bounds; }
virtual void setProperties(const QScriptValue& properties);
protected:
QRect _bounds; // where on the screen to draw
};
#endif /* defined(__interface__Overlay2D__) */

View file

@ -6,8 +6,9 @@
//
#include "Overlays.h"
#include "Cube3DOverlay.h"
#include "ImageOverlay.h"
#include "Overlays.h"
#include "TextOverlay.h"
@ -23,8 +24,14 @@ void Overlays::init(QGLWidget* parent) {
_parent = parent;
}
void Overlays::render() {
foreach(Overlay* thisOverlay, _overlays) {
void Overlays::render2D() {
foreach(Overlay* thisOverlay, _overlays2D) {
thisOverlay->render();
}
}
void Overlays::render3D() {
foreach(Overlay* thisOverlay, _overlays3D) {
thisOverlay->render();
}
}
@ -32,21 +39,36 @@ void Overlays::render() {
// TODO: make multi-threaded safe
unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& properties) {
unsigned int thisID = 0;
bool created = false;
bool is3D = false;
Overlay* thisOverlay = NULL;
if (type == "image") {
thisID = _nextOverlayID;
_nextOverlayID++;
ImageOverlay* thisOverlay = new ImageOverlay();
thisOverlay = new ImageOverlay();
thisOverlay->init(_parent);
thisOverlay->setProperties(properties);
_overlays[thisID] = thisOverlay;
created = true;
} else if (type == "text") {
thisID = _nextOverlayID;
_nextOverlayID++;
TextOverlay* thisOverlay = new TextOverlay();
thisOverlay = new TextOverlay();
thisOverlay->init(_parent);
thisOverlay->setProperties(properties);
_overlays[thisID] = thisOverlay;
created = true;
} else if (type == "cube") {
thisOverlay = new Cube3DOverlay();
thisOverlay->init(_parent);
thisOverlay->setProperties(properties);
created = true;
is3D = true;
}
if (created) {
thisID = _nextOverlayID;
_nextOverlayID++;
if (is3D) {
_overlays3D[thisID] = thisOverlay;
} else {
_overlays2D[thisID] = thisOverlay;
}
}
return thisID;
@ -54,23 +76,30 @@ unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& prope
// TODO: make multi-threaded safe
bool Overlays::editOverlay(unsigned int id, const QScriptValue& properties) {
if (!_overlays.contains(id)) {
return false;
Overlay* thisOverlay = NULL;
if (_overlays2D.contains(id)) {
thisOverlay = _overlays2D[id];
} else if (_overlays3D.contains(id)) {
thisOverlay = _overlays3D[id];
}
Overlay* thisOverlay = _overlays[id];
thisOverlay->setProperties(properties);
return true;
if (thisOverlay) {
thisOverlay->setProperties(properties);
return true;
}
return false;
}
// TODO: make multi-threaded safe
void Overlays::deleteOverlay(unsigned int id) {
if (_overlays.contains(id)) {
_overlays.erase(_overlays.find(id));
if (_overlays2D.contains(id)) {
_overlays2D.erase(_overlays2D.find(id));
} else if (_overlays3D.contains(id)) {
_overlays3D.erase(_overlays3D.find(id));
}
}
unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) {
QMapIterator<unsigned int, Overlay*> i(_overlays);
QMapIterator<unsigned int, Overlay*> i(_overlays2D);
i.toBack();
while (i.hasPrevious()) {
i.previous();

View file

@ -18,7 +18,8 @@ public:
Overlays();
~Overlays();
void init(QGLWidget* parent);
void render();
void render3D();
void render2D();
public slots:
/// adds an overlay with the specific properties
@ -35,7 +36,8 @@ public slots:
unsigned int getOverlayAtPoint(const glm::vec2& point);
private:
QMap<unsigned int, Overlay*> _overlays;
QMap<unsigned int, Overlay*> _overlays2D;
QMap<unsigned int, Overlay*> _overlays3D;
static unsigned int _nextOverlayID;
QGLWidget* _parent;
};

View file

@ -29,7 +29,7 @@ void TextOverlay::render() {
}
const float MAX_COLOR = 255;
glColor4f(_backgroundColor.red / MAX_COLOR, _backgroundColor.green / MAX_COLOR, _backgroundColor.blue / MAX_COLOR, _alpha);
glColor4f(_color.red / MAX_COLOR, _color.green / MAX_COLOR, _color.blue / MAX_COLOR, _alpha);
glBegin(GL_QUADS);
glVertex2f(_bounds.left(), _bounds.top());
@ -63,7 +63,7 @@ void TextOverlay::render() {
}
void TextOverlay::setProperties(const QScriptValue& properties) {
Overlay::setProperties(properties);
Overlay2D::setProperties(properties);
QScriptValue text = properties.property("text");
if (text.isValid()) {

View file

@ -23,10 +23,11 @@
#include <SharedUtil.h>
#include "Overlay.h"
#include "Overlay2D.h"
const int DEFAULT_MARGIN = 10;
class TextOverlay : public Overlay {
class TextOverlay : public Overlay2D {
Q_OBJECT
public: