mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 17:53:32 +02:00
Merge branch 'master' of https://github.com/worklist/hifi
This commit is contained in:
commit
ad4556ab56
16 changed files with 185 additions and 56 deletions
|
@ -76,38 +76,42 @@ function controller(wichSide) {
|
|||
this.oldModelRadius;
|
||||
|
||||
this.laser = Overlays.addOverlay("line3d", {
|
||||
position: this.palmPosition,
|
||||
end: this.tipPosition,
|
||||
position: { x: 0, y: 0, z: 0 },
|
||||
end: { x: 0, y: 0, z: 0 },
|
||||
color: LASER_COLOR,
|
||||
alpha: 1,
|
||||
visible: false,
|
||||
lineWidth: LASER_WIDTH
|
||||
lineWidth: LASER_WIDTH,
|
||||
anchor: "MyAvatar"
|
||||
});
|
||||
|
||||
this.guideScale = 0.02;
|
||||
this.ball = Overlays.addOverlay("sphere", {
|
||||
position: this.palmPosition,
|
||||
position: { x: 0, y: 0, z: 0 },
|
||||
size: this.guideScale,
|
||||
solid: true,
|
||||
color: { red: 0, green: 255, blue: 0 },
|
||||
alpha: 1,
|
||||
visible: false,
|
||||
anchor: "MyAvatar"
|
||||
});
|
||||
this.leftRight = Overlays.addOverlay("line3d", {
|
||||
position: this.palmPosition,
|
||||
end: this.tipPosition,
|
||||
position: { x: 0, y: 0, z: 0 },
|
||||
end: { x: 0, y: 0, z: 0 },
|
||||
color: { red: 0, green: 0, blue: 255 },
|
||||
alpha: 1,
|
||||
visible: false,
|
||||
lineWidth: LASER_WIDTH
|
||||
lineWidth: LASER_WIDTH,
|
||||
anchor: "MyAvatar"
|
||||
});
|
||||
this.topDown = Overlays.addOverlay("line3d", {
|
||||
position: this.palmPosition,
|
||||
end: this.tipPosition,
|
||||
position: { x: 0, y: 0, z: 0 },
|
||||
end: { x: 0, y: 0, z: 0 },
|
||||
color: { red: 0, green: 0, blue: 255 },
|
||||
alpha: 1,
|
||||
visible: false,
|
||||
lineWidth: LASER_WIDTH
|
||||
lineWidth: LASER_WIDTH,
|
||||
anchor: "MyAvatar"
|
||||
});
|
||||
|
||||
|
||||
|
@ -170,10 +174,11 @@ function controller(wichSide) {
|
|||
}
|
||||
|
||||
this.moveLaser = function () {
|
||||
var endPosition = Vec3.sum(this.palmPosition, Vec3.multiply(this.front, LASER_LENGTH_FACTOR));
|
||||
var startPosition = Vec3.subtract(this.palmPosition, MyAvatar.position);
|
||||
var endPosition = Vec3.sum(startPosition, Vec3.multiply(this.front, LASER_LENGTH_FACTOR));
|
||||
|
||||
Overlays.editOverlay(this.laser, {
|
||||
position: this.palmPosition,
|
||||
position: startPosition,
|
||||
end: endPosition,
|
||||
visible: true
|
||||
});
|
||||
|
@ -219,11 +224,11 @@ function controller(wichSide) {
|
|||
position: newPosition,
|
||||
modelRotation: newRotation
|
||||
});
|
||||
print("Moving " + this.modelID.id);
|
||||
// print("Moving " + this.modelID.id);
|
||||
// Vec3.print("Old Position: ", this.oldModelPosition);
|
||||
// Vec3.print("Sav Position: ", newPosition);
|
||||
Quat.print("Old Rotation: ", this.oldModelRotation);
|
||||
Quat.print("New Rotation: ", newRotation);
|
||||
// Quat.print("Old Rotation: ", this.oldModelRotation);
|
||||
// Quat.print("New Rotation: ", newRotation);
|
||||
|
||||
this.oldModelRotation = newRotation;
|
||||
this.oldModelPosition = newPosition;
|
||||
|
@ -301,7 +306,7 @@ var rightController = new controller(RIGHT);
|
|||
|
||||
function moveModels() {
|
||||
if (leftController.grabbing && rightController.grabbing && rightController.modelID.id == leftController.modelID.id) {
|
||||
print("Both controllers");
|
||||
//print("Both controllers");
|
||||
var oldLeftPoint = Vec3.sum(leftController.oldPalmPosition, Vec3.multiply(leftController.oldFront, leftController.x));
|
||||
var oldRightPoint = Vec3.sum(rightController.oldPalmPosition, Vec3.multiply(rightController.oldFront, rightController.x));
|
||||
|
||||
|
@ -319,7 +324,7 @@ function moveModels() {
|
|||
|
||||
var newPosition = Vec3.sum(middle,
|
||||
Vec3.multiply(Vec3.subtract(leftController.oldModelPosition, oldMiddle), ratio));
|
||||
Vec3.print("Ratio : " + ratio + " New position: ", newPosition);
|
||||
//Vec3.print("Ratio : " + ratio + " New position: ", newPosition);
|
||||
var rotation = Quat.multiply(leftController.rotation,
|
||||
Quat.inverse(leftController.oldRotation));
|
||||
rotation = Quat.multiply(rotation, leftController.oldModelRotation);
|
||||
|
|
|
@ -237,6 +237,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
|
||||
connect(&nodeList->getDomainHandler(), SIGNAL(hostnameChanged(const QString&)), SLOT(domainChanged(const QString&)));
|
||||
connect(&nodeList->getDomainHandler(), SIGNAL(connectedToDomain(const QString&)), SLOT(connectedToDomain(const QString&)));
|
||||
|
||||
// update our location every 5 seconds in the data-server, assuming that we are authenticated with one
|
||||
const float DATA_SERVER_LOCATION_CHANGE_UPDATE_MSECS = 5.0f * 1000.0f;
|
||||
|
||||
QTimer* locationUpdateTimer = new QTimer(this);
|
||||
connect(locationUpdateTimer, &QTimer::timeout, this, &Application::updateLocationInServer);
|
||||
locationUpdateTimer->start(DATA_SERVER_LOCATION_CHANGE_UPDATE_MSECS);
|
||||
|
||||
connect(nodeList, &NodeList::nodeAdded, this, &Application::nodeAdded);
|
||||
connect(nodeList, &NodeList::nodeKilled, this, &Application::nodeKilled);
|
||||
|
@ -3113,6 +3120,34 @@ void Application::updateWindowTitle(){
|
|||
_window->setWindowTitle(title);
|
||||
}
|
||||
|
||||
void Application::updateLocationInServer() {
|
||||
|
||||
AccountManager& accountManager = AccountManager::getInstance();
|
||||
|
||||
if (accountManager.isLoggedIn()) {
|
||||
|
||||
static QJsonObject lastLocationObject;
|
||||
|
||||
// construct a QJsonObject given the user's current address information
|
||||
QJsonObject updatedLocationObject;
|
||||
|
||||
QJsonObject addressObject;
|
||||
addressObject.insert("position", QString(createByteArray(_myAvatar->getPosition())));
|
||||
addressObject.insert("orientation", QString(createByteArray(glm::degrees(safeEulerAngles(_myAvatar->getOrientation())))));
|
||||
addressObject.insert("domain", NodeList::getInstance()->getDomainHandler().getHostname());
|
||||
|
||||
updatedLocationObject.insert("address", addressObject);
|
||||
|
||||
if (updatedLocationObject != lastLocationObject) {
|
||||
|
||||
accountManager.authenticatedRequest("/api/v1/users/address", QNetworkAccessManager::PutOperation,
|
||||
JSONCallbackParameters(), QJsonDocument(updatedLocationObject).toJson());
|
||||
|
||||
lastLocationObject = updatedLocationObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Application::domainChanged(const QString& domainHostname) {
|
||||
updateWindowTitle();
|
||||
|
||||
|
|
|
@ -278,6 +278,7 @@ signals:
|
|||
public slots:
|
||||
void domainChanged(const QString& domainHostname);
|
||||
void updateWindowTitle();
|
||||
void updateLocationInServer();
|
||||
void nodeAdded(SharedNodePointer node);
|
||||
void nodeKilled(SharedNodePointer node);
|
||||
void packetSent(quint64 length);
|
||||
|
|
|
@ -351,6 +351,7 @@ Menu::Menu() :
|
|||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::HandsCollideWithSelf, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::ShowIKConstraints, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlignForearmsWithWrists, 0, true);
|
||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::AlternateIK, 0, false);
|
||||
|
||||
addDisabledActionAndSeparator(developerMenu, "Testing");
|
||||
|
||||
|
|
|
@ -267,6 +267,7 @@ private:
|
|||
namespace MenuOption {
|
||||
const QString AboutApp = "About Interface";
|
||||
const QString AlignForearmsWithWrists = "Align Forearms with Wrists";
|
||||
const QString AlternateIK = "Alternate IK";
|
||||
const QString AmbientOcclusion = "Ambient Occlusion";
|
||||
const QString Atmosphere = "Atmosphere";
|
||||
const QString Attachments = "Attachments...";
|
||||
|
|
|
@ -49,8 +49,6 @@ const float COLLISION_RADIUS_SCALE = 0.125f;
|
|||
const float MIN_KEYBOARD_CONTROL_SPEED = 2.0f;
|
||||
const float MAX_WALKING_SPEED = 3.0f * MIN_KEYBOARD_CONTROL_SPEED;
|
||||
|
||||
const float DATA_SERVER_LOCATION_CHANGE_UPDATE_MSECS = 5.0f * 1000.0f;
|
||||
|
||||
// TODO: normalize avatar speed for standard avatar size, then scale all motion logic
|
||||
// to properly follow avatar size.
|
||||
float DEFAULT_MOTOR_TIMESCALE = 0.25f;
|
||||
|
@ -83,11 +81,6 @@ MyAvatar::MyAvatar() :
|
|||
for (int i = 0; i < MAX_DRIVE_KEYS; i++) {
|
||||
_driveKeys[i] = 0.0f;
|
||||
}
|
||||
|
||||
// update our location every 5 seconds in the data-server, assuming that we are authenticated with one
|
||||
QTimer* locationUpdateTimer = new QTimer(this);
|
||||
connect(locationUpdateTimer, &QTimer::timeout, this, &MyAvatar::updateLocationInDataServer);
|
||||
locationUpdateTimer->start(DATA_SERVER_LOCATION_CHANGE_UPDATE_MSECS);
|
||||
}
|
||||
|
||||
MyAvatar::~MyAvatar() {
|
||||
|
@ -237,7 +230,7 @@ void MyAvatar::simulate(float deltaTime) {
|
|||
void MyAvatar::updateFromTrackers(float deltaTime) {
|
||||
glm::vec3 estimatedPosition, estimatedRotation;
|
||||
|
||||
if (Application::getInstance()->getPrioVR()->isActive()) {
|
||||
if (Application::getInstance()->getPrioVR()->hasHeadRotation()) {
|
||||
estimatedRotation = glm::degrees(safeEulerAngles(Application::getInstance()->getPrioVR()->getHeadRotation()));
|
||||
estimatedRotation.x *= -1.0f;
|
||||
estimatedRotation.z *= -1.0f;
|
||||
|
@ -1434,29 +1427,6 @@ void MyAvatar::resetSize() {
|
|||
qDebug("Reseted scale to %f", _targetScale);
|
||||
}
|
||||
|
||||
static QByteArray createByteArray(const glm::vec3& vector) {
|
||||
return QByteArray::number(vector.x) + ',' + QByteArray::number(vector.y) + ',' + QByteArray::number(vector.z);
|
||||
}
|
||||
|
||||
void MyAvatar::updateLocationInDataServer() {
|
||||
// TODO: don't re-send this when it hasn't change or doesn't change by some threshold
|
||||
// This will required storing the last sent values and clearing them when the AccountManager rootURL changes
|
||||
|
||||
AccountManager& accountManager = AccountManager::getInstance();
|
||||
|
||||
if (accountManager.isLoggedIn()) {
|
||||
QString positionString(createByteArray(_position));
|
||||
QString orientationString(createByteArray(glm::degrees(safeEulerAngles(getOrientation()))));
|
||||
|
||||
// construct the json to put the user's location
|
||||
QString locationPutJson = QString() + "{\"address\":{\"position\":\""
|
||||
+ positionString + "\", \"orientation\":\"" + orientationString + "\"}}";
|
||||
|
||||
accountManager.authenticatedRequest("/api/v1/users/address", QNetworkAccessManager::PutOperation,
|
||||
JSONCallbackParameters(), locationPutJson.toUtf8());
|
||||
}
|
||||
}
|
||||
|
||||
void MyAvatar::goToLocationFromResponse(const QJsonObject& jsonObject) {
|
||||
|
||||
if (jsonObject["status"].toString() == "success") {
|
||||
|
|
|
@ -108,7 +108,6 @@ public slots:
|
|||
void decreaseSize();
|
||||
void resetSize();
|
||||
|
||||
void updateLocationInDataServer();
|
||||
void goToLocationFromResponse(const QJsonObject& jsonObject);
|
||||
|
||||
// Set/Get update the thrust that will move the avatar around
|
||||
|
|
|
@ -164,7 +164,8 @@ void SkeletonModel::applyPalmData(int jointIndex, PalmData& palm) {
|
|||
|
||||
// rotate palm to align with its normal (normal points out of hand's palm)
|
||||
glm::quat palmRotation;
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::AlignForearmsWithWrists)) {
|
||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::AlternateIK) &&
|
||||
Menu::getInstance()->isOptionChecked(MenuOption::AlignForearmsWithWrists)) {
|
||||
getJointRotation(parentJointIndex, palmRotation, true);
|
||||
} else {
|
||||
getJointRotation(jointIndex, palmRotation, true);
|
||||
|
@ -176,7 +177,10 @@ void SkeletonModel::applyPalmData(int jointIndex, PalmData& palm) {
|
|||
palmRotation = rotationBetween(palmRotation * glm::vec3(-sign, 0.0f, 0.0f), direction) * palmRotation;
|
||||
|
||||
// set hand position, rotation
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::AlignForearmsWithWrists)) {
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::AlternateIK)) {
|
||||
setHandPosition(jointIndex, palm.getPosition(), palmRotation);
|
||||
|
||||
} else if (Menu::getInstance()->isOptionChecked(MenuOption::AlignForearmsWithWrists)) {
|
||||
glm::vec3 forearmVector = palmRotation * glm::vec3(sign, 0.0f, 0.0f);
|
||||
setJointPosition(parentJointIndex, palm.getPosition() + forearmVector *
|
||||
geometry.joints.at(jointIndex).distanceToParent * extractUniformScale(_scale));
|
||||
|
@ -276,3 +280,68 @@ void SkeletonModel::renderJointConstraints(int jointIndex) {
|
|||
glLineWidth(1.0f);
|
||||
}
|
||||
|
||||
void SkeletonModel::setHandPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation) {
|
||||
// this algorithm is from sample code from sixense
|
||||
const FBXGeometry& geometry = _geometry->getFBXGeometry();
|
||||
int elbowJointIndex = geometry.joints.at(jointIndex).parentIndex;
|
||||
if (elbowJointIndex == -1) {
|
||||
return;
|
||||
}
|
||||
int shoulderJointIndex = geometry.joints.at(elbowJointIndex).parentIndex;
|
||||
glm::vec3 shoulderPosition;
|
||||
if (!getJointPosition(shoulderJointIndex, shoulderPosition)) {
|
||||
return;
|
||||
}
|
||||
// precomputed lengths
|
||||
float scale = extractUniformScale(_scale);
|
||||
float upperArmLength = geometry.joints.at(elbowJointIndex).distanceToParent * scale;
|
||||
float lowerArmLength = geometry.joints.at(jointIndex).distanceToParent * scale;
|
||||
|
||||
// first set wrist position
|
||||
glm::vec3 wristPosition = position;
|
||||
|
||||
glm::vec3 shoulderToWrist = wristPosition - shoulderPosition;
|
||||
float distanceToWrist = glm::length(shoulderToWrist);
|
||||
|
||||
// prevent gimbal lock
|
||||
if (distanceToWrist > upperArmLength + lowerArmLength - EPSILON) {
|
||||
distanceToWrist = upperArmLength + lowerArmLength - EPSILON;
|
||||
shoulderToWrist = glm::normalize(shoulderToWrist) * distanceToWrist;
|
||||
wristPosition = shoulderPosition + shoulderToWrist;
|
||||
}
|
||||
|
||||
// cosine of angle from upper arm to hand vector
|
||||
float cosA = (upperArmLength * upperArmLength + distanceToWrist * distanceToWrist - lowerArmLength * lowerArmLength) /
|
||||
(2 * upperArmLength * distanceToWrist);
|
||||
float mid = upperArmLength * cosA;
|
||||
float height = sqrt(upperArmLength * upperArmLength + mid * mid - 2 * upperArmLength * mid * cosA);
|
||||
|
||||
// direction of the elbow
|
||||
glm::vec3 handNormal = glm::cross(rotation * glm::vec3(0.0f, 1.0f, 0.0f), shoulderToWrist); // elbow rotating with wrist
|
||||
glm::vec3 relaxedNormal = glm::cross(glm::vec3(0.0f, 1.0f, 0.0f), shoulderToWrist); // elbow pointing straight down
|
||||
const float NORMAL_WEIGHT = 0.5f;
|
||||
glm::vec3 finalNormal = glm::mix(relaxedNormal, handNormal, NORMAL_WEIGHT);
|
||||
|
||||
bool rightHand = (jointIndex == geometry.rightHandJointIndex);
|
||||
if (rightHand ? (finalNormal.y > 0.0f) : (finalNormal.y < 0.0f)) {
|
||||
finalNormal.y = 0.0f; // dont allow elbows to point inward (y is vertical axis)
|
||||
}
|
||||
|
||||
glm::vec3 tangent = glm::normalize(glm::cross(shoulderToWrist, finalNormal));
|
||||
|
||||
// ik solution
|
||||
glm::vec3 elbowPosition = shoulderPosition + glm::normalize(shoulderToWrist) * mid - tangent * height;
|
||||
|
||||
glm::vec3 forwardVector(rightHand ? -1.0f : 1.0f, 0.0f, 0.0f);
|
||||
|
||||
glm::quat shoulderRotation;
|
||||
getJointRotation(shoulderJointIndex, shoulderRotation, true);
|
||||
applyRotationDelta(shoulderJointIndex, rotationBetween(shoulderRotation * forwardVector, elbowPosition - shoulderPosition), false);
|
||||
|
||||
glm::quat elbowRotation;
|
||||
getJointRotation(elbowJointIndex, elbowRotation, true);
|
||||
applyRotationDelta(elbowJointIndex, rotationBetween(elbowRotation * forwardVector, wristPosition - elbowPosition), false);
|
||||
|
||||
setJointRotation(jointIndex, rotation, true);
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ protected:
|
|||
private:
|
||||
|
||||
void renderJointConstraints(int jointIndex);
|
||||
void setHandPosition(int jointIndex, const glm::vec3& position, const glm::quat& rotation);
|
||||
|
||||
Avatar* _owningAvatar;
|
||||
};
|
||||
|
|
|
@ -48,6 +48,7 @@ PrioVR::PrioVR() {
|
|||
return;
|
||||
}
|
||||
_jointRotations.resize(LIST_LENGTH);
|
||||
_lastJointRotations.resize(LIST_LENGTH);
|
||||
for (int i = 0; i < LIST_LENGTH; i++) {
|
||||
_humanIKJointIndices.append(jointsDiscovered[i] ? indexOfHumanIKJoint(JOINT_NAMES[i]) : -1);
|
||||
}
|
||||
|
@ -62,8 +63,13 @@ PrioVR::~PrioVR() {
|
|||
#endif
|
||||
}
|
||||
|
||||
glm::quat PrioVR::getHeadRotation() const {
|
||||
const int HEAD_ROTATION_INDEX = 0;
|
||||
const int HEAD_ROTATION_INDEX = 0;
|
||||
|
||||
bool PrioVR::hasHeadRotation() const {
|
||||
return _humanIKJointIndices.size() > HEAD_ROTATION_INDEX && _humanIKJointIndices.at(HEAD_ROTATION_INDEX) != -1;
|
||||
}
|
||||
|
||||
glm::quat PrioVR::getHeadRotation() const {
|
||||
return _jointRotations.size() > HEAD_ROTATION_INDEX ? _jointRotations.at(HEAD_ROTATION_INDEX) : glm::quat();
|
||||
}
|
||||
|
||||
|
@ -81,10 +87,14 @@ void PrioVR::update() {
|
|||
yei_getLastStreamDataAll(_skeletalDevice, (char*)_jointRotations.data(),
|
||||
_jointRotations.size() * sizeof(glm::quat), ×tamp);
|
||||
|
||||
// convert to our expected coordinate system
|
||||
// convert to our expected coordinate system, average with last rotations to smooth
|
||||
for (int i = 0; i < _jointRotations.size(); i++) {
|
||||
_jointRotations[i].y *= -1.0f;
|
||||
_jointRotations[i].z *= -1.0f;
|
||||
|
||||
glm::quat lastRotation = _lastJointRotations.at(i);
|
||||
_lastJointRotations[i] = _jointRotations.at(i);
|
||||
_jointRotations[i] = safeMix(lastRotation, _jointRotations.at(i), 0.5f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@ public:
|
|||
|
||||
bool isActive() const { return !_jointRotations.isEmpty(); }
|
||||
|
||||
bool hasHeadRotation() const;
|
||||
|
||||
glm::quat getHeadRotation() const;
|
||||
glm::quat getTorsoRotation() const;
|
||||
|
||||
|
@ -55,6 +57,7 @@ private:
|
|||
|
||||
QVector<int> _humanIKJointIndices;
|
||||
QVector<glm::quat> _jointRotations;
|
||||
QVector<glm::quat> _lastJointRotations;
|
||||
|
||||
QDateTime _calibrationCountdownStarted;
|
||||
};
|
||||
|
|
|
@ -23,7 +23,8 @@ Overlay::Overlay() :
|
|||
_parent(NULL),
|
||||
_alpha(DEFAULT_ALPHA),
|
||||
_color(DEFAULT_BACKGROUND_COLOR),
|
||||
_visible(true)
|
||||
_visible(true),
|
||||
_anchor(NO_ANCHOR)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -51,8 +52,15 @@ void Overlay::setProperties(const QScriptValue& properties) {
|
|||
if (properties.property("alpha").isValid()) {
|
||||
setAlpha(properties.property("alpha").toVariant().toFloat());
|
||||
}
|
||||
|
||||
|
||||
if (properties.property("visible").isValid()) {
|
||||
setVisible(properties.property("visible").toVariant().toBool());
|
||||
}
|
||||
|
||||
if (properties.property("anchor").isValid()) {
|
||||
QString property = properties.property("anchor").toVariant().toString();
|
||||
if (property == "MyAvatar") {
|
||||
setAnchor(MY_AVATAR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,11 @@ class Overlay : public QObject {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum Anchor {
|
||||
NO_ANCHOR,
|
||||
MY_AVATAR
|
||||
};
|
||||
|
||||
Overlay();
|
||||
~Overlay();
|
||||
void init(QGLWidget* parent);
|
||||
|
@ -38,11 +43,13 @@ public:
|
|||
bool getVisible() const { return _visible; }
|
||||
const xColor& getColor() const { return _color; }
|
||||
float getAlpha() const { return _alpha; }
|
||||
Anchor getAnchor() const { return _anchor; }
|
||||
|
||||
// setters
|
||||
void setVisible(bool visible) { _visible = visible; }
|
||||
void setColor(const xColor& color) { _color = color; }
|
||||
void setAlpha(float alpha) { _alpha = alpha; }
|
||||
void setAnchor(Anchor anchor) { _anchor = anchor; }
|
||||
|
||||
virtual void setProperties(const QScriptValue& properties);
|
||||
|
||||
|
@ -51,6 +58,7 @@ protected:
|
|||
float _alpha;
|
||||
xColor _color;
|
||||
bool _visible; // should the overlay be drawn at all
|
||||
Anchor _anchor;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <Application.h>
|
||||
|
||||
#include "Cube3DOverlay.h"
|
||||
#include "ImageOverlay.h"
|
||||
|
@ -57,8 +58,19 @@ void Overlays::render2D() {
|
|||
}
|
||||
|
||||
void Overlays::render3D() {
|
||||
glm::vec3 myAvatarPosition = Application::getInstance()->getAvatar()->getPosition();
|
||||
|
||||
foreach(Overlay* thisOverlay, _overlays3D) {
|
||||
glPushMatrix();
|
||||
switch (thisOverlay->getAnchor()) {
|
||||
case Overlay::MY_AVATAR:
|
||||
glTranslatef(myAvatarPosition.x, myAvatarPosition.y, myAvatarPosition.z);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
thisOverlay->render();
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -828,3 +828,7 @@ bool isSimilarPosition(const glm::vec3& positionA, const glm::vec3& positionB, f
|
|||
float positionDistance = glm::distance(positionA, positionB);
|
||||
return (positionDistance <= similarEnough);
|
||||
}
|
||||
|
||||
QByteArray createByteArray(const glm::vec3& vector) {
|
||||
return QByteArray::number(vector.x) + ',' + QByteArray::number(vector.y) + ',' + QByteArray::number(vector.z);
|
||||
}
|
||||
|
|
|
@ -187,4 +187,6 @@ bool isSimilarPosition(const glm::vec3& positionA, const glm::vec3& positionB, f
|
|||
/// \return bool is the float NaN
|
||||
bool isNaN(float value);
|
||||
|
||||
QByteArray createByteArray(const glm::vec3& vector);
|
||||
|
||||
#endif // hifi_SharedUtil_h
|
||||
|
|
Loading…
Reference in a new issue