mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 19:01:09 +02:00
Merge pull request #8339 from sethalves/overlay-children
3D Overlays can be children
This commit is contained in:
commit
e2f7b443fd
19 changed files with 350 additions and 107 deletions
|
@ -21,6 +21,7 @@ const bool DEFAULT_IS_SOLID = false;
|
||||||
const bool DEFAULT_IS_DASHED_LINE = false;
|
const bool DEFAULT_IS_DASHED_LINE = false;
|
||||||
|
|
||||||
Base3DOverlay::Base3DOverlay() :
|
Base3DOverlay::Base3DOverlay() :
|
||||||
|
SpatiallyNestable(NestableType::Overlay, QUuid::createUuid()),
|
||||||
_lineWidth(DEFAULT_LINE_WIDTH),
|
_lineWidth(DEFAULT_LINE_WIDTH),
|
||||||
_isSolid(DEFAULT_IS_SOLID),
|
_isSolid(DEFAULT_IS_SOLID),
|
||||||
_isDashedLine(DEFAULT_IS_DASHED_LINE),
|
_isDashedLine(DEFAULT_IS_DASHED_LINE),
|
||||||
|
@ -31,15 +32,85 @@ Base3DOverlay::Base3DOverlay() :
|
||||||
|
|
||||||
Base3DOverlay::Base3DOverlay(const Base3DOverlay* base3DOverlay) :
|
Base3DOverlay::Base3DOverlay(const Base3DOverlay* base3DOverlay) :
|
||||||
Overlay(base3DOverlay),
|
Overlay(base3DOverlay),
|
||||||
_transform(base3DOverlay->_transform),
|
SpatiallyNestable(NestableType::Overlay, QUuid::createUuid()),
|
||||||
_lineWidth(base3DOverlay->_lineWidth),
|
_lineWidth(base3DOverlay->_lineWidth),
|
||||||
_isSolid(base3DOverlay->_isSolid),
|
_isSolid(base3DOverlay->_isSolid),
|
||||||
_isDashedLine(base3DOverlay->_isDashedLine),
|
_isDashedLine(base3DOverlay->_isDashedLine),
|
||||||
_ignoreRayIntersection(base3DOverlay->_ignoreRayIntersection),
|
_ignoreRayIntersection(base3DOverlay->_ignoreRayIntersection),
|
||||||
_drawInFront(base3DOverlay->_drawInFront)
|
_drawInFront(base3DOverlay->_drawInFront)
|
||||||
{
|
{
|
||||||
|
setTransform(base3DOverlay->getTransform());
|
||||||
}
|
}
|
||||||
void Base3DOverlay::setProperties(const QVariantMap& properties) {
|
|
||||||
|
QVariantMap convertOverlayLocationFromScriptSemantics(const QVariantMap& properties) {
|
||||||
|
// the position and rotation in _transform are relative to the parent (aka local). The versions coming from
|
||||||
|
// scripts are in world-frame, unless localPosition or localRotation are used. Patch up the properties
|
||||||
|
// so that "position" and "rotation" are relative-to-parent values.
|
||||||
|
QVariantMap result = properties;
|
||||||
|
QUuid parentID = result["parentID"].isValid() ? QUuid(result["parentID"].toString()) : QUuid();
|
||||||
|
int parentJointIndex = result["parentJointIndex"].isValid() ? result["parentJointIndex"].toInt() : -1;
|
||||||
|
bool success;
|
||||||
|
|
||||||
|
// make "position" and "orientation" be relative-to-parent
|
||||||
|
if (result["localPosition"].isValid()) {
|
||||||
|
result["position"] = result["localPosition"];
|
||||||
|
} else if (result["position"].isValid()) {
|
||||||
|
glm::vec3 localPosition = SpatiallyNestable::worldToLocal(vec3FromVariant(result["position"]),
|
||||||
|
parentID, parentJointIndex, success);
|
||||||
|
result["position"] = vec3toVariant(localPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result["localOrientation"].isValid()) {
|
||||||
|
result["orientation"] = result["localOrientation"];
|
||||||
|
} else if (result["orientation"].isValid()) {
|
||||||
|
glm::quat localOrientation = SpatiallyNestable::worldToLocal(quatFromVariant(result["orientation"]),
|
||||||
|
parentID, parentJointIndex, success);
|
||||||
|
result["orientation"] = quatToVariant(localOrientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Base3DOverlay::setProperties(const QVariantMap& originalProperties) {
|
||||||
|
QVariantMap properties = originalProperties;
|
||||||
|
|
||||||
|
// carry over some legacy keys
|
||||||
|
if (!properties["position"].isValid() && !properties["localPosition"].isValid()) {
|
||||||
|
if (properties["p1"].isValid()) {
|
||||||
|
properties["position"] = properties["p1"];
|
||||||
|
} else if (properties["point"].isValid()) {
|
||||||
|
properties["position"] = properties["point"];
|
||||||
|
} else if (properties["start"].isValid()) {
|
||||||
|
properties["position"] = properties["start"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!properties["orientation"].isValid() && properties["rotation"].isValid()) {
|
||||||
|
properties["orientation"] = properties["rotation"];
|
||||||
|
}
|
||||||
|
if (!properties["localOrientation"].isValid() && properties["localRotation"].isValid()) {
|
||||||
|
properties["localOrientation"] = properties["localRotation"];
|
||||||
|
}
|
||||||
|
|
||||||
|
// All of parentID, parentJointIndex, position, orientation are needed to make sense of any of them.
|
||||||
|
// If any of these changed, pull any missing properties from the overlay.
|
||||||
|
if (properties["parentID"].isValid() || properties["parentJointIndex"].isValid() ||
|
||||||
|
properties["position"].isValid() || properties["localPosition"].isValid() ||
|
||||||
|
properties["orientation"].isValid() || properties["localOrientation"].isValid()) {
|
||||||
|
if (!properties["parentID"].isValid()) {
|
||||||
|
properties["parentID"] = getParentID();
|
||||||
|
}
|
||||||
|
if (!properties["parentJointIndex"].isValid()) {
|
||||||
|
properties["parentJointIndex"] = getParentJointIndex();
|
||||||
|
}
|
||||||
|
if (!properties["position"].isValid() && !properties["localPosition"].isValid()) {
|
||||||
|
properties["position"] = vec3toVariant(getPosition());
|
||||||
|
}
|
||||||
|
if (!properties["orientation"].isValid() && !properties["localOrientation"].isValid()) {
|
||||||
|
properties["orientation"] = quatToVariant(getOrientation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
properties = convertOverlayLocationFromScriptSemantics(properties);
|
||||||
Overlay::setProperties(properties);
|
Overlay::setProperties(properties);
|
||||||
|
|
||||||
bool needRenderItemUpdate = false;
|
bool needRenderItemUpdate = false;
|
||||||
|
@ -52,17 +123,12 @@ void Base3DOverlay::setProperties(const QVariantMap& properties) {
|
||||||
needRenderItemUpdate = true;
|
needRenderItemUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto position = properties["position"];
|
if (properties["position"].isValid()) {
|
||||||
|
setLocalPosition(vec3FromVariant(properties["position"]));
|
||||||
// if "position" property was not there, check to see if they included aliases: point, p1
|
needRenderItemUpdate = true;
|
||||||
if (!position.isValid()) {
|
|
||||||
position = properties["p1"];
|
|
||||||
if (!position.isValid()) {
|
|
||||||
position = properties["point"];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (position.isValid()) {
|
if (properties["orientation"].isValid()) {
|
||||||
setPosition(vec3FromVariant(position));
|
setLocalOrientation(quatFromVariant(properties["orientation"]));
|
||||||
needRenderItemUpdate = true;
|
needRenderItemUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,13 +137,6 @@ void Base3DOverlay::setProperties(const QVariantMap& properties) {
|
||||||
needRenderItemUpdate = true;
|
needRenderItemUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto rotation = properties["rotation"];
|
|
||||||
|
|
||||||
if (rotation.isValid()) {
|
|
||||||
setRotation(quatFromVariant(rotation));
|
|
||||||
needRenderItemUpdate = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (properties["isSolid"].isValid()) {
|
if (properties["isSolid"].isValid()) {
|
||||||
setIsSolid(properties["isSolid"].toBool());
|
setIsSolid(properties["isSolid"].toBool());
|
||||||
}
|
}
|
||||||
|
@ -107,6 +166,15 @@ void Base3DOverlay::setProperties(const QVariantMap& properties) {
|
||||||
setIgnoreRayIntersection(properties["ignoreRayIntersection"].toBool());
|
setIgnoreRayIntersection(properties["ignoreRayIntersection"].toBool());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (properties["parentID"].isValid()) {
|
||||||
|
setParentID(QUuid(properties["parentID"].toString()));
|
||||||
|
needRenderItemUpdate = true;
|
||||||
|
}
|
||||||
|
if (properties["parentJointIndex"].isValid()) {
|
||||||
|
setParentJointIndex(properties["parentJointIndex"].toInt());
|
||||||
|
needRenderItemUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Communicate changes to the renderItem if needed
|
// Communicate changes to the renderItem if needed
|
||||||
if (needRenderItemUpdate) {
|
if (needRenderItemUpdate) {
|
||||||
auto itemID = getRenderItemID();
|
auto itemID = getRenderItemID();
|
||||||
|
@ -123,12 +191,18 @@ QVariant Base3DOverlay::getProperty(const QString& property) {
|
||||||
if (property == "position" || property == "start" || property == "p1" || property == "point") {
|
if (property == "position" || property == "start" || property == "p1" || property == "point") {
|
||||||
return vec3toVariant(getPosition());
|
return vec3toVariant(getPosition());
|
||||||
}
|
}
|
||||||
|
if (property == "localPosition") {
|
||||||
|
return vec3toVariant(getLocalPosition());
|
||||||
|
}
|
||||||
|
if (property == "rotation" || property == "orientation") {
|
||||||
|
return quatToVariant(getOrientation());
|
||||||
|
}
|
||||||
|
if (property == "localRotation" || property == "localOrientation") {
|
||||||
|
return quatToVariant(getLocalOrientation());
|
||||||
|
}
|
||||||
if (property == "lineWidth") {
|
if (property == "lineWidth") {
|
||||||
return _lineWidth;
|
return _lineWidth;
|
||||||
}
|
}
|
||||||
if (property == "rotation") {
|
|
||||||
return quatToVariant(getRotation());
|
|
||||||
}
|
|
||||||
if (property == "isSolid" || property == "isFilled" || property == "solid" || property == "filed") {
|
if (property == "isSolid" || property == "isFilled" || property == "solid" || property == "filed") {
|
||||||
return _isSolid;
|
return _isSolid;
|
||||||
}
|
}
|
||||||
|
@ -144,6 +218,12 @@ QVariant Base3DOverlay::getProperty(const QString& property) {
|
||||||
if (property == "drawInFront") {
|
if (property == "drawInFront") {
|
||||||
return _drawInFront;
|
return _drawInFront;
|
||||||
}
|
}
|
||||||
|
if (property == "parentID") {
|
||||||
|
return getParentID();
|
||||||
|
}
|
||||||
|
if (property == "parentJointIndex") {
|
||||||
|
return getParentJointIndex();
|
||||||
|
}
|
||||||
|
|
||||||
return Overlay::getProperty(property);
|
return Overlay::getProperty(property);
|
||||||
}
|
}
|
||||||
|
@ -152,3 +232,19 @@ bool Base3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3
|
||||||
float& distance, BoxFace& face, glm::vec3& surfaceNormal) {
|
float& distance, BoxFace& face, glm::vec3& surfaceNormal) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Base3DOverlay::locationChanged(bool tellPhysics) {
|
||||||
|
auto itemID = getRenderItemID();
|
||||||
|
if (render::Item::isValidID(itemID)) {
|
||||||
|
render::ScenePointer scene = qApp->getMain3DScene();
|
||||||
|
render::PendingChanges pendingChanges;
|
||||||
|
pendingChanges.updateItem(itemID);
|
||||||
|
scene->enqueuePendingChanges(pendingChanges);
|
||||||
|
}
|
||||||
|
// Overlays can't currently have children.
|
||||||
|
// SpatiallyNestable::locationChanged(tellPhysics); // tell all the children, also
|
||||||
|
}
|
||||||
|
|
||||||
|
void Base3DOverlay::parentDeleted() {
|
||||||
|
qApp->getOverlays().deleteOverlay(getOverlayID());
|
||||||
|
}
|
||||||
|
|
|
@ -12,10 +12,11 @@
|
||||||
#define hifi_Base3DOverlay_h
|
#define hifi_Base3DOverlay_h
|
||||||
|
|
||||||
#include <Transform.h>
|
#include <Transform.h>
|
||||||
|
#include <SpatiallyNestable.h>
|
||||||
|
|
||||||
#include "Overlay.h"
|
#include "Overlay.h"
|
||||||
|
|
||||||
class Base3DOverlay : public Overlay {
|
class Base3DOverlay : public Overlay, public SpatiallyNestable {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -24,12 +25,9 @@ public:
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
virtual bool is3D() const override { return true; }
|
virtual bool is3D() const override { return true; }
|
||||||
const glm::vec3& getPosition() const { return _transform.getTranslation(); }
|
|
||||||
const glm::quat& getRotation() const { return _transform.getRotation(); }
|
|
||||||
const glm::vec3& getScale() const { return _transform.getScale(); }
|
|
||||||
|
|
||||||
// TODO: consider implementing registration points in this class
|
// TODO: consider implementing registration points in this class
|
||||||
const glm::vec3& getCenter() const { return getPosition(); }
|
glm::vec3 getCenter() const { return getPosition(); }
|
||||||
|
|
||||||
float getLineWidth() const { return _lineWidth; }
|
float getLineWidth() const { return _lineWidth; }
|
||||||
bool getIsSolid() const { return _isSolid; }
|
bool getIsSolid() const { return _isSolid; }
|
||||||
|
@ -38,12 +36,6 @@ public:
|
||||||
bool getIgnoreRayIntersection() const { return _ignoreRayIntersection; }
|
bool getIgnoreRayIntersection() const { return _ignoreRayIntersection; }
|
||||||
bool getDrawInFront() const { return _drawInFront; }
|
bool getDrawInFront() const { return _drawInFront; }
|
||||||
|
|
||||||
// setters
|
|
||||||
void setPosition(const glm::vec3& value) { _transform.setTranslation(value); }
|
|
||||||
void setRotation(const glm::quat& value) { _transform.setRotation(value); }
|
|
||||||
void setScale(float value) { _transform.setScale(value); }
|
|
||||||
void setScale(const glm::vec3& value) { _transform.setScale(value); }
|
|
||||||
|
|
||||||
void setLineWidth(float lineWidth) { _lineWidth = lineWidth; }
|
void setLineWidth(float lineWidth) { _lineWidth = lineWidth; }
|
||||||
void setIsSolid(bool isSolid) { _isSolid = isSolid; }
|
void setIsSolid(bool isSolid) { _isSolid = isSolid; }
|
||||||
void setIsDashedLine(bool isDashedLine) { _isDashedLine = isDashedLine; }
|
void setIsDashedLine(bool isDashedLine) { _isDashedLine = isDashedLine; }
|
||||||
|
@ -64,7 +56,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Transform _transform;
|
virtual void locationChanged(bool tellPhysics = true) override;
|
||||||
|
virtual void parentDeleted() override;
|
||||||
|
|
||||||
float _lineWidth;
|
float _lineWidth;
|
||||||
bool _isSolid;
|
bool _isSolid;
|
||||||
|
|
|
@ -69,17 +69,17 @@ void Circle3DOverlay::render(RenderArgs* args) {
|
||||||
|
|
||||||
// FIXME: THe line width of _lineWidth is not supported anymore, we ll need a workaround
|
// FIXME: THe line width of _lineWidth is not supported anymore, we ll need a workaround
|
||||||
|
|
||||||
auto transform = _transform;
|
auto transform = getTransform();
|
||||||
transform.postScale(glm::vec3(getDimensions(), 1.0f));
|
transform.postScale(glm::vec3(getDimensions(), 1.0f));
|
||||||
batch.setModelTransform(transform);
|
batch.setModelTransform(transform);
|
||||||
|
|
||||||
// for our overlay, is solid means we draw a ring between the inner and outer radius of the circle, otherwise
|
// 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...
|
// we just draw a line...
|
||||||
if (getIsSolid()) {
|
if (getIsSolid()) {
|
||||||
if (!_quadVerticesID) {
|
if (!_quadVerticesID) {
|
||||||
_quadVerticesID = geometryCache->allocateID();
|
_quadVerticesID = geometryCache->allocateID();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (geometryChanged) {
|
if (geometryChanged) {
|
||||||
QVector<glm::vec2> points;
|
QVector<glm::vec2> points;
|
||||||
QVector<glm::vec4> colors;
|
QVector<glm::vec4> colors;
|
||||||
|
|
|
@ -37,7 +37,11 @@ Image3DOverlay::Image3DOverlay(const Image3DOverlay* image3DOverlay) :
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image3DOverlay::update(float deltatime) {
|
void Image3DOverlay::update(float deltatime) {
|
||||||
applyTransformTo(_transform);
|
if (usecTimestampNow() > _transformExpiry) {
|
||||||
|
Transform transform = getTransform();
|
||||||
|
applyTransformTo(transform);
|
||||||
|
setTransform(transform);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image3DOverlay::render(RenderArgs* args) {
|
void Image3DOverlay::render(RenderArgs* args) {
|
||||||
|
@ -86,13 +90,14 @@ void Image3DOverlay::render(RenderArgs* args) {
|
||||||
xColor color = getColor();
|
xColor color = getColor();
|
||||||
float alpha = getAlpha();
|
float alpha = getAlpha();
|
||||||
|
|
||||||
applyTransformTo(_transform, true);
|
Transform transform = getTransform();
|
||||||
Transform transform = _transform;
|
applyTransformTo(transform, true);
|
||||||
|
setTransform(transform);
|
||||||
transform.postScale(glm::vec3(getDimensions(), 1.0f));
|
transform.postScale(glm::vec3(getDimensions(), 1.0f));
|
||||||
|
|
||||||
batch->setModelTransform(transform);
|
batch->setModelTransform(transform);
|
||||||
batch->setResourceTexture(0, _texture->getGPUTexture());
|
batch->setResourceTexture(0, _texture->getGPUTexture());
|
||||||
|
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(
|
DependencyManager::get<GeometryCache>()->renderQuad(
|
||||||
*batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
|
*batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
|
||||||
glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha)
|
glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha)
|
||||||
|
@ -187,7 +192,10 @@ bool Image3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec
|
||||||
float& distance, BoxFace& face, glm::vec3& surfaceNormal) {
|
float& distance, BoxFace& face, glm::vec3& surfaceNormal) {
|
||||||
if (_texture && _texture->isLoaded()) {
|
if (_texture && _texture->isLoaded()) {
|
||||||
// Make sure position and rotation is updated.
|
// Make sure position and rotation is updated.
|
||||||
applyTransformTo(_transform, true);
|
Transform transform = getTransform();
|
||||||
|
// XXX this code runs too often for this...
|
||||||
|
// applyTransformTo(transform, true);
|
||||||
|
// setTransform(transform);
|
||||||
|
|
||||||
// Produce the dimensions of the overlay based on the image's aspect ratio and the overlay's scale.
|
// Produce the dimensions of the overlay based on the image's aspect ratio and the overlay's scale.
|
||||||
bool isNull = _fromImage.isNull();
|
bool isNull = _fromImage.isNull();
|
||||||
|
@ -197,7 +205,10 @@ bool Image3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec
|
||||||
glm::vec2 dimensions = _dimensions * glm::vec2(width / maxSize, height / maxSize);
|
glm::vec2 dimensions = _dimensions * glm::vec2(width / maxSize, height / maxSize);
|
||||||
|
|
||||||
// FIXME - face and surfaceNormal not being set
|
// FIXME - face and surfaceNormal not being set
|
||||||
return findRayRectangleIntersection(origin, direction, getRotation(), getPosition(), dimensions, distance);
|
return findRayRectangleIntersection(origin, direction,
|
||||||
|
transform.getRotation(),
|
||||||
|
transform.getTranslation(),
|
||||||
|
dimensions, distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -35,8 +35,8 @@ AABox Line3DOverlay::getBounds() const {
|
||||||
auto extents = Extents{};
|
auto extents = Extents{};
|
||||||
extents.addPoint(_start);
|
extents.addPoint(_start);
|
||||||
extents.addPoint(_end);
|
extents.addPoint(_end);
|
||||||
extents.transform(_transform);
|
extents.transform(getTransform());
|
||||||
|
|
||||||
return AABox(extents);
|
return AABox(extents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ void Line3DOverlay::render(RenderArgs* args) {
|
||||||
|
|
||||||
auto batch = args->_batch;
|
auto batch = args->_batch;
|
||||||
if (batch) {
|
if (batch) {
|
||||||
batch->setModelTransform(_transform);
|
batch->setModelTransform(getTransform());
|
||||||
|
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
if (getIsDashedLine()) {
|
if (getIsDashedLine()) {
|
||||||
|
|
|
@ -178,3 +178,12 @@ bool ModelOverlay::findRayIntersectionExtraInfo(const glm::vec3& origin, const g
|
||||||
ModelOverlay* ModelOverlay::createClone() const {
|
ModelOverlay* ModelOverlay::createClone() const {
|
||||||
return new ModelOverlay(this);
|
return new ModelOverlay(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModelOverlay::locationChanged(bool tellPhysics) {
|
||||||
|
Base3DOverlay::locationChanged(tellPhysics);
|
||||||
|
|
||||||
|
if (_model && _model->isActive()) {
|
||||||
|
_model->setRotation(getRotation());
|
||||||
|
_model->setTranslation(getPosition());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -39,6 +39,8 @@ public:
|
||||||
virtual bool addToScene(Overlay::Pointer overlay, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) override;
|
virtual bool addToScene(Overlay::Pointer overlay, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) override;
|
||||||
virtual void removeFromScene(Overlay::Pointer overlay, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) override;
|
virtual void removeFromScene(Overlay::Pointer overlay, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) override;
|
||||||
|
|
||||||
|
void locationChanged(bool tellPhysics) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
ModelPointer _model;
|
ModelPointer _model;
|
||||||
|
|
|
@ -77,7 +77,7 @@ void Overlay::setProperties(const QVariantMap& properties) {
|
||||||
if (properties["pulsePeriod"].isValid()) {
|
if (properties["pulsePeriod"].isValid()) {
|
||||||
setPulsePeriod(properties["pulsePeriod"].toFloat());
|
setPulsePeriod(properties["pulsePeriod"].toFloat());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (properties["alphaPulse"].isValid()) {
|
if (properties["alphaPulse"].isValid()) {
|
||||||
setAlphaPulse(properties["alphaPulse"].toFloat());
|
setAlphaPulse(properties["alphaPulse"].toFloat());
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ void Overlay::setProperties(const QVariantMap& properties) {
|
||||||
bool visible = properties["visible"].toBool();
|
bool visible = properties["visible"].toBool();
|
||||||
setVisible(visible);
|
setVisible(visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (properties["anchor"].isValid()) {
|
if (properties["anchor"].isValid()) {
|
||||||
QString property = properties["anchor"].toString();
|
QString property = properties["anchor"].toString();
|
||||||
if (property == "MyAvatar") {
|
if (property == "MyAvatar") {
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
class Overlay : public QObject {
|
class Overlay : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum Anchor {
|
enum Anchor {
|
||||||
NO_ANCHOR,
|
NO_ANCHOR,
|
||||||
|
@ -31,9 +31,13 @@ public:
|
||||||
Overlay();
|
Overlay();
|
||||||
Overlay(const Overlay* overlay);
|
Overlay(const Overlay* overlay);
|
||||||
~Overlay();
|
~Overlay();
|
||||||
|
|
||||||
|
unsigned int getOverlayID() { return _overlayID; }
|
||||||
|
void setOverlayID(unsigned int overlayID) { _overlayID = overlayID; }
|
||||||
|
|
||||||
virtual void update(float deltatime) {}
|
virtual void update(float deltatime) {}
|
||||||
virtual void render(RenderArgs* args) = 0;
|
virtual void render(RenderArgs* args) = 0;
|
||||||
|
|
||||||
virtual AABox getBounds() const = 0;
|
virtual AABox getBounds() const = 0;
|
||||||
virtual bool supportsGetProperty() const { return true; }
|
virtual bool supportsGetProperty() const { return true; }
|
||||||
|
|
||||||
|
@ -85,6 +89,8 @@ protected:
|
||||||
|
|
||||||
render::ItemID _renderItemID{ render::Item::INVALID_ITEM_ID };
|
render::ItemID _renderItemID{ render::Item::INVALID_ITEM_ID };
|
||||||
|
|
||||||
|
unsigned int _overlayID; // what Overlays.cpp knows this instance as
|
||||||
|
|
||||||
bool _isLoaded;
|
bool _isLoaded;
|
||||||
float _alpha;
|
float _alpha;
|
||||||
|
|
||||||
|
|
|
@ -192,6 +192,7 @@ unsigned int Overlays::addOverlay(const QString& type, const QVariant& propertie
|
||||||
unsigned int Overlays::addOverlay(Overlay::Pointer overlay) {
|
unsigned int Overlays::addOverlay(Overlay::Pointer overlay) {
|
||||||
QWriteLocker lock(&_lock);
|
QWriteLocker lock(&_lock);
|
||||||
unsigned int thisID = _nextOverlayID;
|
unsigned int thisID = _nextOverlayID;
|
||||||
|
overlay->setOverlayID(thisID);
|
||||||
_nextOverlayID++;
|
_nextOverlayID++;
|
||||||
if (overlay->is3D()) {
|
if (overlay->is3D()) {
|
||||||
_overlaysWorld[thisID] = overlay;
|
_overlaysWorld[thisID] = overlay;
|
||||||
|
|
|
@ -28,10 +28,10 @@ Planar3DOverlay::Planar3DOverlay(const Planar3DOverlay* planar3DOverlay) :
|
||||||
|
|
||||||
AABox Planar3DOverlay::getBounds() const {
|
AABox Planar3DOverlay::getBounds() const {
|
||||||
auto halfDimensions = glm::vec3{_dimensions / 2.0f, 0.01f};
|
auto halfDimensions = glm::vec3{_dimensions / 2.0f, 0.01f};
|
||||||
|
|
||||||
auto extents = Extents{-halfDimensions, halfDimensions};
|
auto extents = Extents{-halfDimensions, halfDimensions};
|
||||||
extents.transform(_transform);
|
extents.transform(getTransform());
|
||||||
|
|
||||||
return AABox(extents);
|
return AABox(extents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ void Sphere3DOverlay::render(RenderArgs* args) {
|
||||||
auto batch = args->_batch;
|
auto batch = args->_batch;
|
||||||
|
|
||||||
if (batch) {
|
if (batch) {
|
||||||
Transform transform = _transform;
|
Transform transform = getTransform();
|
||||||
transform.postScale(getDimensions() * SPHERE_OVERLAY_SCALE);
|
transform.postScale(getDimensions() * SPHERE_OVERLAY_SCALE);
|
||||||
batch->setModelTransform(transform);
|
batch->setModelTransform(transform);
|
||||||
|
|
||||||
|
|
|
@ -65,44 +65,49 @@ xColor Text3DOverlay::getBackgroundColor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Text3DOverlay::update(float deltatime) {
|
void Text3DOverlay::update(float deltatime) {
|
||||||
applyTransformTo(_transform);
|
if (usecTimestampNow() > _transformExpiry) {
|
||||||
|
Transform transform = getTransform();
|
||||||
|
applyTransformTo(transform);
|
||||||
|
setTransform(transform);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Text3DOverlay::render(RenderArgs* args) {
|
void Text3DOverlay::render(RenderArgs* args) {
|
||||||
if (!_visible || !getParentVisible()) {
|
if (!_visible || !getParentVisible()) {
|
||||||
return; // do nothing if we're not visible
|
return; // do nothing if we're not visible
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_ASSERT(args->_batch);
|
Q_ASSERT(args->_batch);
|
||||||
auto& batch = *args->_batch;
|
auto& batch = *args->_batch;
|
||||||
|
|
||||||
applyTransformTo(_transform, true);
|
Transform transform = getTransform();
|
||||||
batch.setModelTransform(_transform);
|
applyTransformTo(transform, true);
|
||||||
|
setTransform(transform);
|
||||||
|
batch.setModelTransform(transform);
|
||||||
|
|
||||||
const float MAX_COLOR = 255.0f;
|
const float MAX_COLOR = 255.0f;
|
||||||
xColor backgroundColor = getBackgroundColor();
|
xColor backgroundColor = getBackgroundColor();
|
||||||
glm::vec4 quadColor(backgroundColor.red / MAX_COLOR, backgroundColor.green / MAX_COLOR,
|
glm::vec4 quadColor(backgroundColor.red / MAX_COLOR, backgroundColor.green / MAX_COLOR,
|
||||||
backgroundColor.blue / MAX_COLOR, getBackgroundAlpha());
|
backgroundColor.blue / MAX_COLOR, getBackgroundAlpha());
|
||||||
|
|
||||||
glm::vec2 dimensions = getDimensions();
|
glm::vec2 dimensions = getDimensions();
|
||||||
glm::vec2 halfDimensions = dimensions * 0.5f;
|
glm::vec2 halfDimensions = dimensions * 0.5f;
|
||||||
|
|
||||||
const float SLIGHTLY_BEHIND = -0.001f;
|
const float SLIGHTLY_BEHIND = -0.001f;
|
||||||
|
|
||||||
glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, SLIGHTLY_BEHIND);
|
glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, SLIGHTLY_BEHIND);
|
||||||
glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, SLIGHTLY_BEHIND);
|
glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, SLIGHTLY_BEHIND);
|
||||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, quadColor);
|
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, quadColor);
|
||||||
|
|
||||||
// Same font properties as textSize()
|
// Same font properties as textSize()
|
||||||
float maxHeight = (float)_textRenderer->computeExtent("Xy").y * LINE_SCALE_RATIO;
|
float maxHeight = (float)_textRenderer->computeExtent("Xy").y * LINE_SCALE_RATIO;
|
||||||
|
|
||||||
float scaleFactor = (maxHeight / FIXED_FONT_SCALING_RATIO) * _lineHeight;
|
float scaleFactor = (maxHeight / FIXED_FONT_SCALING_RATIO) * _lineHeight;
|
||||||
|
|
||||||
glm::vec2 clipMinimum(0.0f, 0.0f);
|
glm::vec2 clipMinimum(0.0f, 0.0f);
|
||||||
glm::vec2 clipDimensions((dimensions.x - (_leftMargin + _rightMargin)) / scaleFactor,
|
glm::vec2 clipDimensions((dimensions.x - (_leftMargin + _rightMargin)) / scaleFactor,
|
||||||
(dimensions.y - (_topMargin + _bottomMargin)) / scaleFactor);
|
(dimensions.y - (_topMargin + _bottomMargin)) / scaleFactor);
|
||||||
|
|
||||||
Transform transform = _transform;
|
|
||||||
transform.postTranslate(glm::vec3(-(halfDimensions.x - _leftMargin),
|
transform.postTranslate(glm::vec3(-(halfDimensions.x - _leftMargin),
|
||||||
halfDimensions.y - _topMargin, 0.001f));
|
halfDimensions.y - _topMargin, 0.001f));
|
||||||
transform.setScale(scaleFactor);
|
transform.setScale(scaleFactor);
|
||||||
|
@ -222,6 +227,8 @@ QSizeF Text3DOverlay::textSize(const QString& text) const {
|
||||||
|
|
||||||
bool Text3DOverlay::findRayIntersection(const glm::vec3 &origin, const glm::vec3 &direction, float &distance,
|
bool Text3DOverlay::findRayIntersection(const glm::vec3 &origin, const glm::vec3 &direction, float &distance,
|
||||||
BoxFace &face, glm::vec3& surfaceNormal) {
|
BoxFace &face, glm::vec3& surfaceNormal) {
|
||||||
applyTransformTo(_transform, true);
|
Transform transform = getTransform();
|
||||||
|
applyTransformTo(transform, true);
|
||||||
|
setTransform(transform);
|
||||||
return Billboard3DOverlay::findRayIntersection(origin, direction, distance, face, surfaceNormal);
|
return Billboard3DOverlay::findRayIntersection(origin, direction, distance, face, surfaceNormal);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ bool Volume3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::ve
|
||||||
float& distance, BoxFace& face, glm::vec3& surfaceNormal) {
|
float& distance, BoxFace& face, glm::vec3& surfaceNormal) {
|
||||||
// extents is the entity relative, scaled, centered extents of the entity
|
// extents is the entity relative, scaled, centered extents of the entity
|
||||||
glm::mat4 worldToEntityMatrix;
|
glm::mat4 worldToEntityMatrix;
|
||||||
_transform.getInverseMatrix(worldToEntityMatrix);
|
getTransform().getInverseMatrix(worldToEntityMatrix);
|
||||||
|
|
||||||
glm::vec3 overlayFrameOrigin = glm::vec3(worldToEntityMatrix * glm::vec4(origin, 1.0f));
|
glm::vec3 overlayFrameOrigin = glm::vec3(worldToEntityMatrix * glm::vec4(origin, 1.0f));
|
||||||
glm::vec3 overlayFrameDirection = glm::vec3(worldToEntityMatrix * glm::vec4(direction, 0.0f));
|
glm::vec3 overlayFrameDirection = glm::vec3(worldToEntityMatrix * glm::vec4(direction, 0.0f));
|
||||||
|
|
|
@ -47,7 +47,7 @@ Web3DOverlay::~Web3DOverlay() {
|
||||||
_webSurface->disconnect(_connection);
|
_webSurface->disconnect(_connection);
|
||||||
// The lifetime of the QML surface MUST be managed by the main thread
|
// The lifetime of the QML surface MUST be managed by the main thread
|
||||||
// Additionally, we MUST use local variables copied by value, rather than
|
// Additionally, we MUST use local variables copied by value, rather than
|
||||||
// member variables, since they would implicitly refer to a this that
|
// member variables, since they would implicitly refer to a this that
|
||||||
// is no longer valid
|
// is no longer valid
|
||||||
auto webSurface = _webSurface;
|
auto webSurface = _webSurface;
|
||||||
AbstractViewStateInterface::instance()->postLambdaEvent([webSurface] {
|
AbstractViewStateInterface::instance()->postLambdaEvent([webSurface] {
|
||||||
|
@ -57,7 +57,11 @@ Web3DOverlay::~Web3DOverlay() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Web3DOverlay::update(float deltatime) {
|
void Web3DOverlay::update(float deltatime) {
|
||||||
applyTransformTo(_transform);
|
if (usecTimestampNow() > _transformExpiry) {
|
||||||
|
Transform transform = getTransform();
|
||||||
|
applyTransformTo(transform);
|
||||||
|
setTransform(transform);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Web3DOverlay::render(RenderArgs* args) {
|
void Web3DOverlay::render(RenderArgs* args) {
|
||||||
|
@ -85,8 +89,9 @@ void Web3DOverlay::render(RenderArgs* args) {
|
||||||
vec2 halfSize = size / 2.0f;
|
vec2 halfSize = size / 2.0f;
|
||||||
vec4 color(toGlm(getColor()), getAlpha());
|
vec4 color(toGlm(getColor()), getAlpha());
|
||||||
|
|
||||||
applyTransformTo(_transform, true);
|
Transform transform = getTransform();
|
||||||
Transform transform = _transform;
|
applyTransformTo(transform, true);
|
||||||
|
setTransform(transform);
|
||||||
if (glm::length2(getDimensions()) != 1.0f) {
|
if (glm::length2(getDimensions()) != 1.0f) {
|
||||||
transform.postScale(vec3(getDimensions(), 1.0f));
|
transform.postScale(vec3(getDimensions(), 1.0f));
|
||||||
}
|
}
|
||||||
|
@ -165,7 +170,10 @@ bool Web3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3&
|
||||||
// FIXME - face and surfaceNormal not being returned
|
// FIXME - face and surfaceNormal not being returned
|
||||||
|
|
||||||
// Make sure position and rotation is updated.
|
// Make sure position and rotation is updated.
|
||||||
applyTransformTo(_transform, true);
|
Transform transform;
|
||||||
|
applyTransformTo(transform, true);
|
||||||
|
setTransform(transform);
|
||||||
|
|
||||||
vec2 size = _resolution / _dpi * INCHES_TO_METERS * vec2(getDimensions());
|
vec2 size = _resolution / _dpi * INCHES_TO_METERS * vec2(getDimensions());
|
||||||
// Produce the dimensions of the overlay based on the image's aspect ratio and the overlay's scale.
|
// Produce the dimensions of the overlay based on the image's aspect ratio and the overlay's scale.
|
||||||
return findRayRectangleIntersection(origin, direction, getRotation(), getPosition(), size, distance);
|
return findRayRectangleIntersection(origin, direction, getRotation(), getPosition(), size, distance);
|
||||||
|
|
|
@ -322,10 +322,6 @@ public:
|
||||||
/// return preferred shape type (actual physical shape may differ)
|
/// return preferred shape type (actual physical shape may differ)
|
||||||
virtual ShapeType getShapeType() const { return SHAPE_TYPE_NONE; }
|
virtual ShapeType getShapeType() const { return SHAPE_TYPE_NONE; }
|
||||||
|
|
||||||
// these are only needed because the names don't match
|
|
||||||
virtual const glm::quat getRotation() const { return getOrientation(); }
|
|
||||||
virtual void setRotation(glm::quat orientation) { setOrientation(orientation); }
|
|
||||||
|
|
||||||
// updateFoo() methods to be used when changes need to be accumulated in the _dirtyFlags
|
// updateFoo() methods to be used when changes need to be accumulated in the _dirtyFlags
|
||||||
virtual void updateRegistrationPoint(const glm::vec3& value);
|
virtual void updateRegistrationPoint(const glm::vec3& value);
|
||||||
void updatePosition(const glm::vec3& value);
|
void updatePosition(const glm::vec3& value);
|
||||||
|
|
|
@ -26,6 +26,12 @@ SpatiallyNestable::SpatiallyNestable(NestableType nestableType, QUuid id) :
|
||||||
_transform.setRotation(glm::quat());
|
_transform.setRotation(glm::quat());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SpatiallyNestable::~SpatiallyNestable() {
|
||||||
|
forEachChild([&](SpatiallyNestablePointer object) {
|
||||||
|
object->parentDeleted();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const QUuid SpatiallyNestable::getID() const {
|
const QUuid SpatiallyNestable::getID() const {
|
||||||
QUuid result;
|
QUuid result;
|
||||||
_idLock.withReadLock([&] {
|
_idLock.withReadLock([&] {
|
||||||
|
@ -35,6 +41,10 @@ const QUuid SpatiallyNestable::getID() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpatiallyNestable::setID(const QUuid& id) {
|
void SpatiallyNestable::setID(const QUuid& id) {
|
||||||
|
// adjust the parentID of any children
|
||||||
|
forEachChild([&](SpatiallyNestablePointer object) {
|
||||||
|
object->setParentID(id);
|
||||||
|
});
|
||||||
_idLock.withWriteLock([&] {
|
_idLock.withWriteLock([&] {
|
||||||
_id = id;
|
_id = id;
|
||||||
});
|
});
|
||||||
|
@ -313,17 +323,20 @@ void SpatiallyNestable::setPosition(const glm::vec3& position, bool& success, bo
|
||||||
success = false;
|
success = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool changed = false;
|
||||||
Transform parentTransform = getParentTransform(success);
|
Transform parentTransform = getParentTransform(success);
|
||||||
Transform myWorldTransform;
|
Transform myWorldTransform;
|
||||||
_transformLock.withWriteLock([&] {
|
_transformLock.withWriteLock([&] {
|
||||||
Transform::mult(myWorldTransform, parentTransform, _transform);
|
Transform::mult(myWorldTransform, parentTransform, _transform);
|
||||||
myWorldTransform.setTranslation(position);
|
if (myWorldTransform.getTranslation() != position) {
|
||||||
Transform::inverseMult(_transform, parentTransform, myWorldTransform);
|
changed = true;
|
||||||
|
myWorldTransform.setTranslation(position);
|
||||||
|
Transform::inverseMult(_transform, parentTransform, myWorldTransform);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
if (success) {
|
if (success && changed) {
|
||||||
locationChanged(tellPhysics);
|
locationChanged(tellPhysics);
|
||||||
} else {
|
|
||||||
qDebug() << "setPosition failed for" << getID();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,14 +376,18 @@ void SpatiallyNestable::setOrientation(const glm::quat& orientation, bool& succe
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool changed = false;
|
||||||
Transform parentTransform = getParentTransform(success);
|
Transform parentTransform = getParentTransform(success);
|
||||||
Transform myWorldTransform;
|
Transform myWorldTransform;
|
||||||
_transformLock.withWriteLock([&] {
|
_transformLock.withWriteLock([&] {
|
||||||
Transform::mult(myWorldTransform, parentTransform, _transform);
|
Transform::mult(myWorldTransform, parentTransform, _transform);
|
||||||
myWorldTransform.setRotation(orientation);
|
if (myWorldTransform.getRotation() != orientation) {
|
||||||
Transform::inverseMult(_transform, parentTransform, myWorldTransform);
|
changed = true;
|
||||||
|
myWorldTransform.setRotation(orientation);
|
||||||
|
Transform::inverseMult(_transform, parentTransform, myWorldTransform);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
if (success) {
|
if (success && changed) {
|
||||||
locationChanged(tellPhysics);
|
locationChanged(tellPhysics);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -513,6 +530,15 @@ const Transform SpatiallyNestable::getTransform(bool& success, int depth) const
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Transform SpatiallyNestable::getTransform() const {
|
||||||
|
bool success;
|
||||||
|
Transform result = getTransform(success);
|
||||||
|
if (!success) {
|
||||||
|
qDebug() << "getTransform failed for" << getID();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
const Transform SpatiallyNestable::getTransform(int jointIndex, bool& success, int depth) const {
|
const Transform SpatiallyNestable::getTransform(int jointIndex, bool& success, int depth) const {
|
||||||
// this returns the world-space transform for this object. It finds its parent's transform (which may
|
// this returns the world-space transform for this object. It finds its parent's transform (which may
|
||||||
// cause this object's parent to query its parent, etc) and multiplies this object's local transform onto it.
|
// cause this object's parent to query its parent, etc) and multiplies this object's local transform onto it.
|
||||||
|
@ -549,15 +575,27 @@ void SpatiallyNestable::setTransform(const Transform& transform, bool& success)
|
||||||
success = false;
|
success = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool changed = false;
|
||||||
Transform parentTransform = getParentTransform(success);
|
Transform parentTransform = getParentTransform(success);
|
||||||
_transformLock.withWriteLock([&] {
|
_transformLock.withWriteLock([&] {
|
||||||
|
Transform beforeTransform = _transform;
|
||||||
Transform::inverseMult(_transform, parentTransform, transform);
|
Transform::inverseMult(_transform, parentTransform, transform);
|
||||||
|
if (_transform != beforeTransform) {
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
if (success) {
|
if (success && changed) {
|
||||||
locationChanged();
|
locationChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SpatiallyNestable::setTransform(const Transform& transform) {
|
||||||
|
bool success;
|
||||||
|
setTransform(transform, success);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
glm::vec3 SpatiallyNestable::getScale() const {
|
glm::vec3 SpatiallyNestable::getScale() const {
|
||||||
// TODO: scale
|
// TODO: scale
|
||||||
glm::vec3 result;
|
glm::vec3 result;
|
||||||
|
@ -575,14 +613,43 @@ glm::vec3 SpatiallyNestable::getScale(int jointIndex) const {
|
||||||
void SpatiallyNestable::setScale(const glm::vec3& scale) {
|
void SpatiallyNestable::setScale(const glm::vec3& scale) {
|
||||||
// guard against introducing NaN into the transform
|
// guard against introducing NaN into the transform
|
||||||
if (isNaN(scale)) {
|
if (isNaN(scale)) {
|
||||||
qDebug() << "SpatiallyNestable::setLocalScale -- scale contains NaN";
|
qDebug() << "SpatiallyNestable::setScale -- scale contains NaN";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool changed = false;
|
||||||
// TODO: scale
|
// TODO: scale
|
||||||
_transformLock.withWriteLock([&] {
|
_transformLock.withWriteLock([&] {
|
||||||
_transform.setScale(scale);
|
if (_transform.getScale() != scale) {
|
||||||
|
_transform.setScale(scale);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
dimensionsChanged();
|
if (changed) {
|
||||||
|
dimensionsChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpatiallyNestable::setScale(float value) {
|
||||||
|
// guard against introducing NaN into the transform
|
||||||
|
if (value <= 0.0f) {
|
||||||
|
qDebug() << "SpatiallyNestable::setScale -- scale is zero or negative value";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool changed = false;
|
||||||
|
// TODO: scale
|
||||||
|
_transformLock.withWriteLock([&] {
|
||||||
|
glm::vec3 beforeScale = _transform.getScale();
|
||||||
|
_transform.setScale(value);
|
||||||
|
if (_transform.getScale() != beforeScale) {
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
dimensionsChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Transform SpatiallyNestable::getLocalTransform() const {
|
const Transform SpatiallyNestable::getLocalTransform() const {
|
||||||
|
@ -599,10 +666,18 @@ void SpatiallyNestable::setLocalTransform(const Transform& transform) {
|
||||||
qDebug() << "SpatiallyNestable::setLocalTransform -- transform contains NaN";
|
qDebug() << "SpatiallyNestable::setLocalTransform -- transform contains NaN";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool changed = false;
|
||||||
_transformLock.withWriteLock([&] {
|
_transformLock.withWriteLock([&] {
|
||||||
_transform = transform;
|
if (_transform != transform) {
|
||||||
|
_transform = transform;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
locationChanged();
|
|
||||||
|
if (changed) {
|
||||||
|
locationChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 SpatiallyNestable::getLocalPosition() const {
|
glm::vec3 SpatiallyNestable::getLocalPosition() const {
|
||||||
|
@ -619,10 +694,16 @@ void SpatiallyNestable::setLocalPosition(const glm::vec3& position, bool tellPhy
|
||||||
qDebug() << "SpatiallyNestable::setLocalPosition -- position contains NaN";
|
qDebug() << "SpatiallyNestable::setLocalPosition -- position contains NaN";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
bool changed = false;
|
||||||
_transformLock.withWriteLock([&] {
|
_transformLock.withWriteLock([&] {
|
||||||
_transform.setTranslation(position);
|
if (_transform.getTranslation() != position) {
|
||||||
|
_transform.setTranslation(position);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
locationChanged(tellPhysics);
|
if (changed) {
|
||||||
|
locationChanged(tellPhysics);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::quat SpatiallyNestable::getLocalOrientation() const {
|
glm::quat SpatiallyNestable::getLocalOrientation() const {
|
||||||
|
@ -639,10 +720,16 @@ void SpatiallyNestable::setLocalOrientation(const glm::quat& orientation) {
|
||||||
qDebug() << "SpatiallyNestable::setLocalOrientation -- orientation contains NaN";
|
qDebug() << "SpatiallyNestable::setLocalOrientation -- orientation contains NaN";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
bool changed = false;
|
||||||
_transformLock.withWriteLock([&] {
|
_transformLock.withWriteLock([&] {
|
||||||
_transform.setRotation(orientation);
|
if (_transform.getRotation() != orientation) {
|
||||||
|
_transform.setRotation(orientation);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
locationChanged();
|
if (changed) {
|
||||||
|
locationChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 SpatiallyNestable::getLocalVelocity() const {
|
glm::vec3 SpatiallyNestable::getLocalVelocity() const {
|
||||||
|
@ -688,9 +775,14 @@ void SpatiallyNestable::setLocalScale(const glm::vec3& scale) {
|
||||||
qDebug() << "SpatiallyNestable::setLocalScale -- scale contains NaN";
|
qDebug() << "SpatiallyNestable::setLocalScale -- scale contains NaN";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool changed = false;
|
||||||
// TODO: scale
|
// TODO: scale
|
||||||
_transformLock.withWriteLock([&] {
|
_transformLock.withWriteLock([&] {
|
||||||
_transform.setScale(scale);
|
if (_transform.getScale() != scale) {
|
||||||
|
_transform.setScale(scale);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
dimensionsChanged();
|
dimensionsChanged();
|
||||||
}
|
}
|
||||||
|
@ -886,12 +978,18 @@ void SpatiallyNestable::getLocalTransformAndVelocities(
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpatiallyNestable::setLocalTransformAndVelocities(
|
void SpatiallyNestable::setLocalTransformAndVelocities(
|
||||||
const Transform& localTransform,
|
const Transform& localTransform,
|
||||||
const glm::vec3& localVelocity,
|
const glm::vec3& localVelocity,
|
||||||
const glm::vec3& localAngularVelocity) {
|
const glm::vec3& localAngularVelocity) {
|
||||||
|
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
// transform
|
// transform
|
||||||
_transformLock.withWriteLock([&] {
|
_transformLock.withWriteLock([&] {
|
||||||
_transform = localTransform;
|
if (_transform != localTransform) {
|
||||||
|
_transform = localTransform;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
// linear velocity
|
// linear velocity
|
||||||
_velocityLock.withWriteLock([&] {
|
_velocityLock.withWriteLock([&] {
|
||||||
|
@ -901,5 +999,8 @@ void SpatiallyNestable::setLocalTransformAndVelocities(
|
||||||
_angularVelocityLock.withWriteLock([&] {
|
_angularVelocityLock.withWriteLock([&] {
|
||||||
_angularVelocity = localAngularVelocity;
|
_angularVelocity = localAngularVelocity;
|
||||||
});
|
});
|
||||||
locationChanged(false);
|
|
||||||
|
if (changed) {
|
||||||
|
locationChanged(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,13 +28,14 @@ using SpatiallyNestableConstPointer = std::shared_ptr<const SpatiallyNestable>;
|
||||||
|
|
||||||
enum class NestableType {
|
enum class NestableType {
|
||||||
Entity,
|
Entity,
|
||||||
Avatar
|
Avatar,
|
||||||
|
Overlay
|
||||||
};
|
};
|
||||||
|
|
||||||
class SpatiallyNestable : public std::enable_shared_from_this<SpatiallyNestable> {
|
class SpatiallyNestable : public std::enable_shared_from_this<SpatiallyNestable> {
|
||||||
public:
|
public:
|
||||||
SpatiallyNestable(NestableType nestableType, QUuid id);
|
SpatiallyNestable(NestableType nestableType, QUuid id);
|
||||||
virtual ~SpatiallyNestable() { }
|
virtual ~SpatiallyNestable();
|
||||||
|
|
||||||
virtual const QUuid getID() const;
|
virtual const QUuid getID() const;
|
||||||
virtual void setID(const QUuid& id);
|
virtual void setID(const QUuid& id);
|
||||||
|
@ -53,7 +54,9 @@ public:
|
||||||
|
|
||||||
// world frame
|
// world frame
|
||||||
virtual const Transform getTransform(bool& success, int depth = 0) const;
|
virtual const Transform getTransform(bool& success, int depth = 0) const;
|
||||||
|
virtual const Transform getTransform() const;
|
||||||
virtual void setTransform(const Transform& transform, bool& success);
|
virtual void setTransform(const Transform& transform, bool& success);
|
||||||
|
virtual bool setTransform(const Transform& transform);
|
||||||
|
|
||||||
virtual Transform getParentTransform(bool& success, int depth = 0) const;
|
virtual Transform getParentTransform(bool& success, int depth = 0) const;
|
||||||
|
|
||||||
|
@ -68,6 +71,10 @@ public:
|
||||||
virtual void setOrientation(const glm::quat& orientation, bool& success, bool tellPhysics = true);
|
virtual void setOrientation(const glm::quat& orientation, bool& success, bool tellPhysics = true);
|
||||||
virtual void setOrientation(const glm::quat& orientation);
|
virtual void setOrientation(const glm::quat& orientation);
|
||||||
|
|
||||||
|
// these are here because some older code uses rotation rather than orientation
|
||||||
|
virtual const glm::quat getRotation() const { return getOrientation(); }
|
||||||
|
virtual void setRotation(glm::quat orientation) { setOrientation(orientation); }
|
||||||
|
|
||||||
virtual glm::vec3 getVelocity(bool& success) const;
|
virtual glm::vec3 getVelocity(bool& success) const;
|
||||||
virtual glm::vec3 getVelocity() const;
|
virtual glm::vec3 getVelocity() const;
|
||||||
virtual void setVelocity(const glm::vec3& velocity, bool& success);
|
virtual void setVelocity(const glm::vec3& velocity, bool& success);
|
||||||
|
@ -91,6 +98,7 @@ public:
|
||||||
|
|
||||||
virtual glm::vec3 getScale() const;
|
virtual glm::vec3 getScale() const;
|
||||||
virtual void setScale(const glm::vec3& scale);
|
virtual void setScale(const glm::vec3& scale);
|
||||||
|
virtual void setScale(float value);
|
||||||
|
|
||||||
// get world-frame values for a specific joint
|
// get world-frame values for a specific joint
|
||||||
virtual const Transform getTransform(int jointIndex, bool& success, int depth = 0) const;
|
virtual const Transform getTransform(int jointIndex, bool& success, int depth = 0) const;
|
||||||
|
@ -123,10 +131,10 @@ public:
|
||||||
|
|
||||||
// this object's frame
|
// this object's frame
|
||||||
virtual const Transform getAbsoluteJointTransformInObjectFrame(int jointIndex) const;
|
virtual const Transform getAbsoluteJointTransformInObjectFrame(int jointIndex) const;
|
||||||
virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const = 0;
|
virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const { return glm::quat(); }
|
||||||
virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const = 0;
|
virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const { return glm::vec3(); }
|
||||||
virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) = 0;
|
virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) { return false; }
|
||||||
virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) = 0;
|
virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) {return false; }
|
||||||
|
|
||||||
SpatiallyNestablePointer getThisPointer() const;
|
SpatiallyNestablePointer getThisPointer() const;
|
||||||
|
|
||||||
|
@ -170,6 +178,7 @@ protected:
|
||||||
|
|
||||||
virtual void locationChanged(bool tellPhysics = true); // called when a this object's location has changed
|
virtual void locationChanged(bool tellPhysics = true); // called when a this object's location has changed
|
||||||
virtual void dimensionsChanged() { } // called when a this object's dimensions have changed
|
virtual void dimensionsChanged() { } // called when a this object's dimensions have changed
|
||||||
|
virtual void parentDeleted() { } // called on children of a deleted parent
|
||||||
|
|
||||||
// _queryAACube is used to decide where something lives in the octree
|
// _queryAACube is used to decide where something lives in the octree
|
||||||
mutable AACube _queryAACube;
|
mutable AACube _queryAACube;
|
||||||
|
|
|
@ -89,6 +89,10 @@ public:
|
||||||
return _rotation == other._rotation && _scale == other._scale && _translation == other._translation;
|
return _rotation == other._rotation && _scale == other._scale && _translation == other._translation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator!=(const Transform& other) const {
|
||||||
|
return _rotation != other._rotation || _scale != other._scale || _translation != other._translation;
|
||||||
|
}
|
||||||
|
|
||||||
Transform& setIdentity();
|
Transform& setIdentity();
|
||||||
|
|
||||||
const Vec3& getTranslation() const;
|
const Vec3& getTranslation() const;
|
||||||
|
|
Loading…
Reference in a new issue