Merge branch 'master' of https://github.com/highfidelity/hifi into blue

This commit is contained in:
samcake 2018-01-03 11:12:16 -08:00
commit ac0cca5345
47 changed files with 710 additions and 176 deletions

4
.gitignore vendored
View file

@ -20,7 +20,7 @@ android/.gradle
android/app/src/main/jniLibs android/app/src/main/jniLibs
# VSCode # VSCode
# List taken from Github Global Ignores master@435c4d92 # List taken from Github Global Ignores master@435c4d92
# https://github.com/github/gitignore/commits/master/Global/VisualStudioCode.gitignore # https://github.com/github/gitignore/commits/master/Global/VisualStudioCode.gitignore
.vscode/* .vscode/*
!.vscode/settings.json !.vscode/settings.json
@ -66,7 +66,7 @@ gvr-interface/libs/*
# ignore files for various dev environments # ignore files for various dev environments
TAGS TAGS
*.sw[po] *.sw[po]
*.qmlc *.jsc
# ignore QML compilation output # ignore QML compilation output
*.qmlc *.qmlc

View file

@ -197,14 +197,36 @@ Item {
anchors.topMargin: 26; anchors.topMargin: 26;
anchors.left: parent.left; anchors.left: parent.left;
anchors.leftMargin: 20; anchors.leftMargin: 20;
anchors.right: parent.right; width: paintedWidth;
anchors.rightMargin: 30;
height: 30; height: 30;
// Text size // Text size
size: 22; size: 22;
// Style // Style
color: hifi.colors.baseGrayHighlight; color: hifi.colors.baseGrayHighlight;
} }
RalewaySemiBold {
id: myPurchasesLink;
text: '<font color="#0093C5"><a href="#myPurchases">My Purchases</a></font>';
// Anchors
anchors.top: parent.top;
anchors.topMargin: 26;
anchors.right: parent.right;
anchors.rightMargin: 20;
width: paintedWidth;
height: 30;
y: 4;
// Text size
size: 18;
// Style
color: hifi.colors.baseGrayHighlight;
horizontalAlignment: Text.AlignRight;
onLinkActivated: {
sendSignalToWallet({method: 'goToPurchases_fromWalletHome'});
}
}
ListModel { ListModel {
id: tempTransactionHistoryModel; id: tempTransactionHistoryModel;
} }

Binary file not shown.

View file

@ -191,6 +191,7 @@
#include <GPUIdent.h> #include <GPUIdent.h>
#include <gl/GLHelpers.h> #include <gl/GLHelpers.h>
#include <src/scripting/LimitlessVoiceRecognitionScriptingInterface.h> #include <src/scripting/LimitlessVoiceRecognitionScriptingInterface.h>
#include <src/scripting/GooglePolyScriptingInterface.h>
#include <EntityScriptClient.h> #include <EntityScriptClient.h>
#include <ModelScriptingInterface.h> #include <ModelScriptingInterface.h>
@ -698,6 +699,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
DependencyManager::set<EntityScriptClient>(); DependencyManager::set<EntityScriptClient>();
DependencyManager::set<EntityScriptServerLogClient>(); DependencyManager::set<EntityScriptServerLogClient>();
DependencyManager::set<LimitlessVoiceRecognitionScriptingInterface>(); DependencyManager::set<LimitlessVoiceRecognitionScriptingInterface>();
DependencyManager::set<GooglePolyScriptingInterface>();
DependencyManager::set<OctreeStatsProvider>(nullptr, qApp->getOcteeSceneStats()); DependencyManager::set<OctreeStatsProvider>(nullptr, qApp->getOcteeSceneStats());
DependencyManager::set<AvatarBookmarks>(); DependencyManager::set<AvatarBookmarks>();
DependencyManager::set<LocationBookmarks>(); DependencyManager::set<LocationBookmarks>();
@ -4279,7 +4281,7 @@ void Application::init() {
getEntities()->init(); getEntities()->init();
getEntities()->setEntityLoadingPriorityFunction([this](const EntityItem& item) { getEntities()->setEntityLoadingPriorityFunction([this](const EntityItem& item) {
auto dims = item.getDimensions(); auto dims = item.getScaledDimensions();
auto maxSize = glm::compMax(dims); auto maxSize = glm::compMax(dims);
if (maxSize <= 0.0f) { if (maxSize <= 0.0f) {
@ -4633,7 +4635,7 @@ void Application::setKeyboardFocusEntity(const EntityItemID& entityItemID) {
_lastAcceptedKeyPress = usecTimestampNow(); _lastAcceptedKeyPress = usecTimestampNow();
setKeyboardFocusHighlight(entity->getWorldPosition(), entity->getWorldOrientation(), setKeyboardFocusHighlight(entity->getWorldPosition(), entity->getWorldOrientation(),
entity->getDimensions() * FOCUS_HIGHLIGHT_EXPANSION_FACTOR); entity->getScaledDimensions() * FOCUS_HIGHLIGHT_EXPANSION_FACTOR);
} }
} }
} }
@ -5941,6 +5943,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe
scriptEngine->registerGlobalObject("Users", DependencyManager::get<UsersScriptingInterface>().data()); scriptEngine->registerGlobalObject("Users", DependencyManager::get<UsersScriptingInterface>().data());
scriptEngine->registerGlobalObject("LimitlessSpeechRecognition", DependencyManager::get<LimitlessVoiceRecognitionScriptingInterface>().data()); scriptEngine->registerGlobalObject("LimitlessSpeechRecognition", DependencyManager::get<LimitlessVoiceRecognitionScriptingInterface>().data());
scriptEngine->registerGlobalObject("GooglePoly", DependencyManager::get<GooglePolyScriptingInterface>().data());
if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) { if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {
scriptEngine->registerGlobalObject("Steam", new SteamScriptingInterface(scriptEngine.data(), steamClient.get())); scriptEngine->registerGlobalObject("Steam", new SteamScriptingInterface(scriptEngine.data(), steamClient.get()));

View file

@ -407,7 +407,7 @@ void shapeInfoCalculator(const ShapeEntityItem * const shapeEntity, ShapeInfo &s
ShapeInfo::PointList points; ShapeInfo::PointList points;
pointCollection.push_back(points); pointCollection.push_back(points);
GeometryCache::computeSimpleHullPointListForShape((int)shapeEntity->getShape(), shapeEntity->getDimensions(), pointCollection.back()); GeometryCache::computeSimpleHullPointListForShape((int)shapeEntity->getShape(), shapeEntity->getScaledDimensions(), pointCollection.back());
shapeInfo.setPointCollection(pointCollection); shapeInfo.setPointCollection(pointCollection);
} }

View file

@ -0,0 +1,181 @@
//
// GooglePolyScriptingInterface.cpp
// interface/src/scripting
//
// Created by Elisa Lupin-Jimenez on 12/3/2017.
// Copyright 2017 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 <QEventLoop>
#include <QtGlobal>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QString>
#include <QTime>
#include <QUrl>
#include <random>
#include "GooglePolyScriptingInterface.h"
#include "ScriptEngineLogging.h"
const QString LIST_POLY_URL = "https://poly.googleapis.com/v1/assets?";
const QString GET_POLY_URL = "https://poly.googleapis.com/v1/assets/model?";
const QStringList VALID_FORMATS = QStringList() << "BLOCKS" << "FBX" << "GLTF" << "GLTF2" << "OBJ" << "TILT" << "";
const QStringList VALID_CATEGORIES = QStringList() << "animals" << "architecture" << "art" << "food" <<
"nature" << "objects" << "people" << "scenes" << "technology" << "transport" << "";
GooglePolyScriptingInterface::GooglePolyScriptingInterface() {
// nothing to be implemented
}
void GooglePolyScriptingInterface::setAPIKey(const QString& key) {
_authCode = key;
}
QString GooglePolyScriptingInterface::getAssetList(const QString& keyword, const QString& category, const QString& format) {
QUrl url = formatURLQuery(keyword, category, format);
if (!url.isEmpty()) {
QByteArray json = parseJSON(url, 0).toJsonDocument().toJson();
return (QString) json;
} else {
qCDebug(scriptengine) << "Invalid filters were specified.";
return "";
}
}
QString GooglePolyScriptingInterface::getFBX(const QString& keyword, const QString& category) {
QUrl url = formatURLQuery(keyword, category, "FBX");
return getModelURL(url);
}
QString GooglePolyScriptingInterface::getOBJ(const QString& keyword, const QString& category) {
QUrl url = formatURLQuery(keyword, category, "OBJ");
return getModelURL(url);
}
QString GooglePolyScriptingInterface::getBlocks(const QString& keyword, const QString& category) {
QUrl url = formatURLQuery(keyword, category, "BLOCKS");
return getModelURL(url);
}
QString GooglePolyScriptingInterface::getGLTF(const QString& keyword, const QString& category) {
QUrl url = formatURLQuery(keyword, category, "GLTF");
return getModelURL(url);
}
QString GooglePolyScriptingInterface::getGLTF2(const QString& keyword, const QString& category) {
QUrl url = formatURLQuery(keyword, category, "GLTF2");
return getModelURL(url);
}
// This method will not be useful until we support Tilt models
QString GooglePolyScriptingInterface::getTilt(const QString& keyword, const QString& category) {
QUrl url = formatURLQuery(keyword, category, "TILT");
return getModelURL(url);
}
// Can provide asset name or full URL to model
QString GooglePolyScriptingInterface::getModelInfo(const QString& input) {
QString name(input);
if (input.contains("poly.googleapis") || input.contains("poly.google.com")) {
QStringList list = input.split("/");
if (input.contains("poly.googleapis")) {
name = list[4];
} else {
name = list.last();
}
}
QString urlString(GET_POLY_URL);
urlString = urlString.replace("model", name) + "key=" + _authCode;
qCDebug(scriptengine) << "Google URL request: " << urlString;
QUrl url(urlString);
QString json = parseJSON(url, 2).toString();
return json;
}
int GooglePolyScriptingInterface::getRandIntInRange(int length) {
QTime time = QTime::currentTime();
qsrand((uint)time.msec());
return qrand() % length;
}
QUrl GooglePolyScriptingInterface::formatURLQuery(const QString& keyword, const QString& category, const QString& format) {
QString queries;
if (!VALID_FORMATS.contains(format, Qt::CaseInsensitive) || !VALID_CATEGORIES.contains(category, Qt::CaseInsensitive)) {
return QUrl("");
} else {
if (!keyword.isEmpty()) {
QString keywords(keyword);
keywords.replace(" ", "+");
queries.append("&keywords=" + keywords);
}
if (!category.isEmpty()) {
queries.append("&category=" + category);
}
if (!format.isEmpty()) {
queries.append("&format=" + format);
}
QString urlString(LIST_POLY_URL + "key=" + _authCode + queries);
return QUrl(urlString);
}
}
QString GooglePolyScriptingInterface::getModelURL(const QUrl& url) {
qCDebug(scriptengine) << "Google URL request: " << url;
if (!url.isEmpty()) {
return parseJSON(url, 1).toString();
} else {
qCDebug(scriptengine) << "Invalid filters were specified.";
return "";
}
}
// FIXME: synchronous
QByteArray GooglePolyScriptingInterface::getHTTPRequest(const QUrl& url) {
QNetworkAccessManager manager;
QNetworkReply *response = manager.get(QNetworkRequest(url));
QEventLoop event;
connect(response, SIGNAL(finished()), &event, SLOT(quit()));
event.exec();
return response->readAll();
}
// 0 = asset list, 1 = model from asset list, 2 = specific model
QVariant GooglePolyScriptingInterface::parseJSON(const QUrl& url, int fileType) {
QByteArray jsonString = getHTTPRequest(url);
QJsonDocument doc = QJsonDocument::fromJson(jsonString);
QJsonObject obj = doc.object();
if (obj.isEmpty()) {
qCDebug(scriptengine) << "Assets with specified filters not found";
return "";
}
if (obj.keys().first() == "error") {
QString error = obj.value("error").toObject().value("message").toString();
qCDebug(scriptengine) << error;
return "";
}
if (fileType == 0 || fileType == 1) {
QJsonArray arr = obj.value("assets").toArray();
// return model url
if (fileType == 1) {
int random = getRandIntInRange(arr.size());
QJsonObject json = arr.at(random).toObject();
// nested JSONs
return json.value("formats").toArray().at(0).toObject().value("root").toObject().value("url");
}
// return whole asset list
return QJsonDocument(arr);
// return specific object
} else {
return jsonString;
}
}

View file

@ -0,0 +1,47 @@
//
// GooglePolyScriptingInterface.h
// interface/src/scripting
//
// Created by Elisa Lupin-Jimenez on 12/3/2017.
// Copyright 2017 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_GooglePolyScriptingInterface_h
#define hifi_GooglePolyScriptingInterface_h
#include <QObject>
#include <DependencyManager.h>
class GooglePolyScriptingInterface : public QObject, public Dependency {
Q_OBJECT
public:
GooglePolyScriptingInterface();
public slots:
void setAPIKey(const QString& key);
QString getAssetList(const QString& keyword, const QString& category, const QString& format);
QString getFBX(const QString& keyword, const QString& category);
QString getOBJ(const QString& keyword, const QString& category);
QString getBlocks(const QString& keyword, const QString& categoryy);
QString getGLTF(const QString& keyword, const QString& category);
QString getGLTF2(const QString& keyword, const QString& category);
QString getTilt(const QString& keyword, const QString& category);
QString getModelInfo(const QString& input);
private:
QString _authCode;
QUrl formatURLQuery(const QString& keyword, const QString& category, const QString& format);
QString getModelURL(const QUrl& url);
QByteArray getHTTPRequest(const QUrl& url);
QVariant parseJSON(const QUrl& url, int fileType);
int getRandIntInRange(int length);
};
#endif // hifi_GooglePolyScriptingInterface_h

View file

@ -42,7 +42,7 @@ Base3DOverlay::Base3DOverlay(const Base3DOverlay* base3DOverlay) :
setTransform(base3DOverlay->getTransform()); setTransform(base3DOverlay->getTransform());
} }
QVariantMap convertOverlayLocationFromScriptSemantics(const QVariantMap& properties) { QVariantMap convertOverlayLocationFromScriptSemantics(const QVariantMap& properties, bool scalesWithParent) {
// the position and rotation in _transform are relative to the parent (aka local). The versions coming from // 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 // 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. // so that "position" and "rotation" are relative-to-parent values.
@ -56,7 +56,7 @@ QVariantMap convertOverlayLocationFromScriptSemantics(const QVariantMap& propert
result["position"] = result["localPosition"]; result["position"] = result["localPosition"];
} else if (result["position"].isValid()) { } else if (result["position"].isValid()) {
glm::vec3 localPosition = SpatiallyNestable::worldToLocal(vec3FromVariant(result["position"]), glm::vec3 localPosition = SpatiallyNestable::worldToLocal(vec3FromVariant(result["position"]),
parentID, parentJointIndex, success); parentID, parentJointIndex, scalesWithParent, success);
if (success) { if (success) {
result["position"] = vec3toVariant(localPosition); result["position"] = vec3toVariant(localPosition);
} }
@ -66,7 +66,7 @@ QVariantMap convertOverlayLocationFromScriptSemantics(const QVariantMap& propert
result["orientation"] = result["localOrientation"]; result["orientation"] = result["localOrientation"];
} else if (result["orientation"].isValid()) { } else if (result["orientation"].isValid()) {
glm::quat localOrientation = SpatiallyNestable::worldToLocal(quatFromVariant(result["orientation"]), glm::quat localOrientation = SpatiallyNestable::worldToLocal(quatFromVariant(result["orientation"]),
parentID, parentJointIndex, success); parentID, parentJointIndex, scalesWithParent, success);
if (success) { if (success) {
result["orientation"] = quatToVariant(localOrientation); result["orientation"] = quatToVariant(localOrientation);
} }
@ -118,7 +118,7 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) {
} }
} }
properties = convertOverlayLocationFromScriptSemantics(properties); properties = convertOverlayLocationFromScriptSemantics(properties, getScalesWithParent());
Overlay::setProperties(properties); Overlay::setProperties(properties);
bool needRenderItemUpdate = false; bool needRenderItemUpdate = false;
@ -335,4 +335,4 @@ SpatialParentTree* Base3DOverlay::getParentTree() const {
void Base3DOverlay::setVisible(bool visible) { void Base3DOverlay::setVisible(bool visible) {
Parent::setVisible(visible); Parent::setVisible(visible);
notifyRenderVariableChange(); notifyRenderVariableChange();
} }

View file

@ -56,12 +56,12 @@ glm::vec3 Line3DOverlay::getEnd() const {
if (_endParentID != QUuid()) { if (_endParentID != QUuid()) {
glm::vec3 localOffset = _direction * _length; glm::vec3 localOffset = _direction * _length;
bool success; bool success;
worldEnd = localToWorld(localOffset, _endParentID, _endParentJointIndex, success); worldEnd = localToWorld(localOffset, _endParentID, _endParentJointIndex, getScalesWithParent(), success);
return worldEnd; return worldEnd;
} }
localEnd = getLocalEnd(); localEnd = getLocalEnd();
worldEnd = localToWorld(localEnd, getParentID(), getParentJointIndex(), success); worldEnd = localToWorld(localEnd, getParentID(), getParentJointIndex(), getScalesWithParent(), success);
if (!success) { if (!success) {
qDebug() << "Line3DOverlay::getEnd failed"; qDebug() << "Line3DOverlay::getEnd failed";
} }
@ -79,10 +79,10 @@ void Line3DOverlay::setEnd(const glm::vec3& end) {
glm::vec3 offset; glm::vec3 offset;
if (_endParentID != QUuid()) { if (_endParentID != QUuid()) {
offset = worldToLocal(end, _endParentID, _endParentJointIndex, success); offset = worldToLocal(end, _endParentID, _endParentJointIndex, getScalesWithParent(), success);
} else { } else {
localStart = getLocalStart(); localStart = getLocalStart();
localEnd = worldToLocal(end, getParentID(), getParentJointIndex(), success); localEnd = worldToLocal(end, getParentID(), getParentJointIndex(), getScalesWithParent(), success);
offset = localEnd - localStart; offset = localEnd - localStart;
} }
if (!success) { if (!success) {

View file

@ -268,6 +268,7 @@ public:
virtual float getModelScale() const { return _modelScale; } virtual float getModelScale() const { return _modelScale; }
virtual void setModelScale(float scale) { _modelScale = scale; } virtual void setModelScale(float scale) { _modelScale = scale; }
virtual glm::vec3 scaleForChildren() const override { return glm::vec3(getModelScale()); }
virtual void setAvatarEntityDataChanged(bool value) override; virtual void setAvatarEntityDataChanged(bool value) override;

View file

@ -612,7 +612,7 @@ static glm::vec2 projectOntoEntityXYPlane(EntityItemPointer entity, const PickRa
glm::vec3 entityPosition = entity->getWorldPosition(); glm::vec3 entityPosition = entity->getWorldPosition();
glm::quat entityRotation = entity->getWorldOrientation(); glm::quat entityRotation = entity->getWorldOrientation();
glm::vec3 entityDimensions = entity->getDimensions(); glm::vec3 entityDimensions = entity->getScaledDimensions();
glm::vec3 entityRegistrationPoint = entity->getRegistrationPoint(); glm::vec3 entityRegistrationPoint = entity->getRegistrationPoint();
// project the intersection point onto the local xy plane of the object. // project the intersection point onto the local xy plane of the object.

View file

@ -37,7 +37,7 @@ void LightEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint
lightPayload.editBound() = render::Item::Bound(); lightPayload.editBound() = render::Item::Bound();
} }
glm::vec3 dimensions = entity->getDimensions(); glm::vec3 dimensions = entity->getScaledDimensions();
float largestDiameter = glm::compMax(dimensions); float largestDiameter = glm::compMax(dimensions);
light->setMaximumRadius(largestDiameter / 2.0f); light->setMaximumRadius(largestDiameter / 2.0f);

View file

@ -78,11 +78,11 @@ RenderableModelEntityItem::RenderableModelEntityItem(const EntityItemID& entityI
RenderableModelEntityItem::~RenderableModelEntityItem() { } RenderableModelEntityItem::~RenderableModelEntityItem() { }
void RenderableModelEntityItem::setDimensions(const glm::vec3& value) { void RenderableModelEntityItem::setUnscaledDimensions(const glm::vec3& value) {
glm::vec3 newDimensions = glm::max(value, glm::vec3(0.0f)); // can never have negative dimensions glm::vec3 newDimensions = glm::max(value, glm::vec3(0.0f)); // can never have negative dimensions
if (getDimensions() != newDimensions) { if (getUnscaledDimensions() != newDimensions) {
_dimensionsInitialized = true; _dimensionsInitialized = true;
ModelEntityItem::setDimensions(value); ModelEntityItem::setUnscaledDimensions(value);
} }
} }
@ -124,11 +124,11 @@ void RenderableModelEntityItem::doInitialModelSimulation() {
// translation/rotation/scale/registration. The first two are straightforward, but the latter two have guards to // translation/rotation/scale/registration. The first two are straightforward, but the latter two have guards to
// make sure they don't happen after they've already been set. Here we reset those guards. This doesn't cause the // make sure they don't happen after they've already been set. Here we reset those guards. This doesn't cause the
// entity values to change -- it just allows the model to match once it comes in. // entity values to change -- it just allows the model to match once it comes in.
model->setScaleToFit(false, getDimensions()); model->setScaleToFit(false, getScaledDimensions());
model->setSnapModelToRegistrationPoint(false, getRegistrationPoint()); model->setSnapModelToRegistrationPoint(false, getRegistrationPoint());
// now recalculate the bounds and registration // now recalculate the bounds and registration
model->setScaleToFit(true, getDimensions()); model->setScaleToFit(true, getScaledDimensions());
model->setSnapModelToRegistrationPoint(true, getRegistrationPoint()); model->setSnapModelToRegistrationPoint(true, getRegistrationPoint());
model->setRotation(getWorldOrientation()); model->setRotation(getWorldOrientation());
model->setTranslation(getWorldPosition()); model->setTranslation(getWorldPosition());
@ -169,7 +169,7 @@ bool RenderableModelEntityItem::needsUpdateModelBounds() const {
return true; return true;
} }
if (model->getScaleToFitDimensions() != getDimensions()) { if (model->getScaleToFitDimensions() != getScaledDimensions()) {
return true; return true;
} }
@ -209,17 +209,17 @@ void RenderableModelEntityItem::updateModelBounds() {
updateRenderItems = true; updateRenderItems = true;
} }
if (model->getScaleToFitDimensions() != getDimensions() || if (model->getScaleToFitDimensions() != getScaledDimensions() ||
model->getRegistrationPoint() != getRegistrationPoint()) { model->getRegistrationPoint() != getRegistrationPoint()) {
// The machinery for updateModelBounds will give existing models the opportunity to fix their // The machinery for updateModelBounds will give existing models the opportunity to fix their
// translation/rotation/scale/registration. The first two are straightforward, but the latter two // translation/rotation/scale/registration. The first two are straightforward, but the latter two
// have guards to make sure they don't happen after they've already been set. Here we reset those guards. // have guards to make sure they don't happen after they've already been set. Here we reset those guards.
// This doesn't cause the entity values to change -- it just allows the model to match once it comes in. // This doesn't cause the entity values to change -- it just allows the model to match once it comes in.
model->setScaleToFit(false, getDimensions()); model->setScaleToFit(false, getScaledDimensions());
model->setSnapModelToRegistrationPoint(false, getRegistrationPoint()); model->setSnapModelToRegistrationPoint(false, getRegistrationPoint());
// now recalculate the bounds and registration // now recalculate the bounds and registration
model->setScaleToFit(true, getDimensions()); model->setScaleToFit(true, getScaledDimensions());
model->setSnapModelToRegistrationPoint(true, getRegistrationPoint()); model->setSnapModelToRegistrationPoint(true, getRegistrationPoint());
updateRenderItems = true; updateRenderItems = true;
model->scaleToFit(); model->scaleToFit();
@ -372,7 +372,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
const uint32_t QUAD_STRIDE = 4; const uint32_t QUAD_STRIDE = 4;
ShapeType type = getShapeType(); ShapeType type = getShapeType();
glm::vec3 dimensions = getDimensions(); glm::vec3 dimensions = getScaledDimensions();
auto model = getModel(); auto model = getModel();
if (type == SHAPE_TYPE_COMPOUND) { if (type == SHAPE_TYPE_COMPOUND) {
updateModelBounds(); updateModelBounds();
@ -1153,7 +1153,7 @@ bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoin
return true; return true;
} }
if (model->getScaleToFitDimensions() != entity->getDimensions() || if (model->getScaleToFitDimensions() != entity->getScaledDimensions() ||
model->getRegistrationPoint() != entity->getRegistrationPoint()) { model->getRegistrationPoint() != entity->getRegistrationPoint()) {
return true; return true;
} }

View file

@ -60,7 +60,7 @@ public:
RenderableModelEntityItem(const EntityItemID& entityItemID, bool dimensionsInitialized); RenderableModelEntityItem(const EntityItemID& entityItemID, bool dimensionsInitialized);
virtual ~RenderableModelEntityItem(); virtual ~RenderableModelEntityItem();
virtual void setDimensions(const glm::vec3& value) override; virtual void setUnscaledDimensions(const glm::vec3& value) override;
virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override; virtual EntityItemProperties getProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()) const override;
void doInitialModelSimulation(); void doInitialModelSimulation();

View file

@ -213,7 +213,7 @@ void RenderablePolyVoxEntityItem::setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxel
glm::vec3 RenderablePolyVoxEntityItem::getSurfacePositionAdjustment() const { glm::vec3 RenderablePolyVoxEntityItem::getSurfacePositionAdjustment() const {
glm::vec3 result; glm::vec3 result;
withReadLock([&] { withReadLock([&] {
glm::vec3 scale = getDimensions() / _voxelVolumeSize; // meters / voxel-units glm::vec3 scale = getScaledDimensions() / _voxelVolumeSize; // meters / voxel-units
if (isEdged(_voxelSurfaceStyle)) { if (isEdged(_voxelSurfaceStyle)) {
result = scale / -2.0f; result = scale / -2.0f;
} }
@ -228,7 +228,7 @@ glm::mat4 RenderablePolyVoxEntityItem::voxelToLocalMatrix() const {
voxelVolumeSize = _voxelVolumeSize; voxelVolumeSize = _voxelVolumeSize;
}); });
glm::vec3 dimensions = getDimensions(); glm::vec3 dimensions = getScaledDimensions();
glm::vec3 scale = dimensions / voxelVolumeSize; // meters / voxel-units glm::vec3 scale = dimensions / voxelVolumeSize; // meters / voxel-units
bool success; // TODO -- Does this actually have to happen in world space? bool success; // TODO -- Does this actually have to happen in world space?
glm::vec3 center = getCenterPosition(success); // this handles registrationPoint changes glm::vec3 center = getCenterPosition(success); // this handles registrationPoint changes
@ -393,7 +393,7 @@ bool RenderablePolyVoxEntityItem::setSphere(const vec3& centerWorldCoords, float
glm::mat4 vtwMatrix = voxelToWorldMatrix(); glm::mat4 vtwMatrix = voxelToWorldMatrix();
glm::mat4 wtvMatrix = glm::inverse(vtwMatrix); glm::mat4 wtvMatrix = glm::inverse(vtwMatrix);
glm::vec3 dimensions = getDimensions(); glm::vec3 dimensions = getScaledDimensions();
glm::vec3 voxelSize = dimensions / _voxelVolumeSize; glm::vec3 voxelSize = dimensions / _voxelVolumeSize;
float smallestDimensionSize = voxelSize.x; float smallestDimensionSize = voxelSize.x;
smallestDimensionSize = glm::min(smallestDimensionSize, voxelSize.y); smallestDimensionSize = glm::min(smallestDimensionSize, voxelSize.y);
@ -454,7 +454,7 @@ bool RenderablePolyVoxEntityItem::setCapsule(const vec3& startWorldCoords, const
glm::mat4 vtwMatrix = voxelToWorldMatrix(); glm::mat4 vtwMatrix = voxelToWorldMatrix();
glm::mat4 wtvMatrix = glm::inverse(vtwMatrix); glm::mat4 wtvMatrix = glm::inverse(vtwMatrix);
glm::vec3 dimensions = getDimensions(); glm::vec3 dimensions = getScaledDimensions();
glm::vec3 voxelSize = dimensions / _voxelVolumeSize; glm::vec3 voxelSize = dimensions / _voxelVolumeSize;
float smallestDimensionSize = voxelSize.x; float smallestDimensionSize = voxelSize.x;
smallestDimensionSize = glm::min(smallestDimensionSize, voxelSize.y); smallestDimensionSize = glm::min(smallestDimensionSize, voxelSize.y);
@ -580,7 +580,7 @@ bool RenderablePolyVoxEntityItem::findDetailedRayIntersection(const glm::vec3& o
// the PolyVox ray intersection code requires a near and far point. // the PolyVox ray intersection code requires a near and far point.
// set ray cast length to long enough to cover all of the voxel space // set ray cast length to long enough to cover all of the voxel space
float distanceToEntity = glm::distance(origin, getWorldPosition()); float distanceToEntity = glm::distance(origin, getWorldPosition());
glm::vec3 dimensions = getDimensions(); glm::vec3 dimensions = getScaledDimensions();
float largestDimension = glm::compMax(dimensions) * 2.0f; float largestDimension = glm::compMax(dimensions) * 2.0f;
glm::vec3 farPoint = origin + normDirection * (distanceToEntity + largestDimension); glm::vec3 farPoint = origin + normDirection * (distanceToEntity + largestDimension);
@ -668,7 +668,7 @@ bool RenderablePolyVoxEntityItem::isReadyToComputeShape() const {
void RenderablePolyVoxEntityItem::computeShapeInfo(ShapeInfo& info) { void RenderablePolyVoxEntityItem::computeShapeInfo(ShapeInfo& info) {
ShapeType shapeType = getShapeType(); ShapeType shapeType = getShapeType();
if (shapeType == SHAPE_TYPE_NONE) { if (shapeType == SHAPE_TYPE_NONE) {
info.setParams(getShapeType(), 0.5f * getDimensions()); info.setParams(getShapeType(), 0.5f * getScaledDimensions());
return; return;
} }

View file

@ -63,7 +63,7 @@ bool ShapeEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoin
return true; return true;
} }
if (_dimensions != entity->getDimensions()) { if (_dimensions != entity->getScaledDimensions()) {
return true; return true;
} }
@ -82,7 +82,7 @@ void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
_shape = entity->getShape(); _shape = entity->getShape();
_position = entity->getWorldPosition(); _position = entity->getWorldPosition();
_dimensions = entity->getDimensions(); _dimensions = entity->getScaledDimensions();
_orientation = entity->getWorldOrientation(); _orientation = entity->getWorldOrientation();
_renderTransform = getModelTransform(); _renderTransform = getModelTransform();

View file

@ -54,7 +54,7 @@ bool TextEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoint
return true; return true;
} }
if (_dimensions != entity->getDimensions()) { if (_dimensions != entity->getScaledDimensions()) {
return true; return true;
} }
@ -67,7 +67,7 @@ bool TextEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoint
void TextEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { void TextEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
_textColor = toGlm(entity->getTextColorX()); _textColor = toGlm(entity->getTextColorX());
_backgroundColor = toGlm(entity->getBackgroundColorX()); _backgroundColor = toGlm(entity->getBackgroundColorX());
_dimensions = entity->getDimensions(); _dimensions = entity->getScaledDimensions();
_faceCamera = entity->getFaceCamera(); _faceCamera = entity->getFaceCamera();
_lineHeight = entity->getLineHeight(); _lineHeight = entity->getLineHeight();
_text = entity->getText(); _text = entity->getText();

View file

@ -149,7 +149,7 @@ void WebEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene
glm::vec2 windowSize = getWindowSize(entity); glm::vec2 windowSize = getWindowSize(entity);
_webSurface->resize(QSize(windowSize.x, windowSize.y)); _webSurface->resize(QSize(windowSize.x, windowSize.y));
_renderTransform = getModelTransform(); _renderTransform = getModelTransform();
_renderTransform.postScale(entity->getDimensions()); _renderTransform.postScale(entity->getScaledDimensions());
}); });
} }
@ -279,7 +279,7 @@ void WebEntityRenderer::destroyWebSurface() {
} }
glm::vec2 WebEntityRenderer::getWindowSize(const TypedEntityPointer& entity) const { glm::vec2 WebEntityRenderer::getWindowSize(const TypedEntityPointer& entity) const {
glm::vec2 dims = glm::vec2(entity->getDimensions()); glm::vec2 dims = glm::vec2(entity->getScaledDimensions());
dims *= METERS_TO_INCHES * _lastDPI; dims *= METERS_TO_INCHES * _lastDPI;
// ensure no side is never larger then MAX_WINDOW_SIZE // ensure no side is never larger then MAX_WINDOW_SIZE

View file

@ -208,7 +208,7 @@ void ZoneEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen
entity->resetRenderingPropertiesChanged(); entity->resetRenderingPropertiesChanged();
_lastPosition = entity->getWorldPosition(); _lastPosition = entity->getWorldPosition();
_lastRotation = entity->getWorldOrientation(); _lastRotation = entity->getWorldOrientation();
_lastDimensions = entity->getDimensions(); _lastDimensions = entity->getScaledDimensions();
_keyLightProperties = entity->getKeyLightProperties(); _keyLightProperties = entity->getKeyLightProperties();
_skyboxProperties = entity->getSkyboxProperties(); _skyboxProperties = entity->getSkyboxProperties();
@ -280,7 +280,7 @@ bool ZoneEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoint
if (entity->getWorldPosition() != _lastPosition) { if (entity->getWorldPosition() != _lastPosition) {
return true; return true;
} }
if (entity->getDimensions() != _lastDimensions) { if (entity->getScaledDimensions() != _lastDimensions) {
return true; return true;
} }
if (entity->getWorldOrientation() != _lastRotation) { if (entity->getWorldOrientation() != _lastRotation) {

View file

@ -50,6 +50,7 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) :
{ {
setLocalVelocity(ENTITY_ITEM_DEFAULT_VELOCITY); setLocalVelocity(ENTITY_ITEM_DEFAULT_VELOCITY);
setLocalAngularVelocity(ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY); setLocalAngularVelocity(ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY);
setUnscaledDimensions(ENTITY_ITEM_DEFAULT_DIMENSIONS);
// explicitly set transform parts to set dirty flags used by batch rendering // explicitly set transform parts to set dirty flags used by batch rendering
locationChanged(); locationChanged();
dimensionsChanged(); dimensionsChanged();
@ -243,7 +244,7 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
APPEND_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, getLocalAngularVelocity()); APPEND_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, getLocalAngularVelocity());
APPEND_ENTITY_PROPERTY(PROP_ACCELERATION, getAcceleration()); APPEND_ENTITY_PROPERTY(PROP_ACCELERATION, getAcceleration());
APPEND_ENTITY_PROPERTY(PROP_DIMENSIONS, getDimensions()); APPEND_ENTITY_PROPERTY(PROP_DIMENSIONS, getUnscaledDimensions());
APPEND_ENTITY_PROPERTY(PROP_DENSITY, getDensity()); APPEND_ENTITY_PROPERTY(PROP_DENSITY, getDensity());
APPEND_ENTITY_PROPERTY(PROP_GRAVITY, getGravity()); APPEND_ENTITY_PROPERTY(PROP_GRAVITY, getGravity());
APPEND_ENTITY_PROPERTY(PROP_DAMPING, getDamping()); APPEND_ENTITY_PROPERTY(PROP_DAMPING, getDamping());
@ -779,7 +780,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
READ_ENTITY_PROPERTY(PROP_ACCELERATION, glm::vec3, customSetAcceleration); READ_ENTITY_PROPERTY(PROP_ACCELERATION, glm::vec3, customSetAcceleration);
} }
READ_ENTITY_PROPERTY(PROP_DIMENSIONS, glm::vec3, setDimensions); READ_ENTITY_PROPERTY(PROP_DIMENSIONS, glm::vec3, setUnscaledDimensions);
READ_ENTITY_PROPERTY(PROP_DENSITY, float, setDensity); READ_ENTITY_PROPERTY(PROP_DENSITY, float, setDensity);
READ_ENTITY_PROPERTY(PROP_GRAVITY, glm::vec3, setGravity); READ_ENTITY_PROPERTY(PROP_GRAVITY, glm::vec3, setGravity);
@ -898,7 +899,7 @@ void EntityItem::debugDump() const {
qCDebug(entities) << "EntityItem id:" << getEntityItemID(); qCDebug(entities) << "EntityItem id:" << getEntityItemID();
qCDebug(entities, " edited ago:%f", (double)getEditedAgo()); qCDebug(entities, " edited ago:%f", (double)getEditedAgo());
qCDebug(entities, " position:%f,%f,%f", (double)position.x, (double)position.y, (double)position.z); qCDebug(entities, " position:%f,%f,%f", (double)position.x, (double)position.y, (double)position.z);
qCDebug(entities) << " dimensions:" << getDimensions(); qCDebug(entities) << " dimensions:" << getScaledDimensions();
} }
// adjust any internal timestamps to fix clock skew for this server // adjust any internal timestamps to fix clock skew for this server
@ -923,7 +924,7 @@ void EntityItem::adjustEditPacketForClockSkew(QByteArray& buffer, qint64 clockSk
} }
float EntityItem::computeMass() const { float EntityItem::computeMass() const {
glm::vec3 dimensions = getDimensions(); glm::vec3 dimensions = getScaledDimensions();
return getDensity() * _volumeMultiplier * dimensions.x * dimensions.y * dimensions.z; return getDensity() * _volumeMultiplier * dimensions.x * dimensions.y * dimensions.z;
} }
@ -942,7 +943,7 @@ void EntityItem::setMass(float mass) {
// we must protect the density range to help maintain stability of physics simulation // we must protect the density range to help maintain stability of physics simulation
// therefore this method might not accept the mass that is supplied. // therefore this method might not accept the mass that is supplied.
glm::vec3 dimensions = getDimensions(); glm::vec3 dimensions = getScaledDimensions();
float volume = _volumeMultiplier * dimensions.x * dimensions.y * dimensions.z; float volume = _volumeMultiplier * dimensions.x * dimensions.y * dimensions.z;
// compute new density // compute new density
@ -1178,7 +1179,7 @@ bool EntityItem::wantTerseEditLogging() const {
glm::mat4 EntityItem::getEntityToWorldMatrix() const { glm::mat4 EntityItem::getEntityToWorldMatrix() const {
glm::mat4 translation = glm::translate(getWorldPosition()); glm::mat4 translation = glm::translate(getWorldPosition());
glm::mat4 rotation = glm::mat4_cast(getWorldOrientation()); glm::mat4 rotation = glm::mat4_cast(getWorldOrientation());
glm::mat4 scale = glm::scale(getDimensions()); glm::mat4 scale = glm::scale(getScaledDimensions());
glm::mat4 registration = glm::translate(ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()); glm::mat4 registration = glm::translate(ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint());
return translation * rotation * scale * registration; return translation * rotation * scale * registration;
} }
@ -1218,7 +1219,7 @@ EntityItemProperties EntityItem::getProperties(EntityPropertyFlags desiredProper
COPY_ENTITY_PROPERTY_TO_PROPERTIES(simulationOwner, getSimulationOwner); COPY_ENTITY_PROPERTY_TO_PROPERTIES(simulationOwner, getSimulationOwner);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(position, getLocalPosition); COPY_ENTITY_PROPERTY_TO_PROPERTIES(position, getLocalPosition);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(dimensions, getDimensions); // NOTE: radius is obsolete COPY_ENTITY_PROPERTY_TO_PROPERTIES(dimensions, getUnscaledDimensions);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(rotation, getLocalOrientation); COPY_ENTITY_PROPERTY_TO_PROPERTIES(rotation, getLocalOrientation);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(density, getDensity); COPY_ENTITY_PROPERTY_TO_PROPERTIES(density, getDensity);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(velocity, getLocalVelocity); COPY_ENTITY_PROPERTY_TO_PROPERTIES(velocity, getLocalVelocity);
@ -1326,7 +1327,7 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) {
SET_ENTITY_PROPERTY_FROM_PROPERTIES(acceleration, setAcceleration); SET_ENTITY_PROPERTY_FROM_PROPERTIES(acceleration, setAcceleration);
// these (along with "position" above) affect tree structure // these (along with "position" above) affect tree structure
SET_ENTITY_PROPERTY_FROM_PROPERTIES(dimensions, setDimensions); SET_ENTITY_PROPERTY_FROM_PROPERTIES(dimensions, setUnscaledDimensions);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(registrationPoint, setRegistrationPoint); SET_ENTITY_PROPERTY_FROM_PROPERTIES(registrationPoint, setRegistrationPoint);
// these (along with all properties above) affect the simulation // these (along with all properties above) affect the simulation
@ -1429,7 +1430,7 @@ void EntityItem::recordCreationTime() {
const Transform EntityItem::getTransformToCenter(bool& success) const { const Transform EntityItem::getTransformToCenter(bool& success) const {
Transform result = getTransform(success); Transform result = getTransform(success);
if (getRegistrationPoint() != ENTITY_ITEM_HALF_VEC3) { // If it is not already centered, translate to center if (getRegistrationPoint() != ENTITY_ITEM_HALF_VEC3) { // If it is not already centered, translate to center
result.postTranslate((ENTITY_ITEM_HALF_VEC3 - getRegistrationPoint()) * getDimensions()); // Position to center result.postTranslate((ENTITY_ITEM_HALF_VEC3 - getRegistrationPoint()) * getScaledDimensions()); // Position to center
} }
return result; return result;
} }
@ -1445,7 +1446,7 @@ AACube EntityItem::getMaximumAACube(bool& success) const {
// we want to compute the furthestExtent that an entity can extend out from its "position" // we want to compute the furthestExtent that an entity can extend out from its "position"
// to do this we compute the max of these two vec3s: registration and 1-registration // to do this we compute the max of these two vec3s: registration and 1-registration
// and then scale by dimensions // and then scale by dimensions
glm::vec3 maxExtents = getDimensions() * glm::max(_registrationPoint, glm::vec3(1.0f) - _registrationPoint); glm::vec3 maxExtents = getScaledDimensions() * glm::max(_registrationPoint, glm::vec3(1.0f) - _registrationPoint);
// there exists a sphere that contains maxExtents for all rotations // there exists a sphere that contains maxExtents for all rotations
float radius = glm::length(maxExtents); float radius = glm::length(maxExtents);
@ -1470,7 +1471,7 @@ AACube EntityItem::getMinimumAACube(bool& success) const {
glm::vec3 position = getWorldPosition(success); glm::vec3 position = getWorldPosition(success);
if (success) { if (success) {
_recalcMinAACube = false; _recalcMinAACube = false;
glm::vec3 dimensions = getDimensions(); glm::vec3 dimensions = getScaledDimensions();
glm::vec3 unrotatedMinRelativeToEntity = - (dimensions * _registrationPoint); glm::vec3 unrotatedMinRelativeToEntity = - (dimensions * _registrationPoint);
glm::vec3 unrotatedMaxRelativeToEntity = dimensions * (glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint); glm::vec3 unrotatedMaxRelativeToEntity = dimensions * (glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint);
Extents extents = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity }; Extents extents = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity };
@ -1500,7 +1501,7 @@ AABox EntityItem::getAABox(bool& success) const {
glm::vec3 position = getWorldPosition(success); glm::vec3 position = getWorldPosition(success);
if (success) { if (success) {
_recalcAABox = false; _recalcAABox = false;
glm::vec3 dimensions = getDimensions(); glm::vec3 dimensions = getScaledDimensions();
glm::vec3 unrotatedMinRelativeToEntity = - (dimensions * _registrationPoint); glm::vec3 unrotatedMinRelativeToEntity = - (dimensions * _registrationPoint);
glm::vec3 unrotatedMaxRelativeToEntity = dimensions * (glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint); glm::vec3 unrotatedMaxRelativeToEntity = dimensions * (glm::vec3(1.0f, 1.0f, 1.0f) - _registrationPoint);
Extents extents = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity }; Extents extents = { unrotatedMinRelativeToEntity, unrotatedMaxRelativeToEntity };
@ -1540,12 +1541,12 @@ bool EntityItem::shouldPuffQueryAACube() const {
// ... cornerToCornerLength = sqrt(3 x maxDimension ^ 2) // ... cornerToCornerLength = sqrt(3 x maxDimension ^ 2)
// ... radius = sqrt(3 x maxDimension ^ 2) / 2.0f; // ... radius = sqrt(3 x maxDimension ^ 2) / 2.0f;
float EntityItem::getRadius() const { float EntityItem::getRadius() const {
return 0.5f * glm::length(getDimensions()); return 0.5f * glm::length(getScaledDimensions());
} }
void EntityItem::adjustShapeInfoByRegistration(ShapeInfo& info) const { void EntityItem::adjustShapeInfoByRegistration(ShapeInfo& info) const {
if (_registrationPoint != ENTITY_ITEM_DEFAULT_REGISTRATION_POINT) { if (_registrationPoint != ENTITY_ITEM_DEFAULT_REGISTRATION_POINT) {
glm::mat4 scale = glm::scale(getDimensions()); glm::mat4 scale = glm::scale(getScaledDimensions());
glm::mat4 registration = scale * glm::translate(ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()); glm::mat4 registration = scale * glm::translate(ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint());
glm::vec3 regTransVec = glm::vec3(registration[3]); // extract position component from matrix glm::vec3 regTransVec = glm::vec3(registration[3]); // extract position component from matrix
info.setOffset(regTransVec); info.setOffset(regTransVec);
@ -1566,12 +1567,12 @@ bool EntityItem::contains(const glm::vec3& point) const {
} }
void EntityItem::computeShapeInfo(ShapeInfo& info) { void EntityItem::computeShapeInfo(ShapeInfo& info) {
info.setParams(getShapeType(), 0.5f * getDimensions()); info.setParams(getShapeType(), 0.5f * getScaledDimensions());
adjustShapeInfoByRegistration(info); adjustShapeInfoByRegistration(info);
} }
float EntityItem::getVolumeEstimate() const { float EntityItem::getVolumeEstimate() const {
glm::vec3 dimensions = getDimensions(); glm::vec3 dimensions = getScaledDimensions();
return dimensions.x * dimensions.y * dimensions.z; return dimensions.x * dimensions.y * dimensions.z;
} }
@ -1671,11 +1672,21 @@ void EntityItem::setParentID(const QUuid& value) {
} }
} }
void EntityItem::setDimensions(const glm::vec3& value) { glm::vec3 EntityItem::getScaledDimensions() const {
glm::vec3 scale = getSNScale();
return _unscaledDimensions * scale;
}
void EntityItem::setScaledDimensions(const glm::vec3& value) {
glm::vec3 parentScale = getSNScale();
setUnscaledDimensions(value * parentScale);
}
void EntityItem::setUnscaledDimensions(const glm::vec3& value) {
glm::vec3 newDimensions = glm::max(value, glm::vec3(0.0f)); // can never have negative dimensions glm::vec3 newDimensions = glm::max(value, glm::vec3(0.0f)); // can never have negative dimensions
if (getDimensions() != newDimensions) { if (getUnscaledDimensions() != newDimensions) {
withWriteLock([&] { withWriteLock([&] {
_dimensions = newDimensions; _unscaledDimensions = newDimensions;
}); });
locationChanged(); locationChanged();
dimensionsChanged(); dimensionsChanged();
@ -2071,17 +2082,6 @@ bool EntityItem::removeActionInternal(const QUuid& actionID, EntitySimulationPoi
} }
EntityDynamicPointer action = _objectActions[actionID]; EntityDynamicPointer action = _objectActions[actionID];
action->setOwnerEntity(nullptr);
action->setIsMine(false);
if (simulation) {
action->removeFromSimulation(simulation);
}
bool success = true;
serializeActions(success, _allActionsDataCache);
_dirtyFlags |= Simulation::DIRTY_PHYSICS_ACTIVATION;
auto removedActionType = action->getType(); auto removedActionType = action->getType();
if ((removedActionType == DYNAMIC_TYPE_HOLD || removedActionType == DYNAMIC_TYPE_FAR_GRAB) && !stillHasGrabActions()) { if ((removedActionType == DYNAMIC_TYPE_HOLD || removedActionType == DYNAMIC_TYPE_FAR_GRAB) && !stillHasGrabActions()) {
_dirtyFlags &= ~Simulation::NO_BOOTSTRAPPING; _dirtyFlags &= ~Simulation::NO_BOOTSTRAPPING;
@ -2098,7 +2098,17 @@ bool EntityItem::removeActionInternal(const QUuid& actionID, EntitySimulationPoi
// because they should have been set correctly when the action was added // because they should have been set correctly when the action was added
// and/or when children were linked // and/or when children were linked
} }
action->setOwnerEntity(nullptr);
action->setIsMine(false);
_objectActions.remove(actionID); _objectActions.remove(actionID);
if (simulation) {
action->removeFromSimulation(simulation);
}
bool success = true;
serializeActions(success, _allActionsDataCache);
_dirtyFlags |= Simulation::DIRTY_PHYSICS_ACTIVATION;
setDynamicDataNeedsTransmit(true); setDynamicDataNeedsTransmit(true);
return success; return success;
} }
@ -2366,6 +2376,16 @@ void EntityItem::dimensionsChanged() {
somethingChangedNotification(); somethingChangedNotification();
} }
bool EntityItem::getScalesWithParent() const {
// keep this logic the same as in EntityItemProperties::getScalesWithParent
if (getClientOnly()) {
QUuid ancestorID = findAncestorOfType(NestableType::Avatar);
return !ancestorID.isNull();
} else {
return false;
}
}
void EntityItem::globalizeProperties(EntityItemProperties& properties, const QString& messageTemplate, const glm::vec3& offset) const { void EntityItem::globalizeProperties(EntityItemProperties& properties, const QString& messageTemplate, const glm::vec3& offset) const {
// TODO -- combine this with convertLocationToScriptSemantics // TODO -- combine this with convertLocationToScriptSemantics
bool success; bool success;
@ -2373,7 +2393,7 @@ void EntityItem::globalizeProperties(EntityItemProperties& properties, const QSt
if (success) { if (success) {
properties.setPosition(globalPosition + offset); properties.setPosition(globalPosition + offset);
properties.setRotation(getWorldOrientation()); properties.setRotation(getWorldOrientation());
properties.setDimensions(getDimensions()); properties.setDimensions(getScaledDimensions());
// Should we do velocities and accelerations, too? This could end up being quite involved, which is why the method exists. // Should we do velocities and accelerations, too? This could end up being quite involved, which is why the method exists.
} else { } else {
properties.setPosition(getQueryAACube().calcCenter() + offset); // best we can do properties.setPosition(getQueryAACube().calcCenter() + offset); // best we can do

View file

@ -180,8 +180,11 @@ public:
void setDescription(const QString& value); void setDescription(const QString& value);
/// Dimensions in meters (0.0 - TREE_SCALE) /// Dimensions in meters (0.0 - TREE_SCALE)
inline const glm::vec3 getDimensions() const { return _dimensions; } glm::vec3 getScaledDimensions() const;
virtual void setDimensions(const glm::vec3& value); virtual void setScaledDimensions(const glm::vec3& value);
inline const glm::vec3 getUnscaledDimensions() const { return _unscaledDimensions; }
virtual void setUnscaledDimensions(const glm::vec3& value);
float getLocalRenderAlpha() const; float getLocalRenderAlpha() const;
void setLocalRenderAlpha(float localRenderAlpha); void setLocalRenderAlpha(float localRenderAlpha);
@ -456,6 +459,8 @@ public:
virtual void locationChanged(bool tellPhysics = true) override; virtual void locationChanged(bool tellPhysics = true) override;
virtual bool getScalesWithParent() const override;
using ChangeHandlerCallback = std::function<void(const EntityItemID&)>; using ChangeHandlerCallback = std::function<void(const EntityItemID&)>;
using ChangeHandlerId = QUuid; using ChangeHandlerId = QUuid;
ChangeHandlerId registerChangeHandler(const ChangeHandlerCallback& handler); ChangeHandlerId registerChangeHandler(const ChangeHandlerCallback& handler);
@ -477,7 +482,7 @@ protected:
virtual void dimensionsChanged() override; virtual void dimensionsChanged() override;
glm::vec3 _dimensions { ENTITY_ITEM_DEFAULT_DIMENSIONS }; glm::vec3 _unscaledDimensions { ENTITY_ITEM_DEFAULT_DIMENSIONS };
EntityTypes::EntityType _type { EntityTypes::Unknown }; EntityTypes::EntityType _type { EntityTypes::Unknown };
quint64 _lastSimulated { 0 }; // last time this entity called simulate(), this includes velocity, angular velocity, quint64 _lastSimulated { 0 }; // last time this entity called simulate(), this includes velocity, angular velocity,
// and physics changes // and physics changes

View file

@ -365,6 +365,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
CHECK_PROPERTY_CHANGE(PROP_LOCAL_ROTATION, localRotation); CHECK_PROPERTY_CHANGE(PROP_LOCAL_ROTATION, localRotation);
CHECK_PROPERTY_CHANGE(PROP_LOCAL_VELOCITY, localVelocity); CHECK_PROPERTY_CHANGE(PROP_LOCAL_VELOCITY, localVelocity);
CHECK_PROPERTY_CHANGE(PROP_LOCAL_ANGULAR_VELOCITY, localAngularVelocity); CHECK_PROPERTY_CHANGE(PROP_LOCAL_ANGULAR_VELOCITY, localAngularVelocity);
CHECK_PROPERTY_CHANGE(PROP_LOCAL_DIMENSIONS, localDimensions);
CHECK_PROPERTY_CHANGE(PROP_FLYING_ALLOWED, flyingAllowed); CHECK_PROPERTY_CHANGE(PROP_FLYING_ALLOWED, flyingAllowed);
CHECK_PROPERTY_CHANGE(PROP_GHOSTING_ALLOWED, ghostingAllowed); CHECK_PROPERTY_CHANGE(PROP_GHOSTING_ALLOWED, ghostingAllowed);
@ -628,6 +629,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_ROTATION, localRotation); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_ROTATION, localRotation);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_VELOCITY, localVelocity); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_VELOCITY, localVelocity);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_ANGULAR_VELOCITY, localAngularVelocity); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_ANGULAR_VELOCITY, localAngularVelocity);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_LOCAL_DIMENSIONS, localDimensions);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CLIENT_ONLY, clientOnly); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_CLIENT_ONLY, clientOnly);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_OWNING_AVATAR_ID, owningAvatarID); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_OWNING_AVATAR_ID, owningAvatarID);
@ -805,6 +807,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
COPY_PROPERTY_FROM_QSCRIPTVALUE(localRotation, glmQuat, setLocalRotation); COPY_PROPERTY_FROM_QSCRIPTVALUE(localRotation, glmQuat, setLocalRotation);
COPY_PROPERTY_FROM_QSCRIPTVALUE(localVelocity, glmVec3, setLocalVelocity); COPY_PROPERTY_FROM_QSCRIPTVALUE(localVelocity, glmVec3, setLocalVelocity);
COPY_PROPERTY_FROM_QSCRIPTVALUE(localAngularVelocity, glmVec3, setLocalAngularVelocity); COPY_PROPERTY_FROM_QSCRIPTVALUE(localAngularVelocity, glmVec3, setLocalAngularVelocity);
COPY_PROPERTY_FROM_QSCRIPTVALUE(localDimensions, glmVec3, setLocalDimensions);
COPY_PROPERTY_FROM_QSCRIPTVALUE(jointRotationsSet, qVectorBool, setJointRotationsSet); COPY_PROPERTY_FROM_QSCRIPTVALUE(jointRotationsSet, qVectorBool, setJointRotationsSet);
COPY_PROPERTY_FROM_QSCRIPTVALUE(jointRotations, qVectorQuat, setJointRotations); COPY_PROPERTY_FROM_QSCRIPTVALUE(jointRotations, qVectorQuat, setJointRotations);
@ -953,6 +956,7 @@ void EntityItemProperties::merge(const EntityItemProperties& other) {
COPY_PROPERTY_IF_CHANGED(localRotation); COPY_PROPERTY_IF_CHANGED(localRotation);
COPY_PROPERTY_IF_CHANGED(localVelocity); COPY_PROPERTY_IF_CHANGED(localVelocity);
COPY_PROPERTY_IF_CHANGED(localAngularVelocity); COPY_PROPERTY_IF_CHANGED(localAngularVelocity);
COPY_PROPERTY_IF_CHANGED(localDimensions);
COPY_PROPERTY_IF_CHANGED(jointRotationsSet); COPY_PROPERTY_IF_CHANGED(jointRotationsSet);
COPY_PROPERTY_IF_CHANGED(jointRotations); COPY_PROPERTY_IF_CHANGED(jointRotations);
@ -1132,6 +1136,7 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue
ADD_PROPERTY_TO_MAP(PROP_LOCAL_ROTATION, LocalRotation, localRotation, glm::quat); ADD_PROPERTY_TO_MAP(PROP_LOCAL_ROTATION, LocalRotation, localRotation, glm::quat);
ADD_PROPERTY_TO_MAP(PROP_LOCAL_VELOCITY, LocalVelocity, localVelocity, glm::vec3); ADD_PROPERTY_TO_MAP(PROP_LOCAL_VELOCITY, LocalVelocity, localVelocity, glm::vec3);
ADD_PROPERTY_TO_MAP(PROP_LOCAL_ANGULAR_VELOCITY, LocalAngularVelocity, localAngularVelocity, glm::vec3); ADD_PROPERTY_TO_MAP(PROP_LOCAL_ANGULAR_VELOCITY, LocalAngularVelocity, localAngularVelocity, glm::vec3);
ADD_PROPERTY_TO_MAP(PROP_LOCAL_DIMENSIONS, LocalDimensions, localDimensions, glm::vec3);
ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS_SET, JointRotationsSet, jointRotationsSet, QVector<bool>); ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS_SET, JointRotationsSet, jointRotationsSet, QVector<bool>);
ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector<glm::quat>); ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector<glm::quat>);
@ -2470,9 +2475,25 @@ bool EntityItemProperties::transformChanged() const {
localPositionChanged() || localRotationChanged(); localPositionChanged() || localRotationChanged();
} }
bool EntityItemProperties::getScalesWithParent() const {
// keep this logic the same as in EntityItem::getScalesWithParent
bool scalesWithParent { false };
if (parentIDChanged()) {
bool success;
SpatiallyNestablePointer parent = SpatiallyNestable::findByID(getParentID(), success);
if (success && parent) {
bool avatarAncestor = (parent->getNestableType() == NestableType::Avatar ||
parent->hasAncestorOfType(NestableType::Avatar));
scalesWithParent = getClientOnly() && avatarAncestor;
}
}
return scalesWithParent;
}
bool EntityItemProperties::parentRelatedPropertyChanged() const { bool EntityItemProperties::parentRelatedPropertyChanged() const {
return positionChanged() || rotationChanged() || return positionChanged() || rotationChanged() ||
localPositionChanged() || localRotationChanged() || localPositionChanged() || localRotationChanged() ||
localDimensionsChanged() ||
parentIDChanged() || parentJointIndexChanged(); parentIDChanged() || parentJointIndexChanged();
} }

View file

@ -88,6 +88,7 @@ public:
EntityPropertyFlags getChangedProperties() const; EntityPropertyFlags getChangedProperties() const;
bool transformChanged() const; bool transformChanged() const;
bool getScalesWithParent() const;
bool parentRelatedPropertyChanged() const; bool parentRelatedPropertyChanged() const;
bool queryAACubeRelatedPropertyChanged() const; bool queryAACubeRelatedPropertyChanged() const;
@ -227,6 +228,7 @@ public:
DEFINE_PROPERTY_REF(PROP_LOCAL_ROTATION, LocalRotation, localRotation, glmQuat, ENTITY_ITEM_DEFAULT_ROTATION); DEFINE_PROPERTY_REF(PROP_LOCAL_ROTATION, LocalRotation, localRotation, glmQuat, ENTITY_ITEM_DEFAULT_ROTATION);
DEFINE_PROPERTY_REF(PROP_LOCAL_VELOCITY, LocalVelocity, localVelocity, glmVec3, ENTITY_ITEM_ZERO_VEC3); DEFINE_PROPERTY_REF(PROP_LOCAL_VELOCITY, LocalVelocity, localVelocity, glmVec3, ENTITY_ITEM_ZERO_VEC3);
DEFINE_PROPERTY_REF(PROP_LOCAL_ANGULAR_VELOCITY, LocalAngularVelocity, localAngularVelocity, glmVec3, ENTITY_ITEM_ZERO_VEC3); DEFINE_PROPERTY_REF(PROP_LOCAL_ANGULAR_VELOCITY, LocalAngularVelocity, localAngularVelocity, glmVec3, ENTITY_ITEM_ZERO_VEC3);
DEFINE_PROPERTY_REF(PROP_LOCAL_DIMENSIONS, LocalDimensions, localDimensions, glmVec3, ENTITY_ITEM_ZERO_VEC3);
DEFINE_PROPERTY_REF(PROP_JOINT_ROTATIONS_SET, JointRotationsSet, jointRotationsSet, QVector<bool>, QVector<bool>()); DEFINE_PROPERTY_REF(PROP_JOINT_ROTATIONS_SET, JointRotationsSet, jointRotationsSet, QVector<bool>, QVector<bool>());
DEFINE_PROPERTY_REF(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector<glm::quat>, QVector<glm::quat>()); DEFINE_PROPERTY_REF(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector<glm::quat>, QVector<glm::quat>());

View file

@ -220,6 +220,8 @@ enum EntityPropertyList {
PROP_HAZE_KEYLIGHT_RANGE, PROP_HAZE_KEYLIGHT_RANGE,
PROP_HAZE_KEYLIGHT_ALTITUDE, PROP_HAZE_KEYLIGHT_ALTITUDE,
PROP_LOCAL_DIMENSIONS, // only used to convert values to and from scripts
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
// ATTENTION: add new properties to end of list just ABOVE this line // ATTENTION: add new properties to end of list just ABOVE this line
PROP_AFTER_LAST_ITEM, PROP_AFTER_LAST_ITEM,

View file

@ -117,7 +117,8 @@ void EntityScriptingInterface::setEntityTree(EntityTreePointer elementTree) {
} }
} }
EntityItemProperties convertLocationToScriptSemantics(const EntityItemProperties& entitySideProperties) { EntityItemProperties convertPropertiesToScriptSemantics(const EntityItemProperties& entitySideProperties,
bool scalesWithParent) {
// In EntityTree code, properties.position and properties.rotation are relative to the parent. In javascript, // In EntityTree code, properties.position and properties.rotation are relative to the parent. In javascript,
// they are in world-space. The local versions are put into localPosition and localRotation and position and // they are in world-space. The local versions are put into localPosition and localRotation and position and
// rotation are converted from local to world space. // rotation are converted from local to world space.
@ -126,35 +127,48 @@ EntityItemProperties convertLocationToScriptSemantics(const EntityItemProperties
scriptSideProperties.setLocalRotation(entitySideProperties.getRotation()); scriptSideProperties.setLocalRotation(entitySideProperties.getRotation());
scriptSideProperties.setLocalVelocity(entitySideProperties.getLocalVelocity()); scriptSideProperties.setLocalVelocity(entitySideProperties.getLocalVelocity());
scriptSideProperties.setLocalAngularVelocity(entitySideProperties.getLocalAngularVelocity()); scriptSideProperties.setLocalAngularVelocity(entitySideProperties.getLocalAngularVelocity());
scriptSideProperties.setLocalDimensions(entitySideProperties.getDimensions());
bool success; bool success;
glm::vec3 worldPosition = SpatiallyNestable::localToWorld(entitySideProperties.getPosition(), glm::vec3 worldPosition = SpatiallyNestable::localToWorld(entitySideProperties.getPosition(),
entitySideProperties.getParentID(), entitySideProperties.getParentID(),
entitySideProperties.getParentJointIndex(), entitySideProperties.getParentJointIndex(),
scalesWithParent,
success); success);
glm::quat worldRotation = SpatiallyNestable::localToWorld(entitySideProperties.getRotation(), glm::quat worldRotation = SpatiallyNestable::localToWorld(entitySideProperties.getRotation(),
entitySideProperties.getParentID(), entitySideProperties.getParentID(),
entitySideProperties.getParentJointIndex(), entitySideProperties.getParentJointIndex(),
scalesWithParent,
success); success);
glm::vec3 worldVelocity = SpatiallyNestable::localToWorldVelocity(entitySideProperties.getVelocity(), glm::vec3 worldVelocity = SpatiallyNestable::localToWorldVelocity(entitySideProperties.getVelocity(),
entitySideProperties.getParentID(), entitySideProperties.getParentID(),
entitySideProperties.getParentJointIndex(), entitySideProperties.getParentJointIndex(),
scalesWithParent,
success); success);
glm::vec3 worldAngularVelocity = SpatiallyNestable::localToWorldAngularVelocity(entitySideProperties.getAngularVelocity(), glm::vec3 worldAngularVelocity = SpatiallyNestable::localToWorldAngularVelocity(entitySideProperties.getAngularVelocity(),
entitySideProperties.getParentID(), entitySideProperties.getParentID(),
entitySideProperties.getParentJointIndex(), entitySideProperties.getParentJointIndex(),
scalesWithParent,
success); success);
glm::vec3 worldDimensions = SpatiallyNestable::localToWorldDimensions(entitySideProperties.getDimensions(),
entitySideProperties.getParentID(),
entitySideProperties.getParentJointIndex(),
scalesWithParent,
success);
scriptSideProperties.setPosition(worldPosition); scriptSideProperties.setPosition(worldPosition);
scriptSideProperties.setRotation(worldRotation); scriptSideProperties.setRotation(worldRotation);
scriptSideProperties.setVelocity(worldVelocity); scriptSideProperties.setVelocity(worldVelocity);
scriptSideProperties.setAngularVelocity(worldAngularVelocity); scriptSideProperties.setAngularVelocity(worldAngularVelocity);
scriptSideProperties.setDimensions(worldDimensions);
return scriptSideProperties; return scriptSideProperties;
} }
EntityItemProperties convertLocationFromScriptSemantics(const EntityItemProperties& scriptSideProperties) { EntityItemProperties convertPropertiesFromScriptSemantics(const EntityItemProperties& scriptSideProperties,
bool scalesWithParent) {
// convert position and rotation properties from world-space to local, unless localPosition and localRotation // convert position and rotation properties from world-space to local, unless localPosition and localRotation
// are set. If they are set, they overwrite position and rotation. // are set. If they are set, they overwrite position and rotation.
EntityItemProperties entitySideProperties = scriptSideProperties; EntityItemProperties entitySideProperties = scriptSideProperties;
@ -168,7 +182,7 @@ EntityItemProperties convertLocationFromScriptSemantics(const EntityItemProperti
glm::vec3 localPosition = SpatiallyNestable::worldToLocal(entitySideProperties.getPosition(), glm::vec3 localPosition = SpatiallyNestable::worldToLocal(entitySideProperties.getPosition(),
entitySideProperties.getParentID(), entitySideProperties.getParentID(),
entitySideProperties.getParentJointIndex(), entitySideProperties.getParentJointIndex(),
success); scalesWithParent, success);
entitySideProperties.setPosition(localPosition); entitySideProperties.setPosition(localPosition);
} }
@ -178,7 +192,7 @@ EntityItemProperties convertLocationFromScriptSemantics(const EntityItemProperti
glm::quat localRotation = SpatiallyNestable::worldToLocal(entitySideProperties.getRotation(), glm::quat localRotation = SpatiallyNestable::worldToLocal(entitySideProperties.getRotation(),
entitySideProperties.getParentID(), entitySideProperties.getParentID(),
entitySideProperties.getParentJointIndex(), entitySideProperties.getParentJointIndex(),
success); scalesWithParent, success);
entitySideProperties.setRotation(localRotation); entitySideProperties.setRotation(localRotation);
} }
@ -188,7 +202,7 @@ EntityItemProperties convertLocationFromScriptSemantics(const EntityItemProperti
glm::vec3 localVelocity = SpatiallyNestable::worldToLocalVelocity(entitySideProperties.getVelocity(), glm::vec3 localVelocity = SpatiallyNestable::worldToLocalVelocity(entitySideProperties.getVelocity(),
entitySideProperties.getParentID(), entitySideProperties.getParentID(),
entitySideProperties.getParentJointIndex(), entitySideProperties.getParentJointIndex(),
success); scalesWithParent, success);
entitySideProperties.setVelocity(localVelocity); entitySideProperties.setVelocity(localVelocity);
} }
@ -199,10 +213,20 @@ EntityItemProperties convertLocationFromScriptSemantics(const EntityItemProperti
SpatiallyNestable::worldToLocalAngularVelocity(entitySideProperties.getAngularVelocity(), SpatiallyNestable::worldToLocalAngularVelocity(entitySideProperties.getAngularVelocity(),
entitySideProperties.getParentID(), entitySideProperties.getParentID(),
entitySideProperties.getParentJointIndex(), entitySideProperties.getParentJointIndex(),
success); scalesWithParent, success);
entitySideProperties.setAngularVelocity(localAngularVelocity); entitySideProperties.setAngularVelocity(localAngularVelocity);
} }
if (scriptSideProperties.localDimensionsChanged()) {
entitySideProperties.setDimensions(scriptSideProperties.getLocalDimensions());
} else if (scriptSideProperties.dimensionsChanged()) {
glm::vec3 localDimensions = SpatiallyNestable::worldToLocalDimensions(entitySideProperties.getDimensions(),
entitySideProperties.getParentID(),
entitySideProperties.getParentJointIndex(),
scalesWithParent, success);
entitySideProperties.setDimensions(localDimensions);
}
return entitySideProperties; return entitySideProperties;
} }
@ -212,9 +236,7 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties
_activityTracking.addedEntityCount++; _activityTracking.addedEntityCount++;
EntityItemProperties propertiesWithSimID = convertLocationFromScriptSemantics(properties); EntityItemProperties propertiesWithSimID = properties;
propertiesWithSimID.setDimensionsInitialized(properties.dimensionsChanged());
if (clientOnly) { if (clientOnly) {
auto nodeList = DependencyManager::get<NodeList>(); auto nodeList = DependencyManager::get<NodeList>();
const QUuid myNodeID = nodeList->getSessionUUID(); const QUuid myNodeID = nodeList->getSessionUUID();
@ -222,6 +244,11 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties
propertiesWithSimID.setOwningAvatarID(myNodeID); propertiesWithSimID.setOwningAvatarID(myNodeID);
} }
bool scalesWithParent = propertiesWithSimID.getScalesWithParent();
propertiesWithSimID = convertPropertiesFromScriptSemantics(propertiesWithSimID, scalesWithParent);
propertiesWithSimID.setDimensionsInitialized(properties.dimensionsChanged());
auto dimensions = propertiesWithSimID.getDimensions(); auto dimensions = propertiesWithSimID.getDimensions();
float volume = dimensions.x * dimensions.y * dimensions.z; float volume = dimensions.x * dimensions.y * dimensions.z;
auto density = propertiesWithSimID.getDensity(); auto density = propertiesWithSimID.getDensity();
@ -295,15 +322,20 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit
EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identity, EntityPropertyFlags desiredProperties) { EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identity, EntityPropertyFlags desiredProperties) {
PROFILE_RANGE(script_entities, __FUNCTION__); PROFILE_RANGE(script_entities, __FUNCTION__);
bool scalesWithParent { false };
EntityItemProperties results; EntityItemProperties results;
if (_entityTree) { if (_entityTree) {
_entityTree->withReadLock([&] { _entityTree->withReadLock([&] {
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(EntityItemID(identity)); EntityItemPointer entity = _entityTree->findEntityByEntityItemID(EntityItemID(identity));
if (entity) { if (entity) {
scalesWithParent = entity->getScalesWithParent();
if (desiredProperties.getHasProperty(PROP_POSITION) || if (desiredProperties.getHasProperty(PROP_POSITION) ||
desiredProperties.getHasProperty(PROP_ROTATION) || desiredProperties.getHasProperty(PROP_ROTATION) ||
desiredProperties.getHasProperty(PROP_LOCAL_POSITION) || desiredProperties.getHasProperty(PROP_LOCAL_POSITION) ||
desiredProperties.getHasProperty(PROP_LOCAL_ROTATION)) { desiredProperties.getHasProperty(PROP_LOCAL_ROTATION) ||
desiredProperties.getHasProperty(PROP_LOCAL_VELOCITY) ||
desiredProperties.getHasProperty(PROP_LOCAL_ANGULAR_VELOCITY) ||
desiredProperties.getHasProperty(PROP_LOCAL_DIMENSIONS)) {
// if we are explicitly getting position or rotation, we need parent information to make sense of them. // if we are explicitly getting position or rotation, we need parent information to make sense of them.
desiredProperties.setHasProperty(PROP_PARENT_ID); desiredProperties.setHasProperty(PROP_PARENT_ID);
desiredProperties.setHasProperty(PROP_PARENT_JOINT_INDEX); desiredProperties.setHasProperty(PROP_PARENT_JOINT_INDEX);
@ -316,6 +348,9 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit
desiredProperties = entity->getEntityProperties(params); desiredProperties = entity->getEntityProperties(params);
desiredProperties.setHasProperty(PROP_LOCAL_POSITION); desiredProperties.setHasProperty(PROP_LOCAL_POSITION);
desiredProperties.setHasProperty(PROP_LOCAL_ROTATION); desiredProperties.setHasProperty(PROP_LOCAL_ROTATION);
desiredProperties.setHasProperty(PROP_LOCAL_VELOCITY);
desiredProperties.setHasProperty(PROP_LOCAL_ANGULAR_VELOCITY);
desiredProperties.setHasProperty(PROP_LOCAL_DIMENSIONS);
} }
results = entity->getProperties(desiredProperties); results = entity->getProperties(desiredProperties);
@ -323,7 +358,7 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit
}); });
} }
return convertLocationToScriptSemantics(results); return convertPropertiesToScriptSemantics(results, scalesWithParent);
} }
QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& scriptSideProperties) { QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& scriptSideProperties) {
@ -390,10 +425,13 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties&
if (!scriptSideProperties.localRotationChanged() && !scriptSideProperties.rotationChanged()) { if (!scriptSideProperties.localRotationChanged() && !scriptSideProperties.rotationChanged()) {
properties.setRotation(entity->getWorldOrientation()); properties.setRotation(entity->getWorldOrientation());
} }
if (!scriptSideProperties.localDimensionsChanged() && !scriptSideProperties.dimensionsChanged()) {
properties.setDimensions(entity->getScaledDimensions());
}
} }
properties = convertLocationFromScriptSemantics(properties);
properties.setClientOnly(entity->getClientOnly()); properties.setClientOnly(entity->getClientOnly());
properties.setOwningAvatarID(entity->getOwningAvatarID()); properties.setOwningAvatarID(entity->getOwningAvatarID());
properties = convertPropertiesFromScriptSemantics(properties, properties.getScalesWithParent());
float cost = calculateCost(density * volume, oldVelocity, newVelocity); float cost = calculateCost(density * volume, oldVelocity, newVelocity);
cost *= costMultiplier; cost *= costMultiplier;
@ -529,7 +567,7 @@ void EntityScriptingInterface::deleteEntity(QUuid id) {
return; return;
} }
auto dimensions = entity->getDimensions(); auto dimensions = entity->getScaledDimensions();
float volume = dimensions.x * dimensions.y * dimensions.z; float volume = dimensions.x * dimensions.y * dimensions.z;
auto density = entity->getDensity(); auto density = entity->getDensity();
auto velocity = entity->getWorldVelocity().length(); auto velocity = entity->getWorldVelocity().length();

View file

@ -667,7 +667,7 @@ bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, con
glm::mat4 entityToWorldMatrix = translation * rotation; glm::mat4 entityToWorldMatrix = translation * rotation;
glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix); glm::mat4 worldToEntityMatrix = glm::inverse(entityToWorldMatrix);
glm::vec3 dimensions = entity->getDimensions(); glm::vec3 dimensions = entity->getScaledDimensions();
glm::vec3 registrationPoint = entity->getRegistrationPoint(); glm::vec3 registrationPoint = entity->getRegistrationPoint();
glm::vec3 corner = -(dimensions * registrationPoint); glm::vec3 corner = -(dimensions * registrationPoint);
@ -763,7 +763,7 @@ void EntityTreeElement::getEntities(const glm::vec3& searchPosition, float searc
glm::vec3 penetration; glm::vec3 penetration;
if (!success || entityBox.findSpherePenetration(searchPosition, searchRadius, penetration)) { if (!success || entityBox.findSpherePenetration(searchPosition, searchRadius, penetration)) {
glm::vec3 dimensions = entity->getDimensions(); glm::vec3 dimensions = entity->getScaledDimensions();
// FIXME - consider allowing the entity to determine penetration so that // FIXME - consider allowing the entity to determine penetration so that
// entities could presumably dull actuall hull testing if they wanted to // entities could presumably dull actuall hull testing if they wanted to

View file

@ -41,16 +41,16 @@ LightEntityItem::LightEntityItem(const EntityItemID& entityItemID) : EntityItem(
_color[RED_INDEX] = _color[GREEN_INDEX] = _color[BLUE_INDEX] = 0; _color[RED_INDEX] = _color[GREEN_INDEX] = _color[BLUE_INDEX] = 0;
} }
void LightEntityItem::setDimensions(const glm::vec3& value) { void LightEntityItem::setUnscaledDimensions(const glm::vec3& value) {
if (_isSpotlight) { if (_isSpotlight) {
// If we are a spotlight, treat the z value as our radius or length, and // If we are a spotlight, treat the z value as our radius or length, and
// recalculate the x/y dimensions to properly encapsulate the spotlight. // recalculate the x/y dimensions to properly encapsulate the spotlight.
const float length = value.z; const float length = value.z;
const float width = length * glm::sin(glm::radians(_cutoff)); const float width = length * glm::sin(glm::radians(_cutoff));
EntityItem::setDimensions(glm::vec3(width, width, length)); EntityItem::setUnscaledDimensions(glm::vec3(width, width, length));
} else { } else {
float maxDimension = glm::compMax(value); float maxDimension = glm::compMax(value);
EntityItem::setDimensions(glm::vec3(maxDimension, maxDimension, maxDimension)); EntityItem::setUnscaledDimensions(glm::vec3(maxDimension, maxDimension, maxDimension));
} }
} }
@ -98,7 +98,7 @@ void LightEntityItem::setIsSpotlight(bool value) {
return; return;
} }
glm::vec3 dimensions = getDimensions(); glm::vec3 dimensions = getScaledDimensions();
glm::vec3 newDimensions; glm::vec3 newDimensions;
if (value) { if (value) {
const float length = dimensions.z; const float length = dimensions.z;
@ -112,7 +112,7 @@ void LightEntityItem::setIsSpotlight(bool value) {
_isSpotlight = value; _isSpotlight = value;
_lightPropertiesChanged = true; _lightPropertiesChanged = true;
}); });
setDimensions(newDimensions); setScaledDimensions(newDimensions);
} }
void LightEntityItem::setCutoff(float value) { void LightEntityItem::setCutoff(float value) {
@ -128,9 +128,9 @@ void LightEntityItem::setCutoff(float value) {
if (getIsSpotlight()) { if (getIsSpotlight()) {
// If we are a spotlight, adjusting the cutoff will affect the area we encapsulate, // If we are a spotlight, adjusting the cutoff will affect the area we encapsulate,
// so update the dimensions to reflect this. // so update the dimensions to reflect this.
const float length = getDimensions().z; const float length = getScaledDimensions().z;
const float width = length * glm::sin(glm::radians(_cutoff)); const float width = length * glm::sin(glm::radians(_cutoff));
setDimensions(glm::vec3(width, width, length)); setScaledDimensions(glm::vec3(width, width, length));
} }
withWriteLock([&] { withWriteLock([&] {

View file

@ -29,7 +29,7 @@ public:
ALLOW_INSTANTIATION // This class can be instantiated ALLOW_INSTANTIATION // This class can be instantiated
/// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately /// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately
virtual void setDimensions(const glm::vec3& value) override; virtual void setUnscaledDimensions(const glm::vec3& value) override;
virtual bool setProperties(const EntityItemProperties& properties) override; virtual bool setProperties(const EntityItemProperties& properties) override;
virtual bool setSubClassProperties(const EntityItemProperties& properties) override; virtual bool setSubClassProperties(const EntityItemProperties& properties) override;

View file

@ -80,7 +80,7 @@ bool LineEntityItem::appendPoint(const glm::vec3& point) {
qCDebug(entities) << "MAX POINTS REACHED!"; qCDebug(entities) << "MAX POINTS REACHED!";
return false; return false;
} }
glm::vec3 halfBox = getDimensions() * 0.5f; glm::vec3 halfBox = getScaledDimensions() * 0.5f;
if ( (point.x < - halfBox.x || point.x > halfBox.x) || (point.y < -halfBox.y || point.y > halfBox.y) || (point.z < - halfBox.z || point.z > halfBox.z) ) { if ( (point.x < - halfBox.x || point.x > halfBox.x) || (point.y < -halfBox.y || point.y > halfBox.y) || (point.z < - halfBox.z || point.z > halfBox.z) ) {
qCDebug(entities) << "Point is outside entity's bounding box"; qCDebug(entities) << "Point is outside entity's bounding box";
return false; return false;
@ -96,7 +96,7 @@ bool LineEntityItem::setLinePoints(const QVector<glm::vec3>& points) {
if (points.size() > MAX_POINTS_PER_LINE) { if (points.size() > MAX_POINTS_PER_LINE) {
return false; return false;
} }
glm::vec3 halfBox = getDimensions() * 0.5f; glm::vec3 halfBox = getScaledDimensions() * 0.5f;
for (int i = 0; i < points.size(); i++) { for (int i = 0; i < points.size(); i++) {
glm::vec3 point = points.at(i); glm::vec3 point = points.at(i);
if ( (point.x < - halfBox.x || point.x > halfBox.x) || (point.y < -halfBox.y || point.y > halfBox.y) || (point.z < - halfBox.z || point.z > halfBox.z) ) { if ( (point.x < - halfBox.x || point.x > halfBox.x) || (point.y < -halfBox.y || point.y > halfBox.y) || (point.z < - halfBox.z || point.z > halfBox.z) ) {
@ -157,7 +157,7 @@ void LineEntityItem::debugDump() const {
qCDebug(entities) << " LINE EntityItem id:" << getEntityItemID() << "---------------------------------------------"; qCDebug(entities) << " LINE EntityItem id:" << getEntityItemID() << "---------------------------------------------";
qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2]; qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2];
qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition()); qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition());
qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions()); qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions());
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now); qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
} }

View file

@ -289,7 +289,7 @@ void ModelEntityItem::debugDump() const {
qCDebug(entities) << "ModelEntityItem id:" << getEntityItemID(); qCDebug(entities) << "ModelEntityItem id:" << getEntityItemID();
qCDebug(entities) << " edited ago:" << getEditedAgo(); qCDebug(entities) << " edited ago:" << getEditedAgo();
qCDebug(entities) << " position:" << getWorldPosition(); qCDebug(entities) << " position:" << getWorldPosition();
qCDebug(entities) << " dimensions:" << getDimensions(); qCDebug(entities) << " dimensions:" << getScaledDimensions();
qCDebug(entities) << " model URL:" << getModelURL(); qCDebug(entities) << " model URL:" << getModelURL();
qCDebug(entities) << " compound shape URL:" << getCompoundShapeURL(); qCDebug(entities) << " compound shape URL:" << getCompoundShapeURL();
} }

View file

@ -353,7 +353,7 @@ void ParticleEffectEntityItem::computeAndUpdateDimensions() {
float maxDistanceValue = glm::compMax(maxDistance); float maxDistanceValue = glm::compMax(maxDistance);
//times 2 because dimensions are diameters not radii //times 2 because dimensions are diameters not radii
glm::vec3 dims(2.0f * maxDistanceValue); glm::vec3 dims(2.0f * maxDistanceValue);
EntityItem::setDimensions(dims); EntityItem::setScaledDimensions(dims);
} }
@ -593,7 +593,7 @@ void ParticleEffectEntityItem::debugDump() const {
_particleProperties.color.gradient.target.green << "," << _particleProperties.color.gradient.target.green << "," <<
_particleProperties.color.gradient.target.blue; _particleProperties.color.gradient.target.blue;
qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition()); qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition());
qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions()); qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions());
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now); qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
} }

View file

@ -191,7 +191,7 @@ void PolyLineEntityItem::calculateScaleAndRegistrationPoint() {
} }
// if Polyline has only one or fewer points, use default dimension settings // if Polyline has only one or fewer points, use default dimension settings
setDimensions(newScale); setScaledDimensions(newScale);
EntityItem::setRegistrationPoint(newRegistrationPoint); EntityItem::setRegistrationPoint(newRegistrationPoint);
} }
@ -257,7 +257,7 @@ void PolyLineEntityItem::debugDump() const {
qCDebug(entities) << " QUAD EntityItem id:" << getEntityItemID() << "---------------------------------------------"; qCDebug(entities) << " QUAD EntityItem id:" << getEntityItemID() << "---------------------------------------------";
qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2]; qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2];
qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition()); qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition());
qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions()); qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions());
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now); qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
} }

View file

@ -229,7 +229,7 @@ void PolyVoxEntityItem::debugDump() const {
quint64 now = usecTimestampNow(); quint64 now = usecTimestampNow();
qCDebug(entities) << " POLYVOX EntityItem id:" << getEntityItemID() << "---------------------------------------------"; qCDebug(entities) << " POLYVOX EntityItem id:" << getEntityItemID() << "---------------------------------------------";
qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition()); qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition());
qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions()); qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions());
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now); qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
} }
@ -377,7 +377,7 @@ EntityItemID PolyVoxEntityItem::getZPNeighborID() const {
glm::vec3 PolyVoxEntityItem::getSurfacePositionAdjustment() const { glm::vec3 PolyVoxEntityItem::getSurfacePositionAdjustment() const {
glm::vec3 result; glm::vec3 result;
withReadLock([&] { withReadLock([&] {
glm::vec3 scale = getDimensions() / _voxelVolumeSize; // meters / voxel-units glm::vec3 scale = getScaledDimensions() / _voxelVolumeSize; // meters / voxel-units
if (isEdged()) { if (isEdged()) {
result = scale / -2.0f; result = scale / -2.0f;
} }
@ -392,7 +392,7 @@ glm::mat4 PolyVoxEntityItem::voxelToLocalMatrix() const {
voxelVolumeSize = _voxelVolumeSize; voxelVolumeSize = _voxelVolumeSize;
}); });
glm::vec3 dimensions = getDimensions(); glm::vec3 dimensions = getScaledDimensions();
glm::vec3 scale = dimensions / voxelVolumeSize; // meters / voxel-units glm::vec3 scale = dimensions / voxelVolumeSize; // meters / voxel-units
bool success; // TODO -- Does this actually have to happen in world space? bool success; // TODO -- Does this actually have to happen in world space?
glm::vec3 center = getCenterPosition(success); // this handles registrationPoint changes glm::vec3 center = getCenterPosition(success); // this handles registrationPoint changes

View file

@ -106,11 +106,11 @@ void ShapeEntityItem::setShape(const entity::Shape& shape) {
break; break;
case entity::Shape::Circle: case entity::Shape::Circle:
// Circle is implicitly flat so we enforce flat dimensions // Circle is implicitly flat so we enforce flat dimensions
setDimensions(getDimensions()); setUnscaledDimensions(getUnscaledDimensions());
break; break;
case entity::Shape::Quad: case entity::Shape::Quad:
// Quad is implicitly flat so we enforce flat dimensions // Quad is implicitly flat so we enforce flat dimensions
setDimensions(getDimensions()); setUnscaledDimensions(getUnscaledDimensions());
break; break;
default: default:
_type = EntityTypes::Shape; _type = EntityTypes::Shape;
@ -204,15 +204,15 @@ void ShapeEntityItem::setColor(const QColor& value) {
setAlpha(value.alpha()); setAlpha(value.alpha());
} }
void ShapeEntityItem::setDimensions(const glm::vec3& value) { void ShapeEntityItem::setUnscaledDimensions(const glm::vec3& value) {
const float MAX_FLAT_DIMENSION = 0.0001f; const float MAX_FLAT_DIMENSION = 0.0001f;
if ((_shape == entity::Shape::Circle || _shape == entity::Shape::Quad) && value.y > MAX_FLAT_DIMENSION) { if ((_shape == entity::Shape::Circle || _shape == entity::Shape::Quad) && value.y > MAX_FLAT_DIMENSION) {
// enforce flatness in Y // enforce flatness in Y
glm::vec3 newDimensions = value; glm::vec3 newDimensions = value;
newDimensions.y = MAX_FLAT_DIMENSION; newDimensions.y = MAX_FLAT_DIMENSION;
EntityItem::setDimensions(newDimensions); EntityItem::setUnscaledDimensions(newDimensions);
} else { } else {
EntityItem::setDimensions(value); EntityItem::setUnscaledDimensions(value);
} }
} }
@ -256,7 +256,7 @@ void ShapeEntityItem::debugDump() const {
qCDebug(entities) << " collisionShapeType:" << ShapeInfo::getNameForShapeType(getShapeType()); qCDebug(entities) << " collisionShapeType:" << ShapeInfo::getNameForShapeType(getShapeType());
qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2]; qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2];
qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition()); qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition());
qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions()); qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions());
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now); qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
qCDebug(entities) << "SHAPE EntityItem Ptr:" << this; qCDebug(entities) << "SHAPE EntityItem Ptr:" << this;
} }
@ -266,7 +266,7 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) {
// This will be called whenever DIRTY_SHAPE flag (set by dimension change, etc) // This will be called whenever DIRTY_SHAPE flag (set by dimension change, etc)
// is set. // is set.
const glm::vec3 entityDimensions = getDimensions(); const glm::vec3 entityDimensions = getScaledDimensions();
switch (_shape){ switch (_shape){
case entity::Shape::Quad: case entity::Shape::Quad:

View file

@ -80,7 +80,7 @@ public:
const rgbColor& getColor() const { return _color; } const rgbColor& getColor() const { return _color; }
void setColor(const rgbColor& value); void setColor(const rgbColor& value);
void setDimensions(const glm::vec3& value) override; void setUnscaledDimensions(const glm::vec3& value) override;
xColor getXColor() const; xColor getXColor() const;
void setColor(const xColor& value); void setColor(const xColor& value);

View file

@ -41,9 +41,9 @@ TextEntityItem::TextEntityItem(const EntityItemID& entityItemID) : EntityItem(en
const float TEXT_ENTITY_ITEM_FIXED_DEPTH = 0.01f; const float TEXT_ENTITY_ITEM_FIXED_DEPTH = 0.01f;
void TextEntityItem::setDimensions(const glm::vec3& value) { void TextEntityItem::setUnscaledDimensions(const glm::vec3& value) {
// NOTE: Text Entities always have a "depth" of 1cm. // NOTE: Text Entities always have a "depth" of 1cm.
EntityItem::setDimensions(glm::vec3(value.x, value.y, TEXT_ENTITY_ITEM_FIXED_DEPTH)); EntityItem::setUnscaledDimensions(glm::vec3(value.x, value.y, TEXT_ENTITY_ITEM_FIXED_DEPTH));
} }
EntityItemProperties TextEntityItem::getProperties(EntityPropertyFlags desiredProperties) const { EntityItemProperties TextEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
@ -132,7 +132,7 @@ bool TextEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const
bool& keepSearching, OctreeElementPointer& element, float& distance, bool& keepSearching, OctreeElementPointer& element, float& distance,
BoxFace& face, glm::vec3& surfaceNormal, BoxFace& face, glm::vec3& surfaceNormal,
void** intersectedObject, bool precisionPicking) const { void** intersectedObject, bool precisionPicking) const {
glm::vec3 dimensions = getDimensions(); glm::vec3 dimensions = getScaledDimensions();
glm::vec2 xyDimensions(dimensions.x, dimensions.y); glm::vec2 xyDimensions(dimensions.x, dimensions.y);
glm::quat rotation = getWorldOrientation(); glm::quat rotation = getWorldOrientation();
glm::vec3 position = getWorldPosition() + rotation * glm::vec3 position = getWorldPosition() + rotation *

View file

@ -23,7 +23,7 @@ public:
ALLOW_INSTANTIATION // This class can be instantiated ALLOW_INSTANTIATION // This class can be instantiated
/// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately /// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately
virtual void setDimensions(const glm::vec3& value) override; virtual void setUnscaledDimensions(const glm::vec3& value) override;
virtual ShapeType getShapeType() const override { return SHAPE_TYPE_BOX; } virtual ShapeType getShapeType() const override { return SHAPE_TYPE_BOX; }
// methods for getting/setting all properties of an entity // methods for getting/setting all properties of an entity

View file

@ -36,9 +36,9 @@ WebEntityItem::WebEntityItem(const EntityItemID& entityItemID) : EntityItem(enti
const float WEB_ENTITY_ITEM_FIXED_DEPTH = 0.01f; const float WEB_ENTITY_ITEM_FIXED_DEPTH = 0.01f;
void WebEntityItem::setDimensions(const glm::vec3& value) { void WebEntityItem::setUnscaledDimensions(const glm::vec3& value) {
// NOTE: Web Entities always have a "depth" of 1cm. // NOTE: Web Entities always have a "depth" of 1cm.
EntityItem::setDimensions(glm::vec3(value.x, value.y, WEB_ENTITY_ITEM_FIXED_DEPTH)); EntityItem::setUnscaledDimensions(glm::vec3(value.x, value.y, WEB_ENTITY_ITEM_FIXED_DEPTH));
} }
EntityItemProperties WebEntityItem::getProperties(EntityPropertyFlags desiredProperties) const { EntityItemProperties WebEntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
@ -109,7 +109,7 @@ bool WebEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const g
bool& keepSearching, OctreeElementPointer& element, float& distance, bool& keepSearching, OctreeElementPointer& element, float& distance,
BoxFace& face, glm::vec3& surfaceNormal, BoxFace& face, glm::vec3& surfaceNormal,
void** intersectedObject, bool precisionPicking) const { void** intersectedObject, bool precisionPicking) const {
glm::vec3 dimensions = getDimensions(); glm::vec3 dimensions = getScaledDimensions();
glm::vec2 xyDimensions(dimensions.x, dimensions.y); glm::vec2 xyDimensions(dimensions.x, dimensions.y);
glm::quat rotation = getWorldOrientation(); glm::quat rotation = getWorldOrientation();
glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint())); glm::vec3 position = getWorldPosition() + rotation * (dimensions * (ENTITY_ITEM_DEFAULT_REGISTRATION_POINT - getRegistrationPoint()));

View file

@ -22,7 +22,7 @@ public:
ALLOW_INSTANTIATION // This class can be instantiated ALLOW_INSTANTIATION // This class can be instantiated
/// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately /// set dimensions in domain scale units (0.0 - 1.0) this will also reset radius appropriately
virtual void setDimensions(const glm::vec3& value) override; virtual void setUnscaledDimensions(const glm::vec3& value) override;
virtual ShapeType getShapeType() const override { return SHAPE_TYPE_BOX; } virtual ShapeType getShapeType() const override { return SHAPE_TYPE_BOX; }
// methods for getting/setting all properties of an entity // methods for getting/setting all properties of an entity

View file

@ -242,7 +242,7 @@ void ZoneEntityItem::debugDump() const {
quint64 now = usecTimestampNow(); quint64 now = usecTimestampNow();
qCDebug(entities) << " ZoneEntityItem id:" << getEntityItemID() << "---------------------------------------------"; qCDebug(entities) << " ZoneEntityItem id:" << getEntityItemID() << "---------------------------------------------";
qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition()); qCDebug(entities) << " position:" << debugTreeVector(getWorldPosition());
qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions()); qCDebug(entities) << " dimensions:" << debugTreeVector(getScaledDimensions());
qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now); qCDebug(entities) << " getLastEdited:" << debugTime(getLastEdited(), now);
qCDebug(entities) << " _backgroundMode:" << EntityItemProperties::getBackgroundModeString(_backgroundMode); qCDebug(entities) << " _backgroundMode:" << EntityItemProperties::getBackgroundModeString(_backgroundMode);
qCDebug(entities) << " _hazeMode:" << EntityItemProperties::getHazeModeString(_hazeMode); qCDebug(entities) << " _hazeMode:" << EntityItemProperties::getHazeModeString(_hazeMode);

View file

@ -594,47 +594,72 @@ void Model::calculateTriangleSets() {
} }
} }
void Model::setVisibleInScene(bool newValue, const render::ScenePointer& scene) { void Model::setVisibleInScene(bool isVisible, const render::ScenePointer& scene) {
if (_isVisible != newValue) { if (_isVisible != isVisible) {
_isVisible = newValue; _isVisible = isVisible;
bool isLayeredInFront = _isLayeredInFront;
bool isLayeredInHUD = _isLayeredInHUD;
render::Transaction transaction; render::Transaction transaction;
foreach (auto item, _modelMeshRenderItemsMap.keys()) { foreach (auto item, _modelMeshRenderItemsMap.keys()) {
transaction.resetItem(item, _modelMeshRenderItemsMap[item]); transaction.updateItem<ModelMeshPartPayload>(item, [isVisible, isLayeredInFront, isLayeredInHUD](ModelMeshPartPayload& data) {
data.setKey(isVisible, isLayeredInFront || isLayeredInHUD);
});
} }
foreach(auto item, _collisionRenderItemsMap.keys()) { foreach(auto item, _collisionRenderItemsMap.keys()) {
transaction.resetItem(item, _collisionRenderItemsMap[item]); transaction.updateItem<ModelMeshPartPayload>(item, [isVisible, isLayeredInFront, isLayeredInHUD](ModelMeshPartPayload& data) {
data.setKey(isVisible, isLayeredInFront || isLayeredInHUD);
});
} }
scene->enqueueTransaction(transaction); scene->enqueueTransaction(transaction);
} }
} }
void Model::setLayeredInFront(bool layered, const render::ScenePointer& scene) { void Model::setLayeredInFront(bool isLayeredInFront, const render::ScenePointer& scene) {
if (_isLayeredInFront != layered) { if (_isLayeredInFront != isLayeredInFront) {
_isLayeredInFront = layered; _isLayeredInFront = isLayeredInFront;
bool isVisible = _isVisible;
bool isLayeredInHUD = _isLayeredInHUD;
render::Transaction transaction; render::Transaction transaction;
foreach(auto item, _modelMeshRenderItemsMap.keys()) { foreach(auto item, _modelMeshRenderItemsMap.keys()) {
transaction.resetItem(item, _modelMeshRenderItemsMap[item]); transaction.updateItem<ModelMeshPartPayload>(item, [isVisible, isLayeredInFront, isLayeredInHUD](ModelMeshPartPayload& data) {
data.setKey(isVisible, isLayeredInFront || isLayeredInHUD);
data.setLayer(isLayeredInFront, isLayeredInHUD);
});
} }
foreach(auto item, _collisionRenderItemsMap.keys()) { foreach(auto item, _collisionRenderItemsMap.keys()) {
transaction.resetItem(item, _collisionRenderItemsMap[item]); transaction.updateItem<ModelMeshPartPayload>(item, [isVisible, isLayeredInFront, isLayeredInHUD](ModelMeshPartPayload& data) {
data.setKey(isVisible, isLayeredInFront || isLayeredInHUD);
data.setLayer(isLayeredInFront, isLayeredInHUD);
});
} }
scene->enqueueTransaction(transaction); scene->enqueueTransaction(transaction);
} }
} }
void Model::setLayeredInHUD(bool layered, const render::ScenePointer& scene) { void Model::setLayeredInHUD(bool isLayeredInHUD, const render::ScenePointer& scene) {
if (_isLayeredInHUD != layered) { if (_isLayeredInHUD != isLayeredInHUD) {
_isLayeredInHUD = layered; _isLayeredInHUD = isLayeredInHUD;
bool isVisible = _isVisible;
bool isLayeredInFront = _isLayeredInFront;
render::Transaction transaction; render::Transaction transaction;
foreach(auto item, _modelMeshRenderItemsMap.keys()) { foreach(auto item, _modelMeshRenderItemsMap.keys()) {
transaction.resetItem(item, _modelMeshRenderItemsMap[item]); transaction.updateItem<ModelMeshPartPayload>(item, [isVisible, isLayeredInFront, isLayeredInHUD](ModelMeshPartPayload& data) {
data.setKey(isVisible, isLayeredInFront || isLayeredInHUD);
data.setLayer(isLayeredInFront, isLayeredInHUD);
});
} }
foreach(auto item, _collisionRenderItemsMap.keys()) { foreach(auto item, _collisionRenderItemsMap.keys()) {
transaction.resetItem(item, _collisionRenderItemsMap[item]); transaction.updateItem<ModelMeshPartPayload>(item, [isVisible, isLayeredInFront, isLayeredInHUD](ModelMeshPartPayload& data) {
data.setKey(isVisible, isLayeredInFront || isLayeredInHUD);
data.setLayer(isLayeredInFront, isLayeredInHUD);
});
} }
scene->enqueueTransaction(transaction); scene->enqueueTransaction(transaction);
} }

View file

@ -82,9 +82,9 @@ public:
const QUrl& getURL() const { return _url; } const QUrl& getURL() const { return _url; }
// new Scene/Engine rendering support // new Scene/Engine rendering support
void setVisibleInScene(bool newValue, const render::ScenePointer& scene); void setVisibleInScene(bool isVisible, const render::ScenePointer& scene);
void setLayeredInFront(bool layered, const render::ScenePointer& scene); void setLayeredInFront(bool isLayeredInFront, const render::ScenePointer& scene);
void setLayeredInHUD(bool layered, const render::ScenePointer& scene); void setLayeredInHUD(bool isLayeredInHUD, const render::ScenePointer& scene);
bool needsFixupInScene() const; bool needsFixupInScene() const;
bool needsReload() const { return _needsReload; } bool needsReload() const { return _needsReload; }

View file

@ -19,7 +19,7 @@
#include "SharedLogging.h" #include "SharedLogging.h"
const float defaultAACubeSize = 1.0f; const float defaultAACubeSize = 1.0f;
const int maxParentingChain = 30; const int MAX_PARENTING_CHAIN_SIZE = 30;
SpatiallyNestable::SpatiallyNestable(NestableType nestableType, QUuid id) : SpatiallyNestable::SpatiallyNestable(NestableType nestableType, QUuid id) :
_nestableType(nestableType), _nestableType(nestableType),
@ -28,6 +28,7 @@ SpatiallyNestable::SpatiallyNestable(NestableType nestableType, QUuid id) :
// set flags in _transform // set flags in _transform
_transform.setTranslation(glm::vec3(0.0f)); _transform.setTranslation(glm::vec3(0.0f));
_transform.setRotation(glm::quat()); _transform.setRotation(glm::quat());
_transform.setScale(1.0f);
_scaleChanged = usecTimestampNow(); _scaleChanged = usecTimestampNow();
_translationChanged = usecTimestampNow(); _translationChanged = usecTimestampNow();
_rotationChanged = usecTimestampNow(); _rotationChanged = usecTimestampNow();
@ -85,6 +86,9 @@ Transform SpatiallyNestable::getParentTransform(bool& success, int depth) const
} }
if (parent) { if (parent) {
result = parent->getTransform(_parentJointIndex, success, depth + 1); result = parent->getTransform(_parentJointIndex, success, depth + 1);
if (getScalesWithParent()) {
result.setScale(parent->scaleForChildren());
}
} }
return result; return result;
} }
@ -165,7 +169,7 @@ void SpatiallyNestable::setParentJointIndex(quint16 parentJointIndex) {
glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position, glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position,
const QUuid& parentID, int parentJointIndex, const QUuid& parentID, int parentJointIndex,
bool& success) { bool scalesWithParent, bool& success) {
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>(); QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
if (!parentFinder) { if (!parentFinder) {
success = false; success = false;
@ -189,6 +193,9 @@ glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position,
if (!success) { if (!success) {
return glm::vec3(0.0f); return glm::vec3(0.0f);
} }
if (scalesWithParent) {
parentTransform.setScale(parent->scaleForChildren());
}
} }
success = true; success = true;
@ -199,7 +206,7 @@ glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position,
glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation, glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation,
const QUuid& parentID, int parentJointIndex, const QUuid& parentID, int parentJointIndex,
bool& success) { bool scalesWithParent, bool& success) {
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>(); QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
if (!parentFinder) { if (!parentFinder) {
success = false; success = false;
@ -223,6 +230,9 @@ glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation,
if (!success) { if (!success) {
return glm::quat(); return glm::quat();
} }
if (scalesWithParent) {
parentTransform.setScale(parent->scaleForChildren());
}
} }
success = true; success = true;
@ -231,7 +241,7 @@ glm::quat SpatiallyNestable::worldToLocal(const glm::quat& orientation,
} }
glm::vec3 SpatiallyNestable::worldToLocalVelocity(const glm::vec3& velocity, const QUuid& parentID, glm::vec3 SpatiallyNestable::worldToLocalVelocity(const glm::vec3& velocity, const QUuid& parentID,
int parentJointIndex, bool& success) { int parentJointIndex, bool scalesWithParent, bool& success) {
SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success); SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success);
if (!success || !parent) { if (!success || !parent) {
return velocity; return velocity;
@ -240,6 +250,9 @@ glm::vec3 SpatiallyNestable::worldToLocalVelocity(const glm::vec3& velocity, con
if (!success) { if (!success) {
return velocity; return velocity;
} }
if (scalesWithParent) {
parentTransform.setScale(parent->scaleForChildren());
}
glm::vec3 parentVelocity = parent->getWorldVelocity(success); glm::vec3 parentVelocity = parent->getWorldVelocity(success);
if (!success) { if (!success) {
return velocity; return velocity;
@ -249,7 +262,7 @@ glm::vec3 SpatiallyNestable::worldToLocalVelocity(const glm::vec3& velocity, con
} }
glm::vec3 SpatiallyNestable::worldToLocalAngularVelocity(const glm::vec3& angularVelocity, const QUuid& parentID, glm::vec3 SpatiallyNestable::worldToLocalAngularVelocity(const glm::vec3& angularVelocity, const QUuid& parentID,
int parentJointIndex, bool& success) { int parentJointIndex, bool scalesWithParent, bool& success) {
SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success); SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success);
if (!success || !parent) { if (!success || !parent) {
return angularVelocity; return angularVelocity;
@ -258,12 +271,50 @@ glm::vec3 SpatiallyNestable::worldToLocalAngularVelocity(const glm::vec3& angula
if (!success) { if (!success) {
return angularVelocity; return angularVelocity;
} }
if (scalesWithParent) {
parentTransform.setScale(parent->scaleForChildren());
}
return glm::inverse(parentTransform.getRotation()) * angularVelocity; return glm::inverse(parentTransform.getRotation()) * angularVelocity;
} }
glm::vec3 SpatiallyNestable::worldToLocalDimensions(const glm::vec3& dimensions,
const QUuid& parentID, int parentJointIndex,
bool scalesWithParent, bool& success) {
if (!scalesWithParent) {
success = true;
return dimensions;
}
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
if (!parentFinder) {
success = false;
return dimensions;
}
Transform parentTransform;
auto parentWP = parentFinder->find(parentID, success);
if (!success) {
return dimensions;
}
auto parent = parentWP.lock();
if (!parentID.isNull() && !parent) {
success = false;
return dimensions;
}
success = true;
if (parent) {
return dimensions / parent->scaleForChildren();
}
return dimensions;
}
glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3& position, glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3& position,
const QUuid& parentID, int parentJointIndex, const QUuid& parentID, int parentJointIndex,
bool scalesWithParent,
bool& success) { bool& success) {
Transform result; Transform result;
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>(); QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
@ -289,6 +340,9 @@ glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3& position,
if (!success) { if (!success) {
return glm::vec3(0.0f); return glm::vec3(0.0f);
} }
if (scalesWithParent) {
parentTransform.setScale(parent->scaleForChildren());
}
} }
success = true; success = true;
@ -300,6 +354,7 @@ glm::vec3 SpatiallyNestable::localToWorld(const glm::vec3& position,
glm::quat SpatiallyNestable::localToWorld(const glm::quat& orientation, glm::quat SpatiallyNestable::localToWorld(const glm::quat& orientation,
const QUuid& parentID, int parentJointIndex, const QUuid& parentID, int parentJointIndex,
bool scalesWithParent,
bool& success) { bool& success) {
Transform result; Transform result;
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>(); QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
@ -325,7 +380,9 @@ glm::quat SpatiallyNestable::localToWorld(const glm::quat& orientation,
if (!success) { if (!success) {
return glm::quat(); return glm::quat();
} }
parentTransform.setScale(1.0f); if (scalesWithParent) {
parentTransform.setScale(parent->scaleForChildren());
}
} }
success = true; success = true;
@ -336,7 +393,7 @@ glm::quat SpatiallyNestable::localToWorld(const glm::quat& orientation,
} }
glm::vec3 SpatiallyNestable::localToWorldVelocity(const glm::vec3& velocity, const QUuid& parentID, glm::vec3 SpatiallyNestable::localToWorldVelocity(const glm::vec3& velocity, const QUuid& parentID,
int parentJointIndex, bool& success) { int parentJointIndex, bool scalesWithParent, bool& success) {
SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success); SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success);
if (!success || !parent) { if (!success || !parent) {
return velocity; return velocity;
@ -345,6 +402,9 @@ glm::vec3 SpatiallyNestable::localToWorldVelocity(const glm::vec3& velocity, con
if (!success) { if (!success) {
return velocity; return velocity;
} }
if (scalesWithParent) {
parentTransform.setScale(parent->scaleForChildren());
}
glm::vec3 parentVelocity = parent->getWorldVelocity(success); glm::vec3 parentVelocity = parent->getWorldVelocity(success);
if (!success) { if (!success) {
return velocity; return velocity;
@ -354,7 +414,7 @@ glm::vec3 SpatiallyNestable::localToWorldVelocity(const glm::vec3& velocity, con
} }
glm::vec3 SpatiallyNestable::localToWorldAngularVelocity(const glm::vec3& angularVelocity, const QUuid& parentID, glm::vec3 SpatiallyNestable::localToWorldAngularVelocity(const glm::vec3& angularVelocity, const QUuid& parentID,
int parentJointIndex, bool& success) { int parentJointIndex, bool scalesWithParent, bool& success) {
SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success); SpatiallyNestablePointer parent = SpatiallyNestable::findByID(parentID, success);
if (!success || !parent) { if (!success || !parent) {
return angularVelocity; return angularVelocity;
@ -363,10 +423,47 @@ glm::vec3 SpatiallyNestable::localToWorldAngularVelocity(const glm::vec3& angula
if (!success) { if (!success) {
return angularVelocity; return angularVelocity;
} }
if (scalesWithParent) {
parentTransform.setScale(parent->scaleForChildren());
}
return parentTransform.getRotation() * angularVelocity; return parentTransform.getRotation() * angularVelocity;
} }
glm::vec3 SpatiallyNestable::localToWorldDimensions(const glm::vec3& dimensions,
const QUuid& parentID, int parentJointIndex, bool scalesWithParent,
bool& success) {
if (!scalesWithParent) {
success = true;
return dimensions;
}
Transform result;
QSharedPointer<SpatialParentFinder> parentFinder = DependencyManager::get<SpatialParentFinder>();
if (!parentFinder) {
success = false;
return dimensions;
}
Transform parentTransform;
auto parentWP = parentFinder->find(parentID, success);
if (!success) {
return dimensions;
}
auto parent = parentWP.lock();
if (!parentID.isNull() && !parent) {
success = false;
return dimensions;
}
success = true;
if (parent) {
return dimensions * parent->scaleForChildren();
}
return dimensions;
}
glm::vec3 SpatiallyNestable::getWorldPosition(bool& success) const { glm::vec3 SpatiallyNestable::getWorldPosition(bool& success) const {
return getTransform(success).getTranslation(); return getTransform(success).getTranslation();
} }
@ -615,10 +712,10 @@ const Transform SpatiallyNestable::getTransform(int jointIndex, bool& success, i
// 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.
Transform jointInWorldFrame; Transform jointInWorldFrame;
if (depth > maxParentingChain) { if (depth > MAX_PARENTING_CHAIN_SIZE) {
success = false; success = false;
// someone created a loop. break it... // someone created a loop. break it...
qCDebug(shared) << "Parenting loop detected."; qCDebug(shared) << "Parenting loop detected: " << getID();
SpatiallyNestablePointer _this = getThisPointer(); SpatiallyNestablePointer _this = getThisPointer();
_this->setParentID(QUuid()); _this->setParentID(QUuid());
bool setPositionSuccess; bool setPositionSuccess;

View file

@ -50,19 +50,28 @@ public:
virtual quint16 getParentJointIndex() const { return _parentJointIndex; } virtual quint16 getParentJointIndex() const { return _parentJointIndex; }
virtual void setParentJointIndex(quint16 parentJointIndex); virtual void setParentJointIndex(quint16 parentJointIndex);
static glm::vec3 worldToLocal(const glm::vec3& position, const QUuid& parentID, int parentJointIndex, bool& success); static glm::vec3 worldToLocal(const glm::vec3& position, const QUuid& parentID, int parentJointIndex,
static glm::quat worldToLocal(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex, bool& success); bool scalesWithParent, bool& success);
static glm::quat worldToLocal(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex,
bool scalesWithParent, bool& success);
static glm::vec3 worldToLocalVelocity(const glm::vec3& velocity, const QUuid& parentID, static glm::vec3 worldToLocalVelocity(const glm::vec3& velocity, const QUuid& parentID,
int parentJointIndex, bool& success); int parentJointIndex, bool scalesWithParent, bool& success);
static glm::vec3 worldToLocalAngularVelocity(const glm::vec3& angularVelocity, const QUuid& parentID, static glm::vec3 worldToLocalAngularVelocity(const glm::vec3& angularVelocity, const QUuid& parentID,
int parentJointIndex, bool& success); int parentJointIndex, bool scalesWithParent, bool& success);
static glm::vec3 worldToLocalDimensions(const glm::vec3& dimensions, const QUuid& parentID,
int parentJointIndex, bool scalesWithParent, bool& success);
static glm::vec3 localToWorld(const glm::vec3& position, const QUuid& parentID, int parentJointIndex, bool& success); static glm::vec3 localToWorld(const glm::vec3& position, const QUuid& parentID, int parentJointIndex,
static glm::quat localToWorld(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex, bool& success); bool scalesWithParent, bool& success);
static glm::quat localToWorld(const glm::quat& orientation, const QUuid& parentID, int parentJointIndex,
bool scalesWithParent, bool& success);
static glm::vec3 localToWorldVelocity(const glm::vec3& velocity, static glm::vec3 localToWorldVelocity(const glm::vec3& velocity,
const QUuid& parentID, int parentJointIndex, bool& success); const QUuid& parentID, int parentJointIndex, bool scalesWithParent, bool& success);
static glm::vec3 localToWorldAngularVelocity(const glm::vec3& angularVelocity, static glm::vec3 localToWorldAngularVelocity(const glm::vec3& angularVelocity,
const QUuid& parentID, int parentJointIndex, bool& success); const QUuid& parentID, int parentJointIndex,
bool scalesWithParent, bool& success);
static glm::vec3 localToWorldDimensions(const glm::vec3& dimensions, const QUuid& parentID,
int parentJointIndex, bool scalesWithParent, bool& success);
static QString nestableTypeToString(NestableType nestableType); static QString nestableTypeToString(NestableType nestableType);
@ -140,6 +149,9 @@ public:
virtual glm::vec3 getLocalSNScale() const; virtual glm::vec3 getLocalSNScale() const;
virtual void setLocalSNScale(const glm::vec3& scale); virtual void setLocalSNScale(const glm::vec3& scale);
virtual bool getScalesWithParent() const { return false; }
virtual glm::vec3 scaleForChildren() const { return glm::vec3(1.0f); }
QList<SpatiallyNestablePointer> getChildren() const; QList<SpatiallyNestablePointer> getChildren() const;
bool hasChildren() const; bool hasChildren() const;

View file

@ -103,6 +103,7 @@
case 'transactionHistory_linkClicked': case 'transactionHistory_linkClicked':
tablet.gotoWebScreen(message.marketplaceLink, MARKETPLACES_INJECT_SCRIPT_URL); tablet.gotoWebScreen(message.marketplaceLink, MARKETPLACES_INJECT_SCRIPT_URL);
break; break;
case 'goToPurchases_fromWalletHome':
case 'goToPurchases': case 'goToPurchases':
tablet.pushOntoStack(MARKETPLACE_PURCHASES_QML_PATH); tablet.pushOntoStack(MARKETPLACE_PURCHASES_QML_PATH);
break; break;

View file

@ -29,7 +29,7 @@
var commerceMode = false; var commerceMode = false;
var userIsLoggedIn = false; var userIsLoggedIn = false;
var walletNeedsSetup = false; var walletNeedsSetup = false;
var metaverseServerURL = "https://metaverse.highfidelity.com"; var marketplaceBaseURL = "https://highfidelity.com";
function injectCommonCode(isDirectoryPage) { function injectCommonCode(isDirectoryPage) {
@ -58,7 +58,7 @@
); );
// Footer. // Footer.
var isInitialHiFiPage = location.href === metaverseServerURL + "/marketplace?"; var isInitialHiFiPage = location.href === marketplaceBaseURL + "/marketplace?";
$("body").append( $("body").append(
'<div id="marketplace-navigation">' + '<div id="marketplace-navigation">' +
(!isInitialHiFiPage ? '<input id="back-button" type="button" class="white" value="&lt; Back" />' : '') + (!isInitialHiFiPage ? '<input id="back-button" type="button" class="white" value="&lt; Back" />' : '') +
@ -70,7 +70,7 @@
// Footer actions. // Footer actions.
$("#back-button").on("click", function () { $("#back-button").on("click", function () {
(document.referrer !== "") ? window.history.back() : window.location = (metaverseServerURL + "/marketplace?"); (document.referrer !== "") ? window.history.back() : window.location = (marketplaceBaseURL + "/marketplace?");
}); });
$("#all-markets").on("click", function () { $("#all-markets").on("click", function () {
EventBridge.emitWebEvent(GOTO_DIRECTORY); EventBridge.emitWebEvent(GOTO_DIRECTORY);
@ -89,7 +89,7 @@
window.location = "https://clara.io/library?gameCheck=true&public=true"; window.location = "https://clara.io/library?gameCheck=true&public=true";
}); });
$('#exploreHifiMarketplace').on('click', function () { $('#exploreHifiMarketplace').on('click', function () {
window.location = "http://www.highfidelity.com/marketplace"; window.location = marketplaceBaseURL + "/marketplace";
}); });
} }
@ -658,9 +658,9 @@
var HIFI_ITEM_PAGE = 3; var HIFI_ITEM_PAGE = 3;
var pageType = DIRECTORY; var pageType = DIRECTORY;
if (location.href.indexOf("highfidelity.com/") !== -1) { pageType = HIFI; } if (location.href.indexOf(marketplaceBaseURL + "/") !== -1) { pageType = HIFI; }
if (location.href.indexOf("clara.io/") !== -1) { pageType = CLARA; } if (location.href.indexOf("clara.io/") !== -1) { pageType = CLARA; }
if (location.href.indexOf("highfidelity.com/marketplace/items/") !== -1) { pageType = HIFI_ITEM_PAGE; } if (location.href.indexOf(marketplaceBaseURL + "/marketplace/items/") !== -1) { pageType = HIFI_ITEM_PAGE; }
injectCommonCode(pageType === DIRECTORY); injectCommonCode(pageType === DIRECTORY);
switch (pageType) { switch (pageType) {
@ -694,7 +694,10 @@
commerceMode = !!parsedJsonMessage.data.commerceMode; commerceMode = !!parsedJsonMessage.data.commerceMode;
userIsLoggedIn = !!parsedJsonMessage.data.userIsLoggedIn; userIsLoggedIn = !!parsedJsonMessage.data.userIsLoggedIn;
walletNeedsSetup = !!parsedJsonMessage.data.walletNeedsSetup; walletNeedsSetup = !!parsedJsonMessage.data.walletNeedsSetup;
metaverseServerURL = parsedJsonMessage.data.metaverseServerURL; marketplaceBaseURL = parsedJsonMessage.data.metaverseServerURL;
if (marketplaceBaseURL.indexOf('metaverse.') !== -1) {
marketplaceBaseURL = marketplaceBaseURL.replace('metaverse.', '');
}
injectCode(); injectCode();
} }
} }

View file

@ -8,7 +8,8 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
/* global Tablet, Script, HMD, UserActivityLogger, Entities */ /* global Tablet, Script, HMD, UserActivityLogger, Entities, Account, Wallet, ContextOverlay, Settings, Camera, Vec3,
Quat, MyAvatar, Clipboard, Menu, Grid, Uuid, GlobalServices, openLoginWindow */
/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */ /* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */
var selectionDisplay = null; // for gridTool.js to ignore var selectionDisplay = null; // for gridTool.js to ignore
@ -219,6 +220,41 @@ var selectionDisplay = null; // for gridTool.js to ignore
function rezEntity(itemHref, isWearable) { function rezEntity(itemHref, isWearable) {
var success = Clipboard.importEntities(itemHref); var success = Clipboard.importEntities(itemHref);
var wearableLocalPosition = null;
var wearableLocalRotation = null;
var wearableLocalDimensions = null;
var wearableDimensions = null;
if (isWearable) {
var wearableTransforms = Settings.getValue("io.highfidelity.avatarStore.checkOut.transforms");
if (!wearableTransforms) {
// TODO delete this clause
wearableTransforms = Settings.getValue("io.highfidelity.avatarStore.checkOut.tranforms");
}
var certPos = itemHref.search("certificate_id="); // TODO how do I parse a URL from here?
if (certPos >= 0) {
certPos += 15; // length of "certificate_id="
var certURLEncoded = itemHref.substring(certPos);
var certB64Encoded = decodeURIComponent(certURLEncoded);
for (var key in wearableTransforms) {
if (wearableTransforms.hasOwnProperty(key)) {
var certificateTransforms = wearableTransforms[key].certificateTransforms;
if (certificateTransforms) {
for (var certID in certificateTransforms) {
if (certificateTransforms.hasOwnProperty(certID) &&
certID == certB64Encoded) {
var certificateTransform = certificateTransforms[certID];
wearableLocalPosition = certificateTransform.localPosition;
wearableLocalRotation = certificateTransform.localRotation;
wearableLocalDimensions = certificateTransform.localDimensions;
wearableDimensions = certificateTransform.dimensions;
}
}
}
}
}
}
}
if (success) { if (success) {
var VERY_LARGE = 10000; var VERY_LARGE = 10000;
@ -287,6 +323,24 @@ var selectionDisplay = null; // for gridTool.js to ignore
} }
} }
} }
if (isWearable) {
// apply the relative offsets saved during checkout
var offsets = {};
if (wearableLocalPosition) {
offsets.localPosition = wearableLocalPosition;
}
if (wearableLocalRotation) {
offsets.localRotation = wearableLocalRotation;
}
if (wearableLocalDimensions) {
offsets.localDimensions = wearableLocalDimensions;
} else if (wearableDimensions) {
offsets.dimensions = wearableDimensions;
}
// we currently assume a wearable is a single entity
Entities.editEntity(pastedEntityIDs[0], offsets);
}
} else { } else {
Window.notifyEditError("Can't import entities: entities would be out of bounds."); Window.notifyEditError("Can't import entities: entities would be out of bounds.");
} }