Refactor billboarding into Billboardable class.
This commit is contained in:
parent
3dcfa84a87
commit
3356bf31ac
@ -41,14 +41,20 @@
|
||||
var overlays = {};
|
||||
var panels = {};
|
||||
|
||||
var overlayTypes,
|
||||
Overlay,
|
||||
var overlayTypes;
|
||||
|
||||
// Abstract overlay types
|
||||
var Overlay,
|
||||
Overlay2D,
|
||||
Base3DOverlay,
|
||||
Planar3DOverlay,
|
||||
Billboard3DOverlay,
|
||||
Volume3DOverlay;
|
||||
|
||||
// Multiple inheritance mixins
|
||||
var PanelAttachable,
|
||||
Billboardable;
|
||||
|
||||
|
||||
//
|
||||
// Create a new JavaScript object for an overlay of given ID.
|
||||
@ -232,10 +238,6 @@
|
||||
return that;
|
||||
}
|
||||
|
||||
// Supports multiple inheritance of properties. Just `concat` them onto the end of the
|
||||
// properties list.
|
||||
var PANEL_ATTACHABLE_FIELDS = ["offsetPosition", "offsetRotation", "offsetScale"];
|
||||
|
||||
Overlay = (function() {
|
||||
var that = function(type, params) {
|
||||
if (type && params) {
|
||||
@ -286,6 +288,11 @@
|
||||
]);
|
||||
})();
|
||||
|
||||
// Supports multiple inheritance of properties. Just `concat` them onto the end of the
|
||||
// properties list.
|
||||
PanelAttachable = ["offsetPosition", "offsetRotation", "offsetScale"];
|
||||
Billboardable = ["isFacingAvatar"];
|
||||
|
||||
Overlay2D = generateOverlayClass(Overlay, ABSTRACT, [
|
||||
"bounds", "x", "y", "width", "height"
|
||||
]);
|
||||
@ -300,8 +307,7 @@
|
||||
]);
|
||||
|
||||
Billboard3DOverlay = generateOverlayClass(Planar3DOverlay, ABSTRACT, [
|
||||
"isFacingAvatar"
|
||||
].concat(PANEL_ATTACHABLE_FIELDS));
|
||||
].concat(PanelAttachable).concat(Billboardable));
|
||||
Billboard3DOverlay.prototype.isPanelAttachable = function() { return true; };
|
||||
|
||||
Volume3DOverlay = generateOverlayClass(Base3DOverlay, ABSTRACT, [
|
||||
@ -382,10 +388,11 @@
|
||||
|
||||
that.prototype.constructor = that;
|
||||
|
||||
[
|
||||
"position", "positionBinding", "rotation", "rotationBinding", "scale",
|
||||
"offsetPosition", "offsetRotation", "offsetScale", "visible", "isFacingAvatar"
|
||||
].forEach(function(prop) {
|
||||
var props = [
|
||||
"position", "positionBinding", "rotation", "rotationBinding", "scale", "visible"
|
||||
].concat(PanelAttachable).concat(Billboardable)
|
||||
|
||||
props.forEach(function(prop) {
|
||||
Object.defineProperty(that.prototype, prop, {
|
||||
get: function() {
|
||||
return Overlays.getPanelProperty(this._id, prop);
|
||||
|
@ -15,26 +15,23 @@
|
||||
Billboard3DOverlay::Billboard3DOverlay(const Billboard3DOverlay* billboard3DOverlay) :
|
||||
Planar3DOverlay(billboard3DOverlay),
|
||||
PanelAttachable(*billboard3DOverlay),
|
||||
_isFacingAvatar(billboard3DOverlay->_isFacingAvatar)
|
||||
Billboardable(*billboard3DOverlay)
|
||||
{
|
||||
}
|
||||
|
||||
void Billboard3DOverlay::setProperties(const QScriptValue &properties) {
|
||||
Planar3DOverlay::setProperties(properties);
|
||||
PanelAttachable::setProperties(properties);
|
||||
|
||||
QScriptValue isFacingAvatarValue = properties.property("isFacingAvatar");
|
||||
if (isFacingAvatarValue.isValid()) {
|
||||
_isFacingAvatar = isFacingAvatarValue.toVariant().toBool();
|
||||
}
|
||||
Billboardable::setProperties(properties);
|
||||
}
|
||||
|
||||
QScriptValue Billboard3DOverlay::getProperty(const QString &property) {
|
||||
if (property == "isFacingAvatar") {
|
||||
return _isFacingAvatar;
|
||||
QScriptValue value;
|
||||
value = Billboardable::getProperty(_scriptEngine, property);
|
||||
if (value.isValid()) {
|
||||
return value;
|
||||
}
|
||||
|
||||
QScriptValue value = PanelAttachable::getProperty(_scriptEngine, property);
|
||||
value = PanelAttachable::getProperty(_scriptEngine, property);
|
||||
if (value.isValid()) {
|
||||
return value;
|
||||
}
|
||||
@ -44,15 +41,7 @@ QScriptValue Billboard3DOverlay::getProperty(const QString &property) {
|
||||
void Billboard3DOverlay::applyTransformTo(Transform& transform, bool force) {
|
||||
if (force || usecTimestampNow() > _transformExpiry) {
|
||||
PanelAttachable::applyTransformTo(transform, true);
|
||||
if (_isFacingAvatar) {
|
||||
glm::vec3 billboardPos = transform.getTranslation();
|
||||
glm::vec3 cameraPos = Application::getInstance()->getCamera()->getPosition();
|
||||
glm::vec3 look = cameraPos - billboardPos;
|
||||
float elevation = -asinf(look.y / glm::length(look));
|
||||
float azimuth = atan2f(look.x, look.z);
|
||||
glm::quat rotation(glm::vec3(elevation, azimuth, 0));
|
||||
transform.setRotation(rotation);
|
||||
transform.postRotate(getOffsetRotation());
|
||||
}
|
||||
transformLookAtCamera(transform);
|
||||
transform.postRotate(getOffsetRotation());
|
||||
}
|
||||
}
|
||||
|
@ -14,25 +14,20 @@
|
||||
|
||||
#include "Planar3DOverlay.h"
|
||||
#include "PanelAttachable.h"
|
||||
#include "Billboardable.h"
|
||||
|
||||
class Billboard3DOverlay : public Planar3DOverlay, public PanelAttachable {
|
||||
class Billboard3DOverlay : public Planar3DOverlay, public PanelAttachable, public Billboardable {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Billboard3DOverlay() {}
|
||||
Billboard3DOverlay(const Billboard3DOverlay* billboard3DOverlay);
|
||||
|
||||
bool getIsFacingAvatar() const { return _isFacingAvatar; }
|
||||
void setIsFacingAvatar(bool isFacingAvatar) { _isFacingAvatar = isFacingAvatar; }
|
||||
|
||||
virtual void setProperties(const QScriptValue& properties);
|
||||
virtual QScriptValue getProperty(const QString& property);
|
||||
|
||||
protected:
|
||||
virtual void applyTransformTo(Transform& transform, bool force = false);
|
||||
|
||||
private:
|
||||
bool _isFacingAvatar = false;
|
||||
};
|
||||
|
||||
#endif // hifi_Billboard3DOverlay_h
|
||||
|
40
interface/src/ui/overlays/Billboardable.cpp
Normal file
40
interface/src/ui/overlays/Billboardable.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
//
|
||||
// Billboardable.cpp
|
||||
// interface/src/ui/overlays
|
||||
//
|
||||
// Created by Zander Otavka on 8/7/15.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "Billboardable.h"
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
void Billboardable::setProperties(const QScriptValue &properties) {
|
||||
QScriptValue isFacingAvatar = properties.property("isFacingAvatar");
|
||||
if (isFacingAvatar.isValid()) {
|
||||
setIsFacingAvatar(isFacingAvatar.toVariant().toBool());
|
||||
}
|
||||
}
|
||||
|
||||
QScriptValue Billboardable::getProperty(QScriptEngine* scriptEngine, const QString &property) {
|
||||
if (property == "isFacingAvatar") {
|
||||
return isFacingAvatar();
|
||||
}
|
||||
return QScriptValue();
|
||||
}
|
||||
|
||||
void Billboardable::transformLookAtCamera(Transform& transform) {
|
||||
if (_isFacingAvatar) {
|
||||
glm::vec3 billboardPos = transform.getTranslation();
|
||||
glm::vec3 cameraPos = Application::getInstance()->getCamera()->getPosition();
|
||||
glm::vec3 look = cameraPos - billboardPos;
|
||||
float elevation = -asinf(look.y / glm::length(look));
|
||||
float azimuth = atan2f(look.x, look.z);
|
||||
glm::quat rotation(glm::vec3(elevation, azimuth, 0));
|
||||
transform.setRotation(rotation);
|
||||
}
|
||||
}
|
35
interface/src/ui/overlays/Billboardable.h
Normal file
35
interface/src/ui/overlays/Billboardable.h
Normal file
@ -0,0 +1,35 @@
|
||||
//
|
||||
// Billboardable.h
|
||||
// interface/src/ui/overlays
|
||||
//
|
||||
// Created by Zander Otavka on 8/7/15.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_Billboardable_h
|
||||
#define hifi_Billboardable_h
|
||||
|
||||
#include <QScriptValue>
|
||||
#include <QScriptEngine>
|
||||
|
||||
#include <Transform.h>
|
||||
|
||||
class Billboardable {
|
||||
public:
|
||||
bool isFacingAvatar() const { return _isFacingAvatar; }
|
||||
void setIsFacingAvatar(bool isFacingAvatar) { _isFacingAvatar = isFacingAvatar; }
|
||||
|
||||
protected:
|
||||
void setProperties(const QScriptValue& properties);
|
||||
QScriptValue getProperty(QScriptEngine* scriptEngine, const QString& property);
|
||||
|
||||
void transformLookAtCamera(Transform& transform);
|
||||
|
||||
private:
|
||||
bool _isFacingAvatar = false;
|
||||
};
|
||||
|
||||
#endif // hifi_Billboardable_h
|
@ -86,9 +86,6 @@ QScriptValue OverlayPanel::getProperty(const QString &property) {
|
||||
if (property == "visible") {
|
||||
return getVisible();
|
||||
}
|
||||
if (property == "isFacingAvatar") {
|
||||
return getIsFacingAvatar();
|
||||
}
|
||||
if (property == "children") {
|
||||
QScriptValue array = _scriptEngine->newArray(_children.length());
|
||||
for (int i = 0; i < _children.length(); i++) {
|
||||
@ -97,11 +94,16 @@ QScriptValue OverlayPanel::getProperty(const QString &property) {
|
||||
return array;
|
||||
}
|
||||
|
||||
QScriptValue value = Billboardable::getProperty(_scriptEngine, property);
|
||||
if (value.isValid()) {
|
||||
return value;
|
||||
}
|
||||
return PanelAttachable::getProperty(_scriptEngine, property);
|
||||
}
|
||||
|
||||
void OverlayPanel::setProperties(const QScriptValue &properties) {
|
||||
PanelAttachable::setProperties(properties);
|
||||
Billboardable::setProperties(properties);
|
||||
|
||||
QScriptValue position = properties.property("position");
|
||||
if (position.isValid() &&
|
||||
@ -157,11 +159,6 @@ void OverlayPanel::setProperties(const QScriptValue &properties) {
|
||||
if (visible.isValid()) {
|
||||
setVisible(visible.toVariant().toBool());
|
||||
}
|
||||
|
||||
QScriptValue isFacingAvatar = properties.property("isFacingAvatar");
|
||||
if (isFacingAvatar.isValid()) {
|
||||
setIsFacingAvatar(isFacingAvatar.toVariant().toBool());
|
||||
}
|
||||
}
|
||||
|
||||
void OverlayPanel::applyTransformTo(Transform& transform, bool force) {
|
||||
@ -176,16 +173,8 @@ void OverlayPanel::applyTransformTo(Transform& transform, bool force) {
|
||||
transform.postRotate(getOffsetRotation());
|
||||
transform.postScale(getOffsetScale());
|
||||
}
|
||||
if (_isFacingAvatar) {
|
||||
glm::vec3 billboardPos = transform.getTranslation();
|
||||
glm::vec3 cameraPos = Application::getInstance()->getCamera()->getPosition();
|
||||
glm::vec3 look = cameraPos - billboardPos;
|
||||
float elevation = -asinf(look.y / glm::length(look));
|
||||
float azimuth = atan2f(look.x, look.z);
|
||||
glm::quat rotation(glm::vec3(elevation, azimuth, 0.0f));
|
||||
transform.setRotation(rotation);
|
||||
transform.postRotate(getOffsetRotation());
|
||||
}
|
||||
transformLookAtCamera(transform);
|
||||
transform.postRotate(getOffsetRotation());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <QUuid>
|
||||
|
||||
#include "PanelAttachable.h"
|
||||
#include "Billboardable.h"
|
||||
|
||||
class PropertyBinding {
|
||||
public:
|
||||
@ -33,7 +34,7 @@ QScriptValue propertyBindingToScriptValue(QScriptEngine* engine, const PropertyB
|
||||
void propertyBindingFromScriptValue(const QScriptValue& object, PropertyBinding& value);
|
||||
|
||||
|
||||
class OverlayPanel : public QObject, public PanelAttachable {
|
||||
class OverlayPanel : public QObject, public PanelAttachable, public Billboardable {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
@ -46,7 +47,6 @@ public:
|
||||
glm::quat getRotation() const { return _transform.getRotation(); }
|
||||
glm::vec3 getScale() const { return _transform.getScale(); }
|
||||
bool getVisible() const { return _visible; }
|
||||
bool getIsFacingAvatar() const { return _isFacingAvatar; }
|
||||
|
||||
// setters
|
||||
void setPosition(const glm::vec3& position) { _transform.setTranslation(position); }
|
||||
@ -54,7 +54,6 @@ public:
|
||||
void setScale(float scale) { _transform.setScale(scale); }
|
||||
void setScale(const glm::vec3& scale) { _transform.setScale(scale); }
|
||||
void setVisible(bool visible) { _visible = visible; }
|
||||
void setIsFacingAvatar(bool isFacingAvatar) { _isFacingAvatar = isFacingAvatar; }
|
||||
|
||||
const QList<unsigned int>& getChildren() { return _children; }
|
||||
void addChild(unsigned int childId);
|
||||
@ -78,7 +77,6 @@ private:
|
||||
QUuid _rotationBindEntity;
|
||||
|
||||
bool _visible = true;
|
||||
bool _isFacingAvatar = false;
|
||||
QList<unsigned int> _children;
|
||||
|
||||
QScriptEngine* _scriptEngine;
|
||||
|
@ -38,10 +38,10 @@ public:
|
||||
void setOffsetScale(float scale) { _offset.setScale(scale); }
|
||||
void setOffsetScale(const glm::vec3& scale) { _offset.setScale(scale); }
|
||||
|
||||
protected:
|
||||
QScriptValue getProperty(QScriptEngine* scriptEngine, const QString& property);
|
||||
void setProperties(const QScriptValue& properties);
|
||||
|
||||
protected:
|
||||
virtual void applyTransformTo(Transform& transform, bool force = false);
|
||||
quint64 _transformExpiry = 0;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user