Merge branch 'master' of github.com:highfidelity/hifi into 21616-addPerTileThreshold

This commit is contained in:
NissimHadar 2019-03-07 13:35:57 -08:00
commit 6cc510a5a9
26 changed files with 211 additions and 109 deletions

View file

@ -1016,8 +1016,8 @@
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/run_fwd.fbx",
"startFrame": 0.0,
"endFrame": 21.0,
"startFrame": 1.0,
"endFrame": 22.0,
"timeScale": 1.0,
"loopFlag": true
},

View file

@ -40,9 +40,9 @@ Rectangle {
property string itemHref;
property string itemAuthor;
property int itemEdition: -1;
property bool hasSomethingToTradeIn: alreadyOwned && (itemEdition > 0); // i.e., don't trade in your artist's proof
property bool isTradingIn: isUpdating && hasSomethingToTradeIn;
property bool isStocking: availability === 'not for sale' && creator === Account.username;
property bool hasSomethingToTradeIn: itemEdition > 0; // i.e., don't trade in your artist's proof
property bool isTradingIn: canUpdate && hasSomethingToTradeIn;
property bool isStocking: (availability === 'not for sale') && (creator === Account.username) && !updated_item_id;
property string certificateId;
property double balanceAfterPurchase;
property bool alreadyOwned: false; // Including proofs
@ -59,8 +59,9 @@ Rectangle {
property bool canRezCertifiedItems: Entities.canRezCertified() || Entities.canRezTmpCertified();
property string referrer;
property bool isInstalled;
property bool isUpdating;
property bool canUpdate;
property string availability: "available";
property string updated_item_id: "";
property string creator: "";
property string baseAppURL;
property int currentUpdatesPage: 1;
@ -144,6 +145,7 @@ Rectangle {
}
onAvailableUpdatesResult: {
// Answers the updatable original item cert data still owned by this user that are EITHER instances of this marketplace id, or update to this marketplace id.
if (result.status !== 'success') {
console.log("Failed to get Available Updates", result.data.message);
} else {
@ -155,7 +157,7 @@ Rectangle {
if (root.itemEdition !== -1 && root.itemEdition !== parseInt(result.data.updates[i].edition_number)) {
continue;
}
root.isUpdating = true;
root.canUpdate = true;
root.baseItemName = result.data.updates[i].base_item_title;
// This CertID is the one corresponding to the base item CertID that the user already owns
root.certificateId = result.data.updates[i].certificate_id;
@ -166,7 +168,7 @@ Rectangle {
}
}
if (result.data.updates.length === 0 || root.isUpdating) {
if (result.data.updates.length === 0 || root.canUpdate) {
root.availableUpdatesReceived = true;
refreshBuyUI();
} else {
@ -178,7 +180,7 @@ Rectangle {
onUpdateItemResult: {
if (result.status !== 'success') {
failureErrorText.text = result.message;
failureErrorText.text = result.data ? (result.data.message || "Unknown Error") : JSON.stringify(result);
root.activeView = "checkoutFailure";
} else {
root.itemHref = result.data.download_url;
@ -266,13 +268,6 @@ Rectangle {
}
}
}
MouseArea {
enabled: titleBarContainer.usernameDropdownVisible;
anchors.fill: parent;
onClicked: {
titleBarContainer.usernameDropdownVisible = false;
}
}
//
// TITLE BAR END
//
@ -481,7 +476,7 @@ Rectangle {
FiraSansSemiBold {
id: itemPriceText;
text: isTradingIn ? "FREE\nUPDATE" :
(isStocking ? "Free for creator" :
(isStocking ? "Free for creator" :
((root.itemPrice === -1) ? "--" : ((root.itemPrice > 0) ? root.itemPrice : "FREE")));
// Text size
size: isTradingIn ? 20 : 26;
@ -580,7 +575,7 @@ Rectangle {
// "View in Inventory" button
HifiControlsUit.Button {
id: viewInMyPurchasesButton;
visible: isCertified && dataReady && (isUpdating ? !hasSomethingToTradeIn : alreadyOwned);
visible: isCertified && dataReady && (isTradingIn ? hasSomethingToTradeIn : alreadyOwned);
color: hifi.buttons.blue;
colorScheme: hifi.colorSchemes.light;
anchors.top: buyTextContainer.visible ? buyTextContainer.bottom : checkoutActionButtonsContainer.top;
@ -588,9 +583,9 @@ Rectangle {
height: 50;
anchors.left: parent.left;
anchors.right: parent.right;
text: root.isUpdating ? "UPDATE TO THIS ITEM FOR FREE" : "VIEW THIS ITEM IN YOUR INVENTORY";
text: (canUpdate && !isTradingIn) ? "UPDATE TO THIS ITEM FOR FREE" : "VIEW THIS ITEM IN YOUR INVENTORY";
onClicked: {
if (root.isUpdating) {
if (root.canUpdate) {
sendToScript({method: 'checkout_goToPurchases', filterText: root.baseItemName});
} else {
sendToScript({method: 'checkout_goToPurchases', filterText: root.itemName});
@ -602,7 +597,11 @@ Rectangle {
HifiControlsUit.Button {
id: buyButton;
visible: isTradingIn || !alreadyOwned || isStocking || !(root.itemType === "avatar" || root.itemType === "app");
enabled: (root.balanceAfterPurchase >= 0 && dataReady) || (!root.isCertified) || root.isUpdating;
property bool checkBalance: dataReady && (root.availability === "available")
enabled: (checkBalance && (balanceAfterPurchase >= 0)) || !isCertified || isTradingIn || isStocking;
text: isTradingIn ? "Confirm Update" :
(enabled ? (viewInMyPurchasesButton.visible ? "Get It Again" : (dataReady ? "Get Item" : "--")) :
(checkBalance ? "Insufficient Funds" : availability))
color: viewInMyPurchasesButton.visible ? hifi.buttons.white : hifi.buttons.blue;
colorScheme: hifi.colorSchemes.light;
anchors.top: viewInMyPurchasesButton.visible ? viewInMyPurchasesButton.bottom :
@ -611,13 +610,6 @@ Rectangle {
height: 50;
anchors.left: parent.left;
anchors.right: parent.right;
text: isTradingIn ?
"CONFIRM UPDATE" :
(((root.isCertified) ?
(dataReady ?
((viewInMyPurchasesButton.visible && !root.isUpdating) ? "Get It Again" : "Confirm") :
"--") :
"Get Item"));
onClicked: {
if (isTradingIn) {
// If we're updating an app, the existing app needs to be uninstalled.
@ -1110,6 +1102,7 @@ Rectangle {
root.itemAuthor = result.data.creator;
root.itemType = result.data.item_type || "unknown";
root.availability = result.data.availability;
root.updated_item_id = result.data.updated_item_id || ""
root.creator = result.data.creator;
if (root.itemType === "unknown") {
root.itemHref = result.data.review_url;
@ -1209,7 +1202,7 @@ Rectangle {
buyText.text = "";
// If the user IS on the checkout page for the updated version of an owned item...
if (root.isUpdating) {
if (root.canUpdate) {
// If the user HAS already selected a specific edition to update...
if (hasSomethingToTradeIn) {
buyText.text = "By pressing \"Confirm Update\", you agree to trade in your old item for the updated item that replaces it.";

View file

@ -112,7 +112,7 @@ Rectangle {
marketplaceItem.image_url = result.data.thumbnail_url;
marketplaceItem.name = result.data.title;
marketplaceItem.likes = result.data.likes;
if(result.data.has_liked !== undefined) {
if (result.data.has_liked !== undefined) {
marketplaceItem.liked = result.data.has_liked;
}
marketplaceItem.creator = result.data.creator;
@ -122,6 +122,7 @@ Rectangle {
marketplaceItem.attributions = result.data.attributions;
marketplaceItem.license = result.data.license;
marketplaceItem.availability = result.data.availability;
marketplaceItem.updated_item_id = result.data.updated_item_id || "";
marketplaceItem.created_at = result.data.created_at;
marketplaceItemScrollView.contentHeight = marketplaceItemContent.height;
itemsList.visible = false;
@ -979,7 +980,6 @@ Rectangle {
xhr.open("GET", url);
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
console.log(xhr.responseText);
licenseText.text = xhr.responseText;
licenseInfo.visible = true;
}

View file

@ -2,7 +2,7 @@
// MarketplaceListItem.qml
// qml/hifi/commerce/marketplace
//
// MarketplaceListItem
// MarketplaceItem
//
// Created by Roxanne Skelly on 2019-01-22
// Copyright 2019 High Fidelity, Inc.
@ -34,6 +34,7 @@ Rectangle {
property var categories: []
property int price: 0
property string availability: "unknown"
property string updated_item_id: ""
property var attributions: []
property string description: ""
property string license: ""
@ -42,7 +43,6 @@ Rectangle {
property bool isLoggedIn: false;
property int edition: -1;
property bool supports3DHTML: false;
onCategoriesChanged: {
categoriesListModel.clear();
@ -52,7 +52,7 @@ Rectangle {
}
onDescriptionChanged: {
if(root.supports3DHTML) {
descriptionTextModel.clear();
descriptionTextModel.append({text: description});
@ -264,17 +264,14 @@ Rectangle {
}
height: 50
property bool isNFS: availability === "not for sale" // Note: server will say "sold out" or "invalidated" before it says NFS
property bool isMine: creator === Account.username
property bool isUpgrade: root.edition >= 0
property int costToMe: ((isMine && isNFS) || isUpgrade) ? 0 : price
property bool isAvailable: costToMe >= 0
text: isUpgrade ? "UPGRADE FOR FREE" : (isAvailable ? (costToMe || "FREE") : availability)
enabled: isAvailable
buttonGlyph: isAvailable ? (costToMe ? hifi.glyphs.hfc : "") : ""
property bool isUpdate: root.edition >= 0 // Special case of updating from a specific older item
property bool isStocking: (creator === Account.username) && (availability === "not for sale") && !updated_item_id // Note: server will say "sold out" or "invalidated" before it says NFS
property bool isFreeSpecial: isStocking || isUpdate
enabled: isFreeSpecial || (availability === 'available')
buttonGlyph: (enabled && !isUpdate && (price > 0)) ? hifi.glyphs.hfc : ""
text: isUpdate ? "UPDATE FOR FREE" : (isStocking ? "FREE STOCK" : (enabled ? (price || "FREE") : availability))
color: hifi.buttons.blue
onClicked: root.buy();
}

View file

@ -380,7 +380,7 @@ Item {
if (updateButton.visible && uninstallButton.visible) {
item.itemButtonText = "";
item.glyphSize = 20;
} else {
} else if (item) {
item.itemButtonText = "Send to Trash";
item.glyphSize = 30;
}

View file

@ -40,10 +40,6 @@ Rectangle {
source: "images/wallet-bg.jpg";
}
Component.onDestruction: {
KeyboardScriptingInterface.raised = false;
}
Connections {
target: Commerce;

View file

@ -910,7 +910,7 @@ void MyAvatar::simulate(float deltaTime, bool inView) {
recorder->recordFrame(FRAME_TYPE, toFrame(*this));
}
locationChanged();
locationChanged(true, false);
// if a entity-child of this avatar has moved outside of its queryAACube, update the cube and tell the entity server.
auto entityTreeRenderer = qApp->getEntities();
EntityTreePointer entityTree = entityTreeRenderer ? entityTreeRenderer->getTree() : nullptr;
@ -920,6 +920,7 @@ void MyAvatar::simulate(float deltaTime, bool inView) {
zoneInteractionProperties = entityTreeRenderer->getZoneInteractionProperties();
EntityEditPacketSender* packetSender = qApp->getEntityEditPacketSender();
forEachDescendant([&](SpatiallyNestablePointer object) {
locationChanged(true, false);
// we need to update attached queryAACubes in our own local tree so point-select always works
// however we don't want to flood the update pipeline with AvatarEntity updates, so we assume
// others have all info required to properly update queryAACube of AvatarEntities on their end
@ -2324,23 +2325,25 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
std::shared_ptr<QMetaObject::Connection> skeletonConnection = std::make_shared<QMetaObject::Connection>();
*skeletonConnection = QObject::connect(_skeletonModel.get(), &SkeletonModel::skeletonLoaded, [this, skeletonModelChangeCount, skeletonConnection]() {
if (skeletonModelChangeCount == _skeletonModelChangeCount) {
if (skeletonModelChangeCount == _skeletonModelChangeCount) {
if (_fullAvatarModelName.isEmpty()) {
// Store the FST file name into preferences
const auto& mapping = _skeletonModel->getGeometry()->getMapping();
if (mapping.value("name").isValid()) {
_fullAvatarModelName = mapping.value("name").toString();
}
}
if (_fullAvatarModelName.isEmpty()) {
// Store the FST file name into preferences
const auto& mapping = _skeletonModel->getGeometry()->getMapping();
if (mapping.value("name").isValid()) {
_fullAvatarModelName = mapping.value("name").toString();
}
}
initHeadBones();
_skeletonModel->setCauterizeBoneSet(_headBoneSet);
_fstAnimGraphOverrideUrl = _skeletonModel->getGeometry()->getAnimGraphOverrideUrl();
initAnimGraph();
_skeletonModelLoaded = true;
}
QObject::disconnect(*skeletonConnection);
initHeadBones();
_skeletonModel->setCauterizeBoneSet(_headBoneSet);
_fstAnimGraphOverrideUrl = _skeletonModel->getGeometry()->getAnimGraphOverrideUrl();
initAnimGraph();
initFlowFromFST();
_skeletonModelLoaded = true;
}
QObject::disconnect(*skeletonConnection);
});
saveAvatarUrl();
@ -5384,6 +5387,15 @@ void MyAvatar::useFlow(bool isActive, bool isCollidable, const QVariantMap& phys
}
}
void MyAvatar::initFlowFromFST() {
if (_skeletonModel->isLoaded()) {
auto &flowData = _skeletonModel->getHFMModel().flowData;
if (flowData.shouldInitFlow()) {
useFlow(true, flowData.shouldInitCollisions(), flowData._physicsConfig, flowData._collisionsConfig);
}
}
}
void MyAvatar::sendPacket(const QUuid& entityID, const EntityItemProperties& properties) const {
auto treeRenderer = DependencyManager::get<EntityTreeRenderer>();
EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr;

View file

@ -1751,6 +1751,7 @@ private:
void updateCollisionSound(const glm::vec3& penetration, float deltaTime, float frequency);
void initHeadBones();
void initAnimGraph();
void initFlowFromFST();
// Avatar Preferences
QUrl _fullAvatarURLFromPreferences;

View file

@ -204,7 +204,8 @@ QString Overlays::overlayToEntityType(const QString& type) {
#define RENAME_PROP(o, e) \
{ \
auto iter = overlayProps.find(#o); \
if (iter != overlayProps.end()) { \
if (iter != overlayProps.end() && \
!overlayProps.contains(#e)) { \
overlayProps[#e] = iter.value(); \
} \
}
@ -493,15 +494,34 @@ EntityItemProperties Overlays::convertOverlayToEntityProperties(QVariantMap& ove
RENAME_PROP_CONVERT(p1, p1, [](const QVariant& v) { return vec3toVariant(glm::vec3(0.0f)); });
RENAME_PROP_CONVERT(p2, p2, [=](const QVariant& v) {
glm::vec3 position;
bool hasPosition = false;
glm::quat rotation;
bool hasRotation = false;
auto iter2 = overlayProps.find("position");
if (iter2 != overlayProps.end()) {
position = vec3FromVariant(iter2.value());
} else if (!add) {
EntityPropertyFlags desiredProperties;
desiredProperties += PROP_POSITION;
position = DependencyManager::get<EntityScriptingInterface>()->getEntityProperties(id, desiredProperties).getPosition();
hasPosition = true;
}
return vec3toVariant(vec3FromVariant(v) - position);
iter2 = overlayProps.find("rotation");
if (iter2 != overlayProps.end()) {
rotation = quatFromVariant(iter2.value());
hasRotation = true;
}
if (!add && !(hasPosition && hasRotation)) {
auto entity = DependencyManager::get<EntityTreeRenderer>()->getEntity(id);
if (entity) {
if (!hasPosition) {
position = entity->getWorldPosition();
}
if (!hasRotation) {
rotation = entity->getWorldOrientation();
}
}
}
return vec3toVariant(glm::inverse(rotation) * (vec3FromVariant(v) - position));
});
RENAME_PROP(localStart, p1);

View file

@ -928,9 +928,9 @@ void RenderableModelEntityItem::setJointTranslationsSet(const QVector<bool>& tra
_needsJointSimulation = true;
}
void RenderableModelEntityItem::locationChanged(bool tellPhysics) {
void RenderableModelEntityItem::locationChanged(bool tellPhysics, bool tellChildren) {
DETAILED_PERFORMANCE_TIMER("locationChanged");
EntityItem::locationChanged(tellPhysics);
EntityItem::locationChanged(tellPhysics, tellChildren);
auto model = getModel();
if (model && model->isLoaded()) {
model->updateRenderItems();
@ -1032,9 +1032,7 @@ void RenderableModelEntityItem::copyAnimationJointDataToModel() {
});
if (changed) {
forEachChild([&](SpatiallyNestablePointer object) {
object->locationChanged(false);
});
locationChanged(false, true);
}
}

View file

@ -108,7 +108,7 @@ public:
virtual void setJointTranslations(const QVector<glm::vec3>& translations) override;
virtual void setJointTranslationsSet(const QVector<bool>& translationsSet) override;
virtual void locationChanged(bool tellPhysics = true) override;
virtual void locationChanged(bool tellPhysics = true, bool tellChildren = true) override;
virtual int getJointIndex(const QString& name) const override;
virtual QStringList getJointNames() const override;

View file

@ -150,7 +150,7 @@ public:
virtual bool addToScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) override;
virtual void removeFromScene(const EntityItemPointer& self, const render::ScenePointer& scene, render::Transaction& transaction) override;
private:
virtual void locationChanged(bool tellPhysics = true) override { EntityItem::locationChanged(tellPhysics); notifyBoundChanged(); }
virtual void locationChanged(bool tellPhysics = true, bool tellChildren = true) override { EntityItem::locationChanged(tellPhysics, tellChildren); notifyBoundChanged(); }
virtual void dimensionsChanged() override { EntityItem::dimensionsChanged(); notifyBoundChanged(); }
void notifyBoundChanged();
void notifyChangedRenderItem();

View file

@ -1873,7 +1873,7 @@ void EntityItem::setParentID(const QUuid& value) {
glm::vec3 EntityItem::getScaledDimensions() const {
glm::vec3 scale = getSNScale();
return _unscaledDimensions * scale;
return getUnscaledDimensions() * scale;
}
void EntityItem::setScaledDimensions(const glm::vec3& value) {
@ -2593,7 +2593,7 @@ QList<EntityDynamicPointer> EntityItem::getActionsOfType(EntityDynamicType typeT
return result;
}
void EntityItem::locationChanged(bool tellPhysics) {
void EntityItem::locationChanged(bool tellPhysics, bool tellChildren) {
requiresRecalcBoxes();
if (tellPhysics) {
_flags |= Simulation::DIRTY_TRANSFORM;
@ -2602,7 +2602,7 @@ void EntityItem::locationChanged(bool tellPhysics) {
tree->entityChanged(getThisPointer());
}
}
SpatiallyNestable::locationChanged(tellPhysics); // tell all the children, also
SpatiallyNestable::locationChanged(tellPhysics, tellChildren);
std::pair<int32_t, glm::vec4> data(_spaceIndex, glm::vec4(getWorldPosition(), _boundingRadius));
emit spaceUpdate(data);
somethingChangedNotification();

View file

@ -518,7 +518,7 @@ public:
virtual bool getMeshes(MeshProxyList& result) { return true; }
virtual void locationChanged(bool tellPhysics = true) override;
virtual void locationChanged(bool tellPhysics = true, bool tellChildren = true) override;
virtual bool getScalesWithParent() const override;

View file

@ -4209,7 +4209,7 @@ void EntityItemProperties::copySimulationRestrictedProperties(const EntityItemPo
setAcceleration(entity->getAcceleration());
}
if (!_localDimensionsChanged && !_dimensionsChanged) {
setDimensions(entity->getScaledDimensions());
setLocalDimensions(entity->getScaledDimensions());
}
}

View file

@ -2039,6 +2039,8 @@ void EntityTree::fixupNeedsParentFixups() {
Simulation::DIRTY_COLLISION_GROUP |
Simulation::DIRTY_TRANSFORM);
entityChanged(entity);
entity->locationChanged(true, false);
entity->forEachDescendant([&](SpatiallyNestablePointer object) {
if (object->getNestableType() == NestableType::Entity) {
EntityItemPointer descendantEntity = std::static_pointer_cast<EntityItem>(object);
@ -2047,8 +2049,8 @@ void EntityTree::fixupNeedsParentFixups() {
Simulation::DIRTY_TRANSFORM);
entityChanged(descendantEntity);
}
object->locationChanged(true, false);
});
entity->locationChanged(true);
// Update our parent's bounding box
bool success = false;
@ -3002,8 +3004,19 @@ void EntityTree::updateEntityQueryAACubeWorker(SpatiallyNestablePointer object,
// if the queryBox has changed, tell the entity-server
EntityItemPointer entity = std::dynamic_pointer_cast<EntityItem>(object);
if (entity) {
// NOTE: we rely on side-effects of the entity->updateQueryAACube() call in the following if() conditional:
if (entity->updateQueryAACube() || force) {
bool queryAACubeChanged = false;
if (!entity->hasChildren()) {
// updateQueryAACube will also update all ancestors' AACubes, so we only need to call this for leaf nodes
queryAACubeChanged = entity->updateQueryAACube();
} else {
AACube oldCube = entity->getQueryAACube();
object->forEachChild([&](SpatiallyNestablePointer descendant) {
updateEntityQueryAACubeWorker(descendant, packetSender, moveOperator, force, tellServer);
});
queryAACubeChanged = oldCube != entity->getQueryAACube();
}
if (queryAACubeChanged || force) {
bool success;
AACube newCube = entity->getQueryAACube(success);
if (success) {
@ -3027,10 +3040,6 @@ void EntityTree::updateEntityQueryAACubeWorker(SpatiallyNestablePointer object,
entityChanged(entity);
}
}
object->forEachDescendant([&](SpatiallyNestablePointer descendant) {
updateEntityQueryAACubeWorker(descendant, packetSender, moveOperator, force, tellServer);
});
}
void EntityTree::updateEntityQueryAACube(SpatiallyNestablePointer object, EntityEditPacketSender* packetSender,

View file

@ -55,8 +55,8 @@ void LightEntityItem::setUnscaledDimensions(const glm::vec3& value) {
}
}
void LightEntityItem::locationChanged(bool tellPhysics) {
EntityItem::locationChanged(tellPhysics);
void LightEntityItem::locationChanged(bool tellPhysics, bool tellChildren) {
EntityItem::locationChanged(tellPhysics, tellChildren);
withWriteLock([&] {
_lightPropertiesChanged = true;
});

View file

@ -74,7 +74,7 @@ public:
static bool getLightsArePickable() { return _lightsArePickable; }
static void setLightsArePickable(bool value) { _lightsArePickable = value; }
virtual void locationChanged(bool tellPhysics) override;
virtual void locationChanged(bool tellPhysics, bool tellChildren) override;
virtual void dimensionsChanged() override;
bool lightPropertiesChanged() const { return _lightPropertiesChanged; }

View file

@ -273,6 +273,15 @@ public:
{}
};
class FlowData {
public:
FlowData() {};
QVariantMap _physicsConfig;
QVariantMap _collisionsConfig;
bool shouldInitFlow() const { return _physicsConfig.size() > 0; }
bool shouldInitCollisions() const { return _collisionsConfig.size() > 0; }
};
/// The runtime model format.
class Model {
public:
@ -319,6 +328,7 @@ public:
QList<QString> blendshapeChannelNames;
QMap<int, glm::quat> jointRotationOffsets;
FlowData flowData;
};
};
@ -343,6 +353,7 @@ typedef hfm::Mesh HFMMesh;
typedef hfm::AnimationFrame HFMAnimationFrame;
typedef hfm::Light HFMLight;
typedef hfm::Model HFMModel;
typedef hfm::FlowData FlowData;
Q_DECLARE_METATYPE(HFMAnimationFrame)
Q_DECLARE_METATYPE(QVector<HFMAnimationFrame>)

View file

@ -20,6 +20,7 @@
#include "CalculateBlendshapeNormalsTask.h"
#include "CalculateBlendshapeTangentsTask.h"
#include "PrepareJointsTask.h"
#include "ParseFlowDataTask.h"
namespace baker {
@ -101,7 +102,7 @@ namespace baker {
class BuildModelTask {
public:
using Input = VaryingSet5<hfm::Model::Pointer, std::vector<hfm::Mesh>, std::vector<hfm::Joint>, QMap<int, glm::quat>, QHash<QString, int>>;
using Input = VaryingSet6<hfm::Model::Pointer, std::vector<hfm::Mesh>, std::vector<hfm::Joint>, QMap<int, glm::quat>, QHash<QString, int>, FlowData>;
using Output = hfm::Model::Pointer;
using JobModel = Job::ModelIO<BuildModelTask, Input, Output>;
@ -111,6 +112,7 @@ namespace baker {
hfmModelOut->joints = QVector<hfm::Joint>::fromStdVector(input.get2());
hfmModelOut->jointRotationOffsets = input.get3();
hfmModelOut->jointIndices = input.get4();
hfmModelOut->flowData = input.get5();
output = hfmModelOut;
}
};
@ -157,12 +159,15 @@ namespace baker {
// Parse material mapping
const auto materialMapping = model.addJob<ParseMaterialMappingTask>("ParseMaterialMapping", mapping);
// Parse flow data
const auto flowData = model.addJob<ParseFlowDataTask>("ParseFlowData", mapping);
// Combine the outputs into a new hfm::Model
const auto buildBlendshapesInputs = BuildBlendshapesTask::Input(blendshapesPerMeshIn, normalsPerBlendshapePerMesh, tangentsPerBlendshapePerMesh).asVarying();
const auto blendshapesPerMeshOut = model.addJob<BuildBlendshapesTask>("BuildBlendshapes", buildBlendshapesInputs);
const auto buildMeshesInputs = BuildMeshesTask::Input(meshesIn, graphicsMeshes, normalsPerMesh, tangentsPerMesh, blendshapesPerMeshOut).asVarying();
const auto meshesOut = model.addJob<BuildMeshesTask>("BuildMeshes", buildMeshesInputs);
const auto buildModelInputs = BuildModelTask::Input(hfmModelIn, meshesOut, jointsOut, jointRotationOffsets, jointIndices).asVarying();
const auto buildModelInputs = BuildModelTask::Input(hfmModelIn, meshesOut, jointsOut, jointRotationOffsets, jointIndices, flowData).asVarying();
const auto hfmModelOut = model.addJob<BuildModelTask>("BuildModel", buildModelInputs);
output = Output(hfmModelOut, materialMapping);

View file

@ -0,0 +1,33 @@
//
// Created by Luis Cuenca on 5/3/2019
// Copyright 2019 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 "ParseFlowDataTask.h"
void ParseFlowDataTask::run(const baker::BakeContextPointer& context, const Input& mapping, Output& output) {
FlowData flowData;
static const QString FLOW_PHYSICS_FIELD = "flowPhysicsData";
static const QString FLOW_COLLISIONS_FIELD = "flowCollisionsData";
for (auto mappingIter = mapping.begin(); mappingIter != mapping.end(); mappingIter++) {
if (mappingIter.key() == FLOW_PHYSICS_FIELD || mappingIter.key() == FLOW_COLLISIONS_FIELD) {
QByteArray data = mappingIter.value().toByteArray();
QJsonObject dataObject = QJsonDocument::fromJson(data).object();
if (!dataObject.isEmpty() && dataObject.keys().size() == 1) {
QString key = dataObject.keys()[0];
if (dataObject[key].isObject()) {
QVariantMap dataMap = dataObject[key].toObject().toVariantMap();
if (mappingIter.key() == FLOW_PHYSICS_FIELD) {
flowData._physicsConfig.insert(key, dataMap);
} else {
flowData._collisionsConfig.insert(key, dataMap);
}
}
}
}
}
output = flowData;
}

View file

@ -0,0 +1,24 @@
//
// Created by Luis Cuenca on 5/3/2019
// Copyright 2019 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_ParseFlowDataTask_h
#define hifi_ParseFlowDataTask_h
#include <hfm/HFM.h>
#include "Engine.h"
class ParseFlowDataTask {
public:
using Input = QVariantHash;
using Output = FlowData;
using JobModel = baker::Job::ModelIO<ParseFlowDataTask, Input, Output>;
void run(const baker::BakeContextPointer& context, const Input& input, Output& output);
};
#endif // hifi_ParseFlowDataTask_h

View file

@ -1100,10 +1100,12 @@ void SpatiallyNestable::forEachDescendantTest(const ChildLambdaTest& actor) cons
}
}
void SpatiallyNestable::locationChanged(bool tellPhysics) {
forEachChild([&](SpatiallyNestablePointer object) {
object->locationChanged(tellPhysics);
});
void SpatiallyNestable::locationChanged(bool tellPhysics, bool tellChildren) {
if (tellChildren) {
forEachChild([&](SpatiallyNestablePointer object) {
object->locationChanged(tellPhysics, tellChildren);
});
}
}
AACube SpatiallyNestable::getMaximumAACube(bool& success) const {

View file

@ -211,7 +211,7 @@ public:
void dump(const QString& prefix = "") const;
virtual void locationChanged(bool tellPhysics = true); // called when a this object's location has changed
virtual void locationChanged(bool tellPhysics = true, bool tellChildren = true); // called when a this object's location has changed
virtual void dimensionsChanged() { _queryAACubeSet = false; } // called when a this object's dimensions have changed
virtual void parentDeleted() { } // called on children of a deleted parent

View file

@ -19,6 +19,11 @@ Script.include("/~/system/libraries/controllers.js");
var isShowingOverlays = true;
var debugOverlays = {};
var textSizeOverlay = Overlays.addOverlay("text3d", {
position: MyAvatar.position,
lineHeight: 0.1,
visible: false
});
function removeOverlays() {
// enumerate the overlays and remove them
@ -31,6 +36,8 @@ function removeOverlays() {
}
}
Overlays.deleteOverlay(textSizeOverlay);
debugOverlays = {};
}
@ -60,8 +67,6 @@ function updateOverlays() {
var overlayPosition = avatar.getJointPosition("Head");
overlayPosition.y += 1.15;
var rows = 8;
var text = avatarID + "\n"
+"--- Data from Mixer ---\n"
+"All: " + AvatarManager.getAvatarDataRate(avatarID).toFixed(2) + "kbps (" + AvatarManager.getAvatarUpdateRate(avatarID).toFixed(2) + "hz)" + "\n"
@ -85,9 +90,11 @@ function updateOverlays() {
//+" SM: " + AvatarManager.getAvatarSimulationRate(avatarID,"skeletonModel").toFixed(2) + "hz \n"
+" JD: " + AvatarManager.getAvatarSimulationRate(avatarID,"jointData").toFixed(2) + "hz \n"
var dimensions = Overlays.textSize(textSizeOverlay, text);
if (avatarID in debugOverlays) {
// keep the overlay above the current position of this avatar
Overlays.editOverlay(debugOverlays[avatarID][0], {
dimensions: { x: 1.1 * dimensions.width, y: 0.6 * dimensions.height },
position: overlayPosition,
text: text
});
@ -95,15 +102,9 @@ function updateOverlays() {
// add the overlay above this avatar
var newOverlay = Overlays.addOverlay("text3d", {
position: overlayPosition,
dimensions: {
x: 1.25,
y: rows * 0.13
},
dimensions: { x: 1.1 * dimensions.width, y: 0.6 * dimensions.height },
lineHeight: 0.1,
font:{size:0.1},
text: text,
size: 1,
scale: 0.4,
color: { red: 255, green: 255, blue: 255},
alpha: 1,
solid: true,