Merge branch 'master' of github.com:highfidelity/hifi into fix-dynamic-entities-not-colliding

This commit is contained in:
Dante Ruiz 2018-01-18 08:56:01 -08:00
commit 3e3b3a0a9e
250 changed files with 4085 additions and 1668 deletions

View file

@ -11,7 +11,7 @@ link_hifi_libraries(
physics physics
audio audio-client audio audio-client
ui midi controllers pointers ui midi controllers pointers
model model-networking fbx animation graphics model-networking fbx animation
entities entities-renderer entities entities-renderer
avatars avatars-renderer avatars avatars-renderer
ui-plugins input-plugins ui-plugins input-plugins

View file

@ -11,7 +11,7 @@ setup_memory_debugger()
# link in the shared libraries # link in the shared libraries
link_hifi_libraries( link_hifi_libraries(
audio avatars octree gpu model fbx entities audio avatars octree gpu graphics fbx entities
networking animation recording shared script-engine embedded-webserver networking animation recording shared script-engine embedded-webserver
controllers physics plugins midi image controllers physics plugins midi image
) )

View file

@ -116,8 +116,9 @@ public:
void setLastOtherAvatarEncodeTime(const QUuid& otherAvatar, const uint64_t& time); void setLastOtherAvatarEncodeTime(const QUuid& otherAvatar, const uint64_t& time);
QVector<JointData>& getLastOtherAvatarSentJoints(QUuid otherAvatar) { QVector<JointData>& getLastOtherAvatarSentJoints(QUuid otherAvatar) {
_lastOtherAvatarSentJoints[otherAvatar].resize(_avatar->getJointCount()); auto& lastOtherAvatarSentJoints = _lastOtherAvatarSentJoints[otherAvatar];
return _lastOtherAvatarSentJoints[otherAvatar]; lastOtherAvatarSentJoints.resize(_avatar->getJointCount());
return lastOtherAvatarSentJoints;
} }
void queuePacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer node); void queuePacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer node);

View file

@ -201,7 +201,7 @@ endif()
# link required hifi libraries # link required hifi libraries
link_hifi_libraries( link_hifi_libraries(
shared octree ktx gpu gl procedural model render shared octree ktx gpu gl procedural graphics render
pointers pointers
recording fbx networking model-networking entities avatars trackers recording fbx networking model-networking entities avatars trackers
audio audio-client animation script-engine physics audio audio-client animation script-engine physics

View file

@ -1,256 +0,0 @@
//
// ToolWindow.qml
//
// Created by Bradley Austin Davis on 12 Jan 2016
// Copyright 2016 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
//
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtWebEngine 1.1
import QtWebChannel 1.0
import Qt.labs.settings 1.0
import "windows"
import "controls-uit"
import "styles-uit"
ScrollingWindow {
id: toolWindow
resizable: true
objectName: "ToolWindow"
destroyOnCloseButton: false
destroyOnHidden: false
closable: true
shown: false
title: "Edit"
property alias tabView: tabView
implicitWidth: 520; implicitHeight: 695
minSize: Qt.vector2d(456, 500)
HifiConstants { id: hifi }
onParentChanged: {
if (parent) {
x = 120;
y = 120;
}
}
onShownChanged: {
keyboardEnabled = HMD.active;
}
Settings {
category: "ToolWindow.Position"
property alias x: toolWindow.x
property alias y: toolWindow.y
}
Item {
id: toolWindowTabViewItem
height: pane.scrollHeight
width: pane.contentWidth
anchors.left: parent.left
anchors.top: parent.top
TabView {
id: tabView
width: pane.contentWidth
// Pane height so that don't use Window's scrollbars otherwise tabs may be scrolled out of view.
height: pane.scrollHeight
property int tabCount: 0
Repeater {
model: 4
Tab {
// Force loading of the content even if the tab is not visible
// (required for letting the C++ code access the webview)
active: true
enabled: false
property string originalUrl: ""
WebView {
id: webView
anchors.fill: parent
enabled: false
Component.onCompleted: {
webChannel.registerObject("eventBridge", eventBridge);
webChannel.registerObject("eventBridgeWrapper", eventBridgeWrapper);
}
onEnabledChanged: toolWindow.updateVisiblity()
}
}
}
style: TabViewStyle {
frame: Rectangle { // Background shown before content loads.
anchors.fill: parent
color: hifi.colors.baseGray
}
frameOverlap: 0
tab: Rectangle {
implicitWidth: text.width
implicitHeight: 3 * text.height
color: styleData.selected ? hifi.colors.black : hifi.colors.tabBackgroundDark
RalewayRegular {
id: text
text: styleData.title
font.capitalization: Font.AllUppercase
size: hifi.fontSizes.tabName
width: tabView.tabCount > 1 ? styleData.availableWidth / tabView.tabCount : implicitWidth + 2 * hifi.dimensions.contentSpacing.x
elide: Text.ElideRight
color: styleData.selected ? hifi.colors.primaryHighlight : hifi.colors.lightGrayText
horizontalAlignment: Text.AlignHCenter
anchors.centerIn: parent
}
Rectangle { // Separator.
width: 1
height: parent.height
color: hifi.colors.black
anchors.left: parent.left
anchors.top: parent.top
visible: styleData.index > 0
Rectangle {
width: 1
height: 1
color: hifi.colors.baseGray
anchors.left: parent.left
anchors.bottom: parent.bottom
}
}
Rectangle { // Active underline.
width: parent.width - (styleData.index > 0 ? 1 : 0)
height: 1
anchors.right: parent.right
anchors.bottom: parent.bottom
color: styleData.selected ? hifi.colors.primaryHighlight : hifi.colors.baseGray
}
}
tabOverlap: 0
}
}
}
function updateVisiblity() {
if (visible) {
for (var i = 0; i < tabView.count; ++i) {
if (tabView.getTab(i).enabled) {
return;
}
}
shown = false;
}
}
function findIndexForUrl(source) {
for (var i = 0; i < tabView.count; ++i) {
var tab = tabView.getTab(i);
if (tab.originalUrl === source) {
return i;
}
}
return -1;
}
function findTabForUrl(source) {
var index = findIndexForUrl(source);
if (index < 0) {
return;
}
return tabView.getTab(index);
}
function showTabForUrl(source, newVisible) {
var index = findIndexForUrl(source);
if (index < 0) {
return;
}
var tab = tabView.getTab(index);
if (newVisible) {
toolWindow.shown = true
tab.enabled = true
} else {
tab.enabled = false;
updateVisiblity();
}
}
function findFreeTab() {
for (var i = 0; i < tabView.count; ++i) {
var tab = tabView.getTab(i);
if (tab && (!tab.originalUrl || tab.originalUrl === "")) {
return i;
}
}
return -1;
}
function removeTabForUrl(source) {
var index = findIndexForUrl(source);
if (index < 0) {
return;
}
var tab = tabView.getTab(index);
tab.title = "";
tab.enabled = false;
tab.originalUrl = "";
tab.item.url = "about:blank";
tab.item.enabled = false;
tabView.tabCount--;
}
function addWebTab(properties) {
if (!properties.source) {
console.warn("Attempted to open Web Tool Pane without URL");
return;
}
var existingTabIndex = findIndexForUrl(properties.source);
if (existingTabIndex >= 0) {
var tab = tabView.getTab(existingTabIndex);
return tab.item;
}
var freeTabIndex = findFreeTab();
if (freeTabIndex === -1) {
console.warn("Unable to add new tab");
return;
}
if (properties.width) {
tabView.width = Math.min(Math.max(tabView.width, properties.width), toolWindow.maxSize.x);
}
if (properties.height) {
tabView.height = Math.min(Math.max(tabView.height, properties.height), toolWindow.maxSize.y);
}
var tab = tabView.getTab(freeTabIndex);
tab.title = properties.title || "Unknown";
tab.enabled = true;
tab.originalUrl = properties.source;
var result = tab.item;
result.enabled = true;
tabView.tabCount++;
result.url = properties.source;
return result;
}
}

View file

@ -27,10 +27,12 @@ TextField {
property bool hasRoundedBorder: false property bool hasRoundedBorder: false
property bool error: false; property bool error: false;
property bool hasClearButton: false; property bool hasClearButton: false;
property string leftPlaceholderGlyph: "";
placeholderText: textField.placeholderText placeholderText: textField.placeholderText
FontLoader { id: firaSansSemiBold; source: "../../fonts/FiraSans-SemiBold.ttf"; } FontLoader { id: firaSansSemiBold; source: "../../fonts/FiraSans-SemiBold.ttf"; }
FontLoader { id: hifiGlyphs; source: "../../fonts/hifi-glyphs.ttf"; }
font.family: firaSansSemiBold.name font.family: firaSansSemiBold.name
font.pixelSize: hifi.fontSizes.textFieldInput font.pixelSize: hifi.fontSizes.textFieldInput
font.italic: textField.text == "" font.italic: textField.text == ""
@ -54,6 +56,7 @@ TextField {
} }
style: TextFieldStyle { style: TextFieldStyle {
id: style;
textColor: { textColor: {
if (isLightColorScheme) { if (isLightColorScheme) {
if (textField.activeFocus) { if (textField.activeFocus) {
@ -102,6 +105,16 @@ TextField {
border.width: textField.activeFocus || hasRoundedBorder || textField.error ? 1 : 0 border.width: textField.activeFocus || hasRoundedBorder || textField.error ? 1 : 0
radius: isSearchField ? textField.height / 2 : (hasRoundedBorder ? 4 : 0) radius: isSearchField ? textField.height / 2 : (hasRoundedBorder ? 4 : 0)
HiFiGlyphs {
text: textField.leftPlaceholderGlyph;
color: textColor;
size: hifi.fontSizes.textFieldSearchIcon;
anchors.left: parent.left;
anchors.verticalCenter: parent.verticalCenter;
anchors.leftMargin: hifi.dimensions.textPadding - 2;
visible: text;
}
HiFiGlyphs { HiFiGlyphs {
text: hifi.glyphs.search text: hifi.glyphs.search
color: textColor color: textColor
@ -132,7 +145,7 @@ TextField {
placeholderTextColor: isFaintGrayColorScheme ? hifi.colors.lightGrayText : hifi.colors.lightGray placeholderTextColor: isFaintGrayColorScheme ? hifi.colors.lightGrayText : hifi.colors.lightGray
selectedTextColor: hifi.colors.black selectedTextColor: hifi.colors.black
selectionColor: hifi.colors.primaryHighlight selectionColor: hifi.colors.primaryHighlight
padding.left: (isSearchField ? textField.height - 2 : 0) + hifi.dimensions.textPadding padding.left: ((isSearchField || textField.leftPlaceholderGlyph !== "") ? textField.height - 2 : 0) + hifi.dimensions.textPadding
padding.right: (hasClearButton ? textField.height - 2 : 0) + hifi.dimensions.textPadding padding.right: (hasClearButton ? textField.height - 2 : 0) + hifi.dimensions.textPadding
} }

View file

@ -22,10 +22,6 @@ OriginalDesktop.Desktop {
acceptedButtons: Qt.NoButton acceptedButtons: Qt.NoButton
} }
// The tool window, one instance
property alias toolWindow: toolWindow
ToolWindow { id: toolWindow }
Action { Action {
text: "Open Browser" text: "Open Browser"
shortcut: "Ctrl+B" shortcut: "Ctrl+B"

View file

@ -50,7 +50,7 @@ Item {
id: avatarImage id: avatarImage
visible: profileUrl !== "" && userName !== ""; visible: profileUrl !== "" && userName !== "";
// Size // Size
height: isMyCard ? 70 : 42; height: isMyCard ? 84 : 42;
width: visible ? height : 0; width: visible ? height : 0;
anchors.top: parent.top; anchors.top: parent.top;
anchors.topMargin: isMyCard ? 0 : 8; anchors.topMargin: isMyCard ? 0 : 8;
@ -520,7 +520,7 @@ Item {
Slider { Slider {
id: gainSlider id: gainSlider
// Size // Size
width: thisNameCard.width; width: isMyCard ? thisNameCard.width - 20 : thisNameCard.width;
height: 14 height: 14
// Anchors // Anchors
anchors.verticalCenter: nameCardVUMeter.verticalCenter; anchors.verticalCenter: nameCardVUMeter.verticalCenter;

View file

@ -28,7 +28,7 @@ Rectangle {
// Properties // Properties
property bool debug: false; property bool debug: false;
property int myCardWidth: width - upperRightInfoContainer.width; property int myCardWidth: width - upperRightInfoContainer.width;
property int myCardHeight: 80; property int myCardHeight: 100;
property int rowHeight: 60; property int rowHeight: 60;
property int actionButtonWidth: 55; property int actionButtonWidth: 55;
property int locationColumnWidth: 170; property int locationColumnWidth: 170;

View file

@ -1,73 +0,0 @@
//
// SendMoney.qml
// qml/hifi/commerce/wallet
//
// SendMoney
//
// Created by Zach Fox on 2017-08-18
// 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
//
import Hifi 1.0 as Hifi
import QtQuick 2.5
import QtQuick.Controls 1.4
import "../../../styles-uit"
import "../../../controls-uit" as HifiControlsUit
import "../../../controls" as HifiControls
// references XXX from root context
Item {
HifiConstants { id: hifi; }
id: root;
Connections {
target: Commerce;
}
// "Unavailable"
RalewayRegular {
text: "You currently cannot send money to other High Fidelity users.";
// Anchors
anchors.fill: parent;
// Text size
size: 24;
// Style
color: hifi.colors.faintGray;
wrapMode: Text.WordWrap;
// Alignment
horizontalAlignment: Text.AlignHCenter;
verticalAlignment: Text.AlignVCenter;
}
//
// FUNCTION DEFINITIONS START
//
//
// Function Name: fromScript()
//
// Relevant Variables:
// None
//
// Arguments:
// message: The message sent from the JavaScript.
// Messages are in format "{method, params}", like json-rpc.
//
// Description:
// Called when a message is received from a script.
//
function fromScript(message) {
switch (message.method) {
default:
console.log('Unrecognized message from wallet.js:', JSON.stringify(message));
}
}
signal sendSignalToWallet(var msg);
//
// FUNCTION DEFINITIONS END
//
}

View file

@ -19,8 +19,7 @@ import "../../../styles-uit"
import "../../../controls-uit" as HifiControlsUit import "../../../controls-uit" as HifiControlsUit
import "../../../controls" as HifiControls import "../../../controls" as HifiControls
import "../common" as HifiCommerceCommon import "../common" as HifiCommerceCommon
import "./sendMoney"
// references XXX from root context
Rectangle { Rectangle {
HifiConstants { id: hifi; } HifiConstants { id: hifi; }
@ -316,18 +315,29 @@ Rectangle {
Connections { Connections {
onSendSignalToWallet: { onSendSignalToWallet: {
sendToScript(msg); if (msg.method === 'transactionHistory_usernameLinkClicked') {
userInfoViewer.url = msg.usernameLink;
userInfoViewer.visible = true;
} else {
sendToScript(msg);
}
} }
} }
} }
SendMoney { SendMoney {
id: sendMoney; id: sendMoney;
z: 997;
visible: root.activeView === "sendMoney"; visible: root.activeView === "sendMoney";
anchors.top: titleBarContainer.bottom; anchors.fill: parent;
anchors.bottom: tabButtonsContainer.top; parentAppTitleBarHeight: titleBarContainer.height;
anchors.left: parent.left; parentAppNavBarHeight: tabButtonsContainer.height;
anchors.right: parent.right;
Connections {
onSendSignalToWallet: {
sendToScript(msg);
}
}
} }
Security { Security {
@ -497,7 +507,7 @@ Rectangle {
Rectangle { Rectangle {
id: sendMoneyButtonContainer; id: sendMoneyButtonContainer;
visible: !walletSetup.visible; visible: !walletSetup.visible;
color: hifi.colors.black; color: root.activeView === "sendMoney" ? hifi.colors.blueAccent : hifi.colors.black;
anchors.top: parent.top; anchors.top: parent.top;
anchors.left: exchangeMoneyButtonContainer.right; anchors.left: exchangeMoneyButtonContainer.right;
anchors.bottom: parent.bottom; anchors.bottom: parent.bottom;
@ -513,7 +523,7 @@ Rectangle {
anchors.top: parent.top; anchors.top: parent.top;
anchors.topMargin: -2; anchors.topMargin: -2;
// Style // Style
color: hifi.colors.lightGray50; color: root.activeView === "sendMoney" || sendMoneyTabMouseArea.containsMouse ? hifi.colors.white : hifi.colors.blueHighlight;
} }
RalewaySemiBold { RalewaySemiBold {
@ -528,12 +538,24 @@ Rectangle {
anchors.right: parent.right; anchors.right: parent.right;
anchors.rightMargin: 4; anchors.rightMargin: 4;
// Style // Style
color: hifi.colors.lightGray50; color: root.activeView === "sendMoney" || sendMoneyTabMouseArea.containsMouse ? hifi.colors.white : hifi.colors.blueHighlight;
wrapMode: Text.WordWrap; wrapMode: Text.WordWrap;
// Alignment // Alignment
horizontalAlignment: Text.AlignHCenter; horizontalAlignment: Text.AlignHCenter;
verticalAlignment: Text.AlignTop; verticalAlignment: Text.AlignTop;
} }
MouseArea {
id: sendMoneyTabMouseArea;
anchors.fill: parent;
hoverEnabled: enabled;
onClicked: {
root.activeView = "sendMoney";
tabButtonsContainer.resetTabButtonColors();
}
onEntered: parent.color = hifi.colors.blueHighlight;
onExited: parent.color = root.activeView === "sendMoney" ? hifi.colors.blueAccent : hifi.colors.black;
}
} }
// "SECURITY" tab button // "SECURITY" tab button
@ -665,9 +687,16 @@ Rectangle {
// TAB BUTTONS END // TAB BUTTONS END
// //
HifiControls.TabletWebView {
id: userInfoViewer;
z: 998;
anchors.fill: parent;
visible: false;
}
Item { Item {
id: keyboardContainer; id: keyboardContainer;
z: 998; z: 999;
visible: keyboard.raised; visible: keyboard.raised;
property bool punctuationMode: false; property bool punctuationMode: false;
anchors { anchors {
@ -713,6 +742,13 @@ Rectangle {
case 'inspectionCertificate_resetCert': case 'inspectionCertificate_resetCert':
// NOP // NOP
break; break;
case 'updateConnections':
sendMoney.updateConnections(message.connections);
break;
case 'selectRecipient':
case 'updateSelectedRecipientUsername':
sendMoney.fromScript(message);
break;
default: default:
console.log('Unrecognized message from wallet.js:', JSON.stringify(message)); console.log('Unrecognized message from wallet.js:', JSON.stringify(message));
} }

View file

@ -19,8 +19,6 @@ import "../../../styles-uit"
import "../../../controls-uit" as HifiControlsUit import "../../../controls-uit" as HifiControlsUit
import "../../../controls" as HifiControls import "../../../controls" as HifiControls
// references XXX from root context
Item { Item {
HifiConstants { id: hifi; } HifiConstants { id: hifi; }
@ -32,6 +30,20 @@ Item {
property int currentHistoryPage: 1; property int currentHistoryPage: 1;
property var pagesAlreadyAdded: new Array(); property var pagesAlreadyAdded: new Array();
onVisibleChanged: {
if (visible) {
transactionHistoryModel.clear();
Commerce.balance();
initialHistoryReceived = false;
root.currentHistoryPage = 1;
root.noMoreHistoryData = false;
root.historyRequestPending = true;
Commerce.history(root.currentHistoryPage);
} else {
refreshTimer.stop();
}
}
Connections { Connections {
target: Commerce; target: Commerce;
@ -189,20 +201,6 @@ Item {
color: hifi.colors.white; color: hifi.colors.white;
// Alignment // Alignment
verticalAlignment: Text.AlignVCenter; verticalAlignment: Text.AlignVCenter;
onVisibleChanged: {
if (visible) {
transactionHistoryModel.clear();
Commerce.balance();
initialHistoryReceived = false;
root.currentHistoryPage = 1;
root.noMoreHistoryData = false;
root.historyRequestPending = true;
Commerce.history(root.currentHistoryPage);
} else {
refreshTimer.stop();
}
}
} }
// "balance" text below field // "balance" text below field
@ -384,8 +382,8 @@ Item {
height: visible ? parent.height : 0; height: visible ? parent.height : 0;
AnonymousProRegular { AnonymousProRegular {
id: dateText; id: hfcText;
text: model.created_at ? getFormattedDate(model.created_at * 1000) : ""; text: model.hfc_text || '';
// Style // Style
size: 18; size: 18;
anchors.left: parent.left; anchors.left: parent.left;
@ -393,28 +391,33 @@ Item {
anchors.topMargin: 15; anchors.topMargin: 15;
width: 118; width: 118;
height: paintedHeight; height: paintedHeight;
color: hifi.colors.blueAccent;
wrapMode: Text.WordWrap; wrapMode: Text.WordWrap;
font.bold: true;
// Alignment // Alignment
horizontalAlignment: Text.AlignRight; horizontalAlignment: Text.AlignRight;
} }
AnonymousProRegular { AnonymousProRegular {
id: transactionText; id: transactionText;
text: model.text ? (model.status === "invalidated" ? ("INVALIDATED: " + model.text) : model.text) : ""; text: model.transaction_text ? (model.status === "invalidated" ? ("INVALIDATED: " + model.transaction_text) : model.transaction_text) : "";
size: 18; size: 18;
anchors.top: parent.top; anchors.top: parent.top;
anchors.topMargin: 15; anchors.topMargin: 15;
anchors.left: dateText.right; anchors.left: hfcText.right;
anchors.leftMargin: 20; anchors.leftMargin: 20;
anchors.right: parent.right; anchors.right: parent.right;
height: paintedHeight; height: paintedHeight;
color: model.status === "invalidated" ? hifi.colors.redAccent : hifi.colors.baseGrayHighlight; color: model.status === "invalidated" ? hifi.colors.redAccent : hifi.colors.baseGrayHighlight;
linkColor: hifi.colors.blueAccent;
wrapMode: Text.WordWrap; wrapMode: Text.WordWrap;
font.strikeout: model.status === "invalidated"; font.strikeout: model.status === "invalidated";
onLinkActivated: { onLinkActivated: {
sendSignalToWallet({method: 'transactionHistory_linkClicked', marketplaceLink: link}); if (link.indexOf("users/") !== -1) {
sendSignalToWallet({method: 'transactionHistory_usernameLinkClicked', usernameLink: link});
} else {
sendSignalToWallet({method: 'transactionHistory_linkClicked', marketplaceLink: link});
}
} }
} }

View file

@ -0,0 +1,128 @@
//
// ConnectionItem.qml
// qml/hifi/commerce/wallet/sendMoney
//
// ConnectionItem
//
// Created by Zach Fox on 2018-01-09
// Copyright 2018 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
//
import Hifi 1.0 as Hifi
import QtQuick 2.5
import QtGraphicalEffects 1.0
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import "../../../../styles-uit"
import "../../../../controls-uit" as HifiControlsUit
import "../../../../controls" as HifiControls
import "../../wallet" as HifiWallet
Item {
HifiConstants { id: hifi; }
id: root;
property bool isSelected: false;
property string userName;
property string profilePicUrl;
height: 65;
width: parent.width;
Rectangle {
id: mainContainer;
// Style
color: root.isSelected ? hifi.colors.faintGray : hifi.colors.white;
// Size
anchors.left: parent.left;
anchors.right: parent.right;
anchors.top: parent.top;
height: root.height;
Item {
id: avatarImage;
visible: profileUrl !== "" && userName !== "";
// Size
anchors.verticalCenter: parent.verticalCenter;
anchors.left: parent.left;
anchors.leftMargin: 36;
height: root.height - 15;
width: visible ? height : 0;
clip: true;
Image {
id: userImage;
source: root.profilePicUrl !== "" ? ((0 === root.profilePicUrl.indexOf("http")) ?
root.profilePicUrl : (Account.metaverseServerURL + root.profilePicUrl)) : "";
mipmap: true;
// Anchors
anchors.fill: parent
layer.enabled: true
layer.effect: OpacityMask {
maskSource: Item {
width: userImage.width;
height: userImage.height;
Rectangle {
anchors.centerIn: parent;
width: userImage.width; // This works because userImage is square
height: width;
radius: width;
}
}
}
}
AnimatedImage {
source: "../../../../../icons/profilePicLoading.gif"
anchors.fill: parent;
visible: userImage.status != Image.Ready;
}
}
RalewaySemiBold {
id: userName;
anchors.left: avatarImage.right;
anchors.leftMargin: 16;
anchors.top: parent.top;
anchors.bottom: parent.bottom;
anchors.right: chooseButton.visible ? chooseButton.left : parent.right;
anchors.rightMargin: chooseButton.visible ? 10 : 0;
// Text size
size: 20;
// Style
color: hifi.colors.baseGray;
text: root.userName;
elide: Text.ElideRight;
// Alignment
horizontalAlignment: Text.AlignLeft;
verticalAlignment: Text.AlignVCenter;
}
// "Choose" button
HifiControlsUit.Button {
id: chooseButton;
visible: root.isSelected;
color: hifi.buttons.blue;
colorScheme: hifi.colorSchemes.dark;
anchors.verticalCenter: parent.verticalCenter;
anchors.right: parent.right;
anchors.rightMargin: 24;
height: root.height - 20;
width: 110;
text: "CHOOSE";
onClicked: {
var msg = { method: 'chooseConnection', userName: root.userName, profilePicUrl: root.profilePicUrl };
sendToSendMoney(msg);
}
}
}
//
// FUNCTION DEFINITIONS START
//
signal sendToSendMoney(var msg);
//
// FUNCTION DEFINITIONS END
//
}

View file

@ -0,0 +1,116 @@
//
// RecipientDisplay.qml
// qml/hifi/commerce/wallet/sendMoney
//
// RecipientDisplay
//
// Created by Zach Fox on 2018-01-11
// Copyright 2018 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
//
import Hifi 1.0 as Hifi
import QtQuick 2.6
import QtQuick.Controls 2.2
import QtGraphicalEffects 1.0
import "../../../../styles-uit"
import "../../../../controls-uit" as HifiControlsUit
import "../../../../controls" as HifiControls
import "../../common" as HifiCommerceCommon
Item {
HifiConstants { id: hifi; }
id: root;
property bool isDisplayingNearby; // as opposed to 'connections'
property string displayName;
property string userName;
property string profilePic;
Item {
visible: root.isDisplayingNearby;
anchors.fill: parent;
RalewaySemiBold {
id: recipientDisplayName;
text: root.displayName;
// Anchors
anchors.top: parent.top;
anchors.left: parent.left;
anchors.right: parent.right;
anchors.rightMargin: 12;
height: parent.height/2;
// Text size
size: 18;
// Style
color: hifi.colors.baseGray;
verticalAlignment: Text.AlignBottom;
elide: Text.ElideRight;
}
RalewaySemiBold {
text: root.userName;
// Anchors
anchors.bottom: parent.bottom;
anchors.left: recipientDisplayName.anchors.left;
anchors.leftMargin: recipientDisplayName.anchors.leftMargin;
anchors.right: recipientDisplayName.anchors.right;
anchors.rightMargin: recipientDisplayName.anchors.rightMargin;
height: parent.height/2;
// Text size
size: 16;
// Style
color: hifi.colors.baseGray;
verticalAlignment: Text.AlignTop;
elide: Text.ElideRight;
}
}
Item {
visible: !root.isDisplayingNearby;
anchors.fill: parent;
Image {
id: userImage;
source: root.profilePic;
mipmap: true;
// Anchors
anchors.left: parent.left;
anchors.verticalCenter: parent.verticalCenter;
height: parent.height - 36;
width: height;
layer.enabled: true;
layer.effect: OpacityMask {
maskSource: Item {
width: userImage.width;
height: userImage.height;
Rectangle {
anchors.centerIn: parent;
width: userImage.width; // This works because userImage is square
height: width;
radius: width;
}
}
}
}
RalewaySemiBold {
text: root.userName;
// Anchors
anchors.left: userImage.right;
anchors.leftMargin: 8;
anchors.right: parent.right;
anchors.verticalCenter: parent.verticalCenter;
height: parent.height - 4;
// Text size
size: 16;
// Style
color: hifi.colors.baseGray;
verticalAlignment: Text.AlignVCenter;
elide: Text.ElideRight;
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -22,7 +22,6 @@ Item {
anchors.fill: parent anchors.fill: parent
id: d id: d
objectName: "stack" objectName: "stack"
initialItem: topMenu
property var menuStack: [] property var menuStack: []
property var topMenu: null; property var topMenu: null;

View file

@ -157,7 +157,7 @@
#include "scripting/AssetMappingsScriptingInterface.h" #include "scripting/AssetMappingsScriptingInterface.h"
#include "scripting/ClipboardScriptingInterface.h" #include "scripting/ClipboardScriptingInterface.h"
#include "scripting/DesktopScriptingInterface.h" #include "scripting/DesktopScriptingInterface.h"
#include "scripting/GlobalServicesScriptingInterface.h" #include "scripting/AccountServicesScriptingInterface.h"
#include "scripting/HMDScriptingInterface.h" #include "scripting/HMDScriptingInterface.h"
#include "scripting/MenuScriptingInterface.h" #include "scripting/MenuScriptingInterface.h"
#include "scripting/SettingsScriptingInterface.h" #include "scripting/SettingsScriptingInterface.h"
@ -2287,7 +2287,7 @@ void Application::initializeUi() {
QUrl{ "hifi/commerce/wallet/SecurityImageChange.qml" }, QUrl{ "hifi/commerce/wallet/SecurityImageChange.qml" },
QUrl{ "hifi/commerce/wallet/SecurityImageModel.qml" }, QUrl{ "hifi/commerce/wallet/SecurityImageModel.qml" },
QUrl{ "hifi/commerce/wallet/SecurityImageSelection.qml" }, QUrl{ "hifi/commerce/wallet/SecurityImageSelection.qml" },
QUrl{ "hifi/commerce/wallet/SendMoney.qml" }, QUrl{ "hifi/commerce/wallet/sendMoney/SendMoney.qml" },
QUrl{ "hifi/commerce/wallet/Wallet.qml" }, QUrl{ "hifi/commerce/wallet/Wallet.qml" },
QUrl{ "hifi/commerce/wallet/WalletHome.qml" }, QUrl{ "hifi/commerce/wallet/WalletHome.qml" },
QUrl{ "hifi/commerce/wallet/WalletSetup.qml" }, QUrl{ "hifi/commerce/wallet/WalletSetup.qml" },
@ -2376,9 +2376,11 @@ void Application::initializeUi() {
surfaceContext->setContextProperty("SoundCache", DependencyManager::get<SoundCache>().data()); surfaceContext->setContextProperty("SoundCache", DependencyManager::get<SoundCache>().data());
surfaceContext->setContextProperty("InputConfiguration", DependencyManager::get<InputConfiguration>().data()); surfaceContext->setContextProperty("InputConfiguration", DependencyManager::get<InputConfiguration>().data());
surfaceContext->setContextProperty("Account", GlobalServicesScriptingInterface::getInstance()); surfaceContext->setContextProperty("Account", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED
surfaceContext->setContextProperty("GlobalServices", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED
surfaceContext->setContextProperty("AccountServices", AccountServicesScriptingInterface::getInstance());
surfaceContext->setContextProperty("DialogsManager", _dialogsManagerScriptingInterface); surfaceContext->setContextProperty("DialogsManager", _dialogsManagerScriptingInterface);
surfaceContext->setContextProperty("GlobalServices", GlobalServicesScriptingInterface::getInstance());
surfaceContext->setContextProperty("FaceTracker", DependencyManager::get<DdeFaceTracker>().data()); surfaceContext->setContextProperty("FaceTracker", DependencyManager::get<DdeFaceTracker>().data());
surfaceContext->setContextProperty("AvatarManager", DependencyManager::get<AvatarManager>().data()); surfaceContext->setContextProperty("AvatarManager", DependencyManager::get<AvatarManager>().data());
surfaceContext->setContextProperty("UndoStack", &_undoStackScriptingInterface); surfaceContext->setContextProperty("UndoStack", &_undoStackScriptingInterface);
@ -5465,7 +5467,7 @@ void Application::clearDomainOctreeDetails() {
auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage(); auto skyStage = DependencyManager::get<SceneScriptingInterface>()->getSkyStage();
skyStage->setBackgroundMode(model::SunSkyStage::SKY_DEFAULT); skyStage->setBackgroundMode(graphics::SunSkyStage::SKY_DEFAULT);
DependencyManager::get<AnimationCache>()->clearUnusedResources(); DependencyManager::get<AnimationCache>()->clearUnusedResources();
DependencyManager::get<ModelCache>()->clearUnusedResources(); DependencyManager::get<ModelCache>()->clearUnusedResources();
@ -5775,10 +5777,11 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe
scriptEngine->registerGlobalObject("ModelCache", DependencyManager::get<ModelCache>().data()); scriptEngine->registerGlobalObject("ModelCache", DependencyManager::get<ModelCache>().data());
scriptEngine->registerGlobalObject("SoundCache", DependencyManager::get<SoundCache>().data()); scriptEngine->registerGlobalObject("SoundCache", DependencyManager::get<SoundCache>().data());
scriptEngine->registerGlobalObject("Account", GlobalServicesScriptingInterface::getInstance());
scriptEngine->registerGlobalObject("DialogsManager", _dialogsManagerScriptingInterface); scriptEngine->registerGlobalObject("DialogsManager", _dialogsManagerScriptingInterface);
scriptEngine->registerGlobalObject("GlobalServices", GlobalServicesScriptingInterface::getInstance()); scriptEngine->registerGlobalObject("Account", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED
scriptEngine->registerGlobalObject("GlobalServices", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED
scriptEngine->registerGlobalObject("AccountServices", AccountServicesScriptingInterface::getInstance());
qScriptRegisterMetaType(scriptEngine.data(), DownloadInfoResultToScriptValue, DownloadInfoResultFromScriptValue); qScriptRegisterMetaType(scriptEngine.data(), DownloadInfoResultToScriptValue, DownloadInfoResultFromScriptValue);
scriptEngine->registerGlobalObject("FaceTracker", DependencyManager::get<DdeFaceTracker>().data()); scriptEngine->registerGlobalObject("FaceTracker", DependencyManager::get<DdeFaceTracker>().data());
@ -6178,7 +6181,7 @@ void Application::showAssetServerWidget(QString filePath) {
if (!hmd->getShouldShowTablet() && !isHMDMode()) { if (!hmd->getShouldShowTablet() && !isHMDMode()) {
DependencyManager::get<OffscreenUi>()->show(url, "AssetServer", startUpload); DependencyManager::get<OffscreenUi>()->show(url, "AssetServer", startUpload);
} else { } else {
static const QUrl url("hifi/dialogs/TabletAssetServer.qml"); static const QUrl url("../dialogs/TabletAssetServer.qml");
tablet->pushOntoStack(url); tablet->pushOntoStack(url);
} }
} }
@ -7398,11 +7401,13 @@ void Application::updateThreadPoolCount() const {
} }
void Application::updateSystemTabletMode() { void Application::updateSystemTabletMode() {
qApp->setProperty(hifi::properties::HMD, isHMDMode()); if (_settingsLoaded) {
if (isHMDMode()) { qApp->setProperty(hifi::properties::HMD, isHMDMode());
DependencyManager::get<TabletScriptingInterface>()->setToolbarMode(getHmdTabletBecomesToolbarSetting()); if (isHMDMode()) {
} else { DependencyManager::get<TabletScriptingInterface>()->setToolbarMode(getHmdTabletBecomesToolbarSetting());
DependencyManager::get<TabletScriptingInterface>()->setToolbarMode(getDesktopTabletBecomesToolbarSetting()); } else {
DependencyManager::get<TabletScriptingInterface>()->setToolbarMode(getDesktopTabletBecomesToolbarSetting());
}
} }
} }

View file

@ -71,7 +71,7 @@
#include "UndoStackScriptingInterface.h" #include "UndoStackScriptingInterface.h"
#include <procedural/ProceduralSkybox.h> #include <procedural/ProceduralSkybox.h>
#include <model/Skybox.h> #include <graphics/Skybox.h>
#include <ModelScriptingInterface.h> #include <ModelScriptingInterface.h>
#include "FrameTimingsScriptingInterface.h" #include "FrameTimingsScriptingInterface.h"
@ -270,7 +270,7 @@ public:
void takeSecondaryCameraSnapshot(); void takeSecondaryCameraSnapshot();
void shareSnapshot(const QString& filename, const QUrl& href = QUrl("")); void shareSnapshot(const QString& filename, const QUrl& href = QUrl(""));
model::SkyboxPointer getDefaultSkybox() const { return _defaultSkybox; } graphics::SkyboxPointer getDefaultSkybox() const { return _defaultSkybox; }
gpu::TexturePointer getDefaultSkyboxTexture() const { return _defaultSkyboxTexture; } gpu::TexturePointer getDefaultSkyboxTexture() const { return _defaultSkyboxTexture; }
gpu::TexturePointer getDefaultSkyboxAmbientTexture() const { return _defaultSkyboxAmbientTexture; } gpu::TexturePointer getDefaultSkyboxAmbientTexture() const { return _defaultSkyboxAmbientTexture; }
@ -667,7 +667,7 @@ private:
ConnectionMonitor _connectionMonitor; ConnectionMonitor _connectionMonitor;
model::SkyboxPointer _defaultSkybox { new ProceduralSkybox() } ; graphics::SkyboxPointer _defaultSkybox { new ProceduralSkybox() } ;
gpu::TexturePointer _defaultSkyboxTexture; gpu::TexturePointer _defaultSkyboxTexture;
gpu::TexturePointer _defaultSkyboxAmbientTexture; gpu::TexturePointer _defaultSkyboxAmbientTexture;

View file

@ -574,8 +574,6 @@ Menu::Menu() {
avatar.get(), SLOT(setEnableMeshVisible(bool))); avatar.get(), SLOT(setEnableMeshVisible(bool)));
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::DisableEyelidAdjustment, 0, false); addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::DisableEyelidAdjustment, 0, false);
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::TurnWithHead, 0, false); addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::TurnWithHead, 0, false);
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::UseAnimPreAndPostRotations, 0, true,
avatar.get(), SLOT(setUseAnimPreAndPostRotations(bool)));
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::EnableInverseKinematics, 0, true, addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::EnableInverseKinematics, 0, true,
avatar.get(), SLOT(setEnableInverseKinematics(bool))); avatar.get(), SLOT(setEnableInverseKinematics(bool)));
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderSensorToWorldMatrix, 0, false, addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::RenderSensorToWorldMatrix, 0, false,

View file

@ -194,7 +194,6 @@ namespace MenuOption {
const QString TurnWithHead = "Turn using Head"; const QString TurnWithHead = "Turn using Head";
const QString UseAudioForMouth = "Use Audio for Mouth"; const QString UseAudioForMouth = "Use Audio for Mouth";
const QString UseCamera = "Use Camera"; const QString UseCamera = "Use Camera";
const QString UseAnimPreAndPostRotations = "Use Anim Pre and Post Rotations";
const QString VelocityFilter = "Velocity Filter"; const QString VelocityFilter = "Velocity Filter";
const QString VisibleToEveryone = "Everyone"; const QString VisibleToEveryone = "Everyone";
const QString VisibleToFriends = "Friends"; const QString VisibleToFriends = "Friends";

View file

@ -537,6 +537,7 @@ void MyAvatar::simulate(float deltaTime) {
// we've achived our final adjusted position and rotation for the avatar // we've achived our final adjusted position and rotation for the avatar
// and all of its joints, now update our attachements. // and all of its joints, now update our attachements.
Avatar::simulateAttachments(deltaTime); Avatar::simulateAttachments(deltaTime);
relayJointDataToChildren();
if (!_skeletonModel->hasSkeleton()) { if (!_skeletonModel->hasSkeleton()) {
// All the simulation that can be done has been done // All the simulation that can be done has been done
@ -1061,11 +1062,6 @@ void MyAvatar::setEnableMeshVisible(bool isEnabled) {
_skeletonModel->setVisibleInScene(isEnabled, qApp->getMain3DScene()); _skeletonModel->setVisibleInScene(isEnabled, qApp->getMain3DScene());
} }
void MyAvatar::setUseAnimPreAndPostRotations(bool isEnabled) {
AnimClip::usePreAndPostPoseFromAnim = isEnabled;
reset(true);
}
void MyAvatar::setEnableInverseKinematics(bool isEnabled) { void MyAvatar::setEnableInverseKinematics(bool isEnabled) {
_skeletonModel->getRig().setEnableInverseKinematics(isEnabled); _skeletonModel->getRig().setEnableInverseKinematics(isEnabled);
} }
@ -1929,7 +1925,7 @@ void MyAvatar::preDisplaySide(RenderArgs* renderArgs) {
_prevShouldDrawHead = shouldDrawHead; _prevShouldDrawHead = shouldDrawHead;
} }
const float RENDER_HEAD_CUTOFF_DISTANCE = 0.3f; const float RENDER_HEAD_CUTOFF_DISTANCE = 0.47f;
bool MyAvatar::cameraInsideHead(const glm::vec3& cameraPosition) const { bool MyAvatar::cameraInsideHead(const glm::vec3& cameraPosition) const {
return glm::length(cameraPosition - getHeadPosition()) < (RENDER_HEAD_CUTOFF_DISTANCE * getModelScale()); return glm::length(cameraPosition - getHeadPosition()) < (RENDER_HEAD_CUTOFF_DISTANCE * getModelScale());
@ -2100,7 +2096,7 @@ void MyAvatar::updateActionMotor(float deltaTime) {
_actionMotorVelocity = motorSpeed * direction; _actionMotorVelocity = motorSpeed * direction;
} else { } else {
// we're interacting with a floor --> simple horizontal speed and exponential decay // we're interacting with a floor --> simple horizontal speed and exponential decay
_actionMotorVelocity = getSensorToWorldScale() * DEFAULT_AVATAR_MAX_WALKING_SPEED * direction; _actionMotorVelocity = getSensorToWorldScale() * _walkSpeed.get() * direction;
} }
float boomChange = getDriveKey(ZOOM); float boomChange = getDriveKey(ZOOM);
@ -2692,6 +2688,14 @@ float MyAvatar::getUserEyeHeight() const {
return userHeight - userHeight * ratio; return userHeight - userHeight * ratio;
} }
float MyAvatar::getWalkSpeed() const {
return _walkSpeed.get();
}
void MyAvatar::setWalkSpeed(float value) {
_walkSpeed.set(value);
}
glm::vec3 MyAvatar::getPositionForAudio() { glm::vec3 MyAvatar::getPositionForAudio() {
switch (_audioListenerMode) { switch (_audioListenerMode) {
case AudioListenerMode::FROM_HEAD: case AudioListenerMode::FROM_HEAD:

View file

@ -163,6 +163,8 @@ class MyAvatar : public Avatar {
Q_PROPERTY(QUuid SELF_ID READ getSelfID CONSTANT) Q_PROPERTY(QUuid SELF_ID READ getSelfID CONSTANT)
Q_PROPERTY(float walkSpeed READ getWalkSpeed WRITE setWalkSpeed);
const QString DOMINANT_LEFT_HAND = "left"; const QString DOMINANT_LEFT_HAND = "left";
const QString DOMINANT_RIGHT_HAND = "right"; const QString DOMINANT_RIGHT_HAND = "right";
@ -557,6 +559,9 @@ public:
const QUuid& getSelfID() const { return AVATAR_SELF_ID; } const QUuid& getSelfID() const { return AVATAR_SELF_ID; }
void setWalkSpeed(float value);
float getWalkSpeed() const;
public slots: public slots:
void increaseSize(); void increaseSize();
void decreaseSize(); void decreaseSize();
@ -594,7 +599,6 @@ public slots:
bool getEnableMeshVisible() const { return _skeletonModel->isVisible(); } bool getEnableMeshVisible() const { return _skeletonModel->isVisible(); }
void setEnableMeshVisible(bool isEnabled); void setEnableMeshVisible(bool isEnabled);
void setUseAnimPreAndPostRotations(bool isEnabled);
void setEnableInverseKinematics(bool isEnabled); void setEnableInverseKinematics(bool isEnabled);
QUrl getAnimGraphOverrideUrl() const; // thread-safe QUrl getAnimGraphOverrideUrl() const; // thread-safe
@ -841,6 +845,9 @@ private:
// height of user in sensor space, when standing erect. // height of user in sensor space, when standing erect.
ThreadSafeValueCache<float> _userHeight { DEFAULT_AVATAR_HEIGHT }; ThreadSafeValueCache<float> _userHeight { DEFAULT_AVATAR_HEIGHT };
// max unscaled forward movement speed
ThreadSafeValueCache<float> _walkSpeed { DEFAULT_AVATAR_MAX_WALKING_SPEED };
}; };
QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode); QScriptValue audioListenModeToScriptValue(QScriptEngine* engine, const AudioListenerMode& audioListenerMode);

View file

@ -46,6 +46,8 @@ Handler(buy)
Handler(receiveAt) Handler(receiveAt)
Handler(balance) Handler(balance)
Handler(inventory) Handler(inventory)
Handler(transferHfcToNode)
Handler(transferHfcToUsername)
void Ledger::send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, AccountManagerAuth::Type authType, QJsonObject request) { void Ledger::send(const QString& endpoint, const QString& success, const QString& fail, QNetworkAccessManager::Operation method, AccountManagerAuth::Type authType, QJsonObject request) {
auto accountManager = DependencyManager::get<AccountManager>(); auto accountManager = DependencyManager::get<AccountManager>();
@ -116,23 +118,60 @@ void Ledger::inventory(const QStringList& keys) {
keysQuery("inventory", "inventorySuccess", "inventoryFailure"); keysQuery("inventory", "inventorySuccess", "inventoryFailure");
} }
QString amountString(const QString& label, const QString&color, const QJsonValue& moneyValue, const QJsonValue& certsValue) { QString hfcString(const QJsonValue& sentValue, const QJsonValue& receivedValue) {
int money = moneyValue.toInt(); int sent = sentValue.toInt();
int certs = certsValue.toInt(); int received = receivedValue.toInt();
if (money <= 0 && certs <= 0) { if (sent <= 0 && received <= 0) {
return QString(); return QString("-");
} }
QString result(QString("<font color='#%1'> %2").arg(color, label)); QString result;
if (money > 0) { if (sent > 0) {
result += QString(" %1 HFC").arg(money); result += QString("<font color='#B70A37'>-%1 HFC</font>").arg(sent);
} if (received > 0) {
if (certs > 0) { result += QString("<br>");
if (money > 0) {
result += QString(",");
} }
result += QString((certs == 1) ? " %1 certificate" : " %1 certificates").arg(certs);
} }
return result + QString("</font>"); if (received > 0) {
result += QString("<font color='#3AA38F'>%1 HFC</font>").arg(received);
}
return result;
}
static const QString USER_PAGE_BASE_URL = NetworkingConstants::METAVERSE_SERVER_URL().toString() + "/users/";
QString userLink(const QString& username) {
if (username.isEmpty()) {
return QString("someone");
}
return QString("<a href=\"%1%2\">%2</a>").arg(USER_PAGE_BASE_URL, username);
}
QString transactionString(const QJsonObject& valueObject) {
int sentCerts = valueObject["sent_certs"].toInt();
int receivedCerts = valueObject["received_certs"].toInt();
int sent = valueObject["sent_money"].toInt();
int dateInteger = valueObject["created_at"].toInt();
QString message = valueObject["message"].toString();
QDateTime createdAt(QDateTime::fromSecsSinceEpoch(dateInteger, Qt::UTC));
QString result;
if (sentCerts <= 0 && receivedCerts <= 0) {
// this is an hfc transfer.
if (sent > 0) {
QString recipient = userLink(valueObject["recipient_name"].toString());
result += QString("Money sent to %1").arg(recipient);
} else {
QString sender = userLink(valueObject["sender_name"].toString());
result += QString("Money from %1").arg(sender);
}
if (!message.isEmpty()) {
result += QString("<br>with memo: <i>\"%1\"</i>").arg(message);
}
} else {
result += valueObject["message"].toString();
}
// no matter what we append a smaller date to the bottom of this...
result += QString("<br><font size='-2' color='#1080B8'>%1").arg(createdAt.toLocalTime().toString(Qt::DefaultLocaleShortDate));
return result;
} }
static const QString MARKETPLACE_ITEMS_BASE_URL = NetworkingConstants::METAVERSE_SERVER_URL().toString() + "/marketplace/items/"; static const QString MARKETPLACE_ITEMS_BASE_URL = NetworkingConstants::METAVERSE_SERVER_URL().toString() + "/marketplace/items/";
@ -155,16 +194,13 @@ void Ledger::historySuccess(QNetworkReply& reply) {
// TODO: do this with 0 copies if possible // TODO: do this with 0 copies if possible
for (auto it = historyArray.begin(); it != historyArray.end(); it++) { for (auto it = historyArray.begin(); it != historyArray.end(); it++) {
// We have 2 text fields to synthesize, the one on the left is a listing
// of the HFC in/out of your wallet. The one on the right contains an explaination
// of the transaction. That could be just the memo (if it is a regular purchase), or
// more text (plus the optional memo) if an hfc transfer
auto valueObject = (*it).toObject(); auto valueObject = (*it).toObject();
QString sent = amountString("sent", "EA4C5F", valueObject["sent_money"], valueObject["sent_certs"]); valueObject["hfc_text"] = hfcString(valueObject["sent_money"], valueObject["received_money"]);
QString received = amountString("received", "1FC6A6", valueObject["received_money"], valueObject["received_certs"]); valueObject["transaction_text"] = transactionString(valueObject);
// turns out on my machine, toLocalTime convert to some weird timezone, yet the
// systemTimeZone is correct. To avoid a strange bug with other's systems too, lets
// be explicit
QDateTime createdAt = QDateTime::fromSecsSinceEpoch(valueObject["created_at"].toInt(), Qt::UTC);
QDateTime localCreatedAt = createdAt.toTimeZone(QTimeZone::systemTimeZone());
valueObject["text"] = QString("%1%2%3").arg(valueObject["message"].toString(), sent, received);
newHistoryArray.push_back(valueObject); newHistoryArray.push_back(valueObject);
} }
// now copy the rest of the json -- this is inefficient // now copy the rest of the json -- this is inefficient
@ -198,11 +234,17 @@ void Ledger::accountSuccess(QNetworkReply& reply) {
auto salt = QByteArray::fromBase64(data["salt"].toString().toUtf8()); auto salt = QByteArray::fromBase64(data["salt"].toString().toUtf8());
auto iv = QByteArray::fromBase64(data["iv"].toString().toUtf8()); auto iv = QByteArray::fromBase64(data["iv"].toString().toUtf8());
auto ckey = QByteArray::fromBase64(data["ckey"].toString().toUtf8()); auto ckey = QByteArray::fromBase64(data["ckey"].toString().toUtf8());
QString remotePublicKey = data["public_key"].toString();
wallet->setSalt(salt); wallet->setSalt(salt);
wallet->setIv(iv); wallet->setIv(iv);
wallet->setCKey(ckey); wallet->setCKey(ckey);
QStringList localPublicKeys = wallet->listPublicKeys();
if (remotePublicKey.isEmpty() && !localPublicKeys.isEmpty()) {
receiveAt(localPublicKeys.first(), "");
}
// none of the hfc account info should be emitted // none of the hfc account info should be emitted
emit accountResult(QJsonObject{ {"status", "success"} }); emit accountResult(QJsonObject{ {"status", "success"} });
} }
@ -261,3 +303,25 @@ void Ledger::certificateInfo(const QString& certificateId) {
request["certificate_id"] = certificateId; request["certificate_id"] = certificateId;
send(endpoint, "certificateInfoSuccess", "certificateInfoFailure", QNetworkAccessManager::PutOperation, AccountManagerAuth::None, request); send(endpoint, "certificateInfoSuccess", "certificateInfoFailure", QNetworkAccessManager::PutOperation, AccountManagerAuth::None, request);
} }
void Ledger::transferHfcToNode(const QString& hfc_key, const QString& nodeID, const int& amount, const QString& optionalMessage) {
QJsonObject transaction;
transaction["public_key"] = hfc_key;
transaction["node_id"] = nodeID;
transaction["quantity"] = amount;
transaction["message"] = optionalMessage;
QJsonDocument transactionDoc{ transaction };
auto transactionString = transactionDoc.toJson(QJsonDocument::Compact);
signedSend("transaction", transactionString, hfc_key, "transfer_hfc_to_node", "transferHfcToNodeSuccess", "transferHfcToNodeFailure");
}
void Ledger::transferHfcToUsername(const QString& hfc_key, const QString& username, const int& amount, const QString& optionalMessage) {
QJsonObject transaction;
transaction["public_key"] = hfc_key;
transaction["username"] = username;
transaction["quantity"] = amount;
transaction["message"] = optionalMessage;
QJsonDocument transactionDoc{ transaction };
auto transactionString = transactionDoc.toJson(QJsonDocument::Compact);
signedSend("transaction", transactionString, hfc_key, "transfer_hfc_to_user", "transferHfcToUsernameSuccess", "transferHfcToUsernameFailure");
}

View file

@ -33,6 +33,8 @@ public:
void account(); void account();
void updateLocation(const QString& asset_id, const QString location, const bool controlledFailure = false); void updateLocation(const QString& asset_id, const QString location, const bool controlledFailure = false);
void certificateInfo(const QString& certificateId); void certificateInfo(const QString& certificateId);
void transferHfcToNode(const QString& hfc_key, const QString& nodeID, const int& amount, const QString& optionalMessage);
void transferHfcToUsername(const QString& hfc_key, const QString& username, const int& amount, const QString& optionalMessage);
enum CertificateStatus { enum CertificateStatus {
CERTIFICATE_STATUS_UNKNOWN = 0, CERTIFICATE_STATUS_UNKNOWN = 0,
@ -51,6 +53,8 @@ signals:
void accountResult(QJsonObject result); void accountResult(QJsonObject result);
void locationUpdateResult(QJsonObject result); void locationUpdateResult(QJsonObject result);
void certificateInfoResult(QJsonObject result); void certificateInfoResult(QJsonObject result);
void transferHfcToNodeResult(QJsonObject result);
void transferHfcToUsernameResult(QJsonObject result);
void updateCertificateStatus(const QString& certID, uint certStatus); void updateCertificateStatus(const QString& certID, uint certStatus);
@ -71,6 +75,10 @@ public slots:
void updateLocationFailure(QNetworkReply& reply); void updateLocationFailure(QNetworkReply& reply);
void certificateInfoSuccess(QNetworkReply& reply); void certificateInfoSuccess(QNetworkReply& reply);
void certificateInfoFailure(QNetworkReply& reply); void certificateInfoFailure(QNetworkReply& reply);
void transferHfcToNodeSuccess(QNetworkReply& reply);
void transferHfcToNodeFailure(QNetworkReply& reply);
void transferHfcToUsernameSuccess(QNetworkReply& reply);
void transferHfcToUsernameFailure(QNetworkReply& reply);
private: private:
QJsonObject apiResponse(const QString& label, QNetworkReply& reply); QJsonObject apiResponse(const QString& label, QNetworkReply& reply);

View file

@ -29,6 +29,8 @@ QmlCommerce::QmlCommerce() {
connect(wallet.data(), &Wallet::walletStatusResult, this, &QmlCommerce::walletStatusResult); connect(wallet.data(), &Wallet::walletStatusResult, this, &QmlCommerce::walletStatusResult);
connect(ledger.data(), &Ledger::certificateInfoResult, this, &QmlCommerce::certificateInfoResult); connect(ledger.data(), &Ledger::certificateInfoResult, this, &QmlCommerce::certificateInfoResult);
connect(ledger.data(), &Ledger::updateCertificateStatus, this, &QmlCommerce::updateCertificateStatus); connect(ledger.data(), &Ledger::updateCertificateStatus, this, &QmlCommerce::updateCertificateStatus);
connect(ledger.data(), &Ledger::transferHfcToNodeResult, this, &QmlCommerce::transferHfcToNodeResult);
connect(ledger.data(), &Ledger::transferHfcToUsernameResult, this, &QmlCommerce::transferHfcToUsernameResult);
auto accountManager = DependencyManager::get<AccountManager>(); auto accountManager = DependencyManager::get<AccountManager>();
connect(accountManager.data(), &AccountManager::usernameChanged, this, [&]() { connect(accountManager.data(), &AccountManager::usernameChanged, this, [&]() {
@ -137,3 +139,27 @@ void QmlCommerce::certificateInfo(const QString& certificateId) {
auto ledger = DependencyManager::get<Ledger>(); auto ledger = DependencyManager::get<Ledger>();
ledger->certificateInfo(certificateId); ledger->certificateInfo(certificateId);
} }
void QmlCommerce::transferHfcToNode(const QString& nodeID, const int& amount, const QString& optionalMessage) {
auto ledger = DependencyManager::get<Ledger>();
auto wallet = DependencyManager::get<Wallet>();
QStringList keys = wallet->listPublicKeys();
if (keys.count() == 0) {
QJsonObject result{ { "status", "fail" },{ "message", "Uninitialized Wallet." } };
return emit buyResult(result);
}
QString key = keys[0];
ledger->transferHfcToNode(key, nodeID, amount, optionalMessage);
}
void QmlCommerce::transferHfcToUsername(const QString& username, const int& amount, const QString& optionalMessage) {
auto ledger = DependencyManager::get<Ledger>();
auto wallet = DependencyManager::get<Wallet>();
QStringList keys = wallet->listPublicKeys();
if (keys.count() == 0) {
QJsonObject result{ { "status", "fail" },{ "message", "Uninitialized Wallet." } };
return emit buyResult(result);
}
QString key = keys[0];
ledger->transferHfcToUsername(key, username, amount, optionalMessage);
}

View file

@ -45,6 +45,9 @@ signals:
void updateCertificateStatus(const QString& certID, uint certStatus); void updateCertificateStatus(const QString& certID, uint certStatus);
void transferHfcToNodeResult(QJsonObject result);
void transferHfcToUsernameResult(QJsonObject result);
protected: protected:
Q_INVOKABLE void getWalletStatus(); Q_INVOKABLE void getWalletStatus();
@ -65,6 +68,9 @@ protected:
Q_INVOKABLE void account(); Q_INVOKABLE void account();
Q_INVOKABLE void certificateInfo(const QString& certificateId); Q_INVOKABLE void certificateInfo(const QString& certificateId);
Q_INVOKABLE void transferHfcToNode(const QString& nodeID, const int& amount, const QString& optionalMessage);
Q_INVOKABLE void transferHfcToUsername(const QString& username, const int& amount, const QString& optionalMessage);
}; };
#endif // hifi_QmlCommerce_h #endif // hifi_QmlCommerce_h

View file

@ -1,36 +0,0 @@
//
// AccountScriptingInterface.cpp
// interface/src/scripting
//
// Created by Stojce Slavkovski on 6/07/14.
// Copyright 2014 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "AccountManager.h"
#include "AccountScriptingInterface.h"
#include "GlobalServicesScriptingInterface.h"
AccountScriptingInterface* AccountScriptingInterface::getInstance() {
static AccountScriptingInterface sharedInstance;
return &sharedInstance;
}
bool AccountScriptingInterface::isLoggedIn() {
return GlobalServicesScriptingInterface::getInstance()->isLoggedIn();
}
void AccountScriptingInterface::logOut() {
GlobalServicesScriptingInterface::getInstance()->logOut();
}
bool AccountScriptingInterface::loggedIn() const {
return GlobalServicesScriptingInterface::getInstance()->loggedIn();
}
QString AccountScriptingInterface::getUsername() {
return GlobalServicesScriptingInterface::getInstance()->getUsername();
}

View file

@ -1,60 +0,0 @@
//
// AccountScriptingInterface.h
// interface/src/scripting
//
// Created by Stojce Slavkovski on 6/07/14.
// Copyright 2014 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_AccountScriptingInterface_h
#define hifi_AccountScriptingInterface_h
#include <QObject>
class AccountScriptingInterface : public QObject {
Q_OBJECT
/**jsdoc
* @namespace Account
* @property username {String} username if user is logged in, otherwise it returns "Unknown user"
*/
Q_PROPERTY(QString username READ getUsername)
Q_PROPERTY(bool loggedIn READ loggedIn)
signals:
/**jsdoc
* Triggered when username has changed.
* @function Account.usernameChanged
* @return {Signal}
*/
void usernameChanged();
void loggedInChanged(bool loggedIn);
public slots:
static AccountScriptingInterface* getInstance();
/**jsdoc
* Returns the username for the currently logged in High Fidelity metaverse account.
* @function Account.getUsername
* @return {string} username if user is logged in, otherwise it returns "Unknown user"
*/
QString getUsername();
/**jsdoc
* Determine if the user is logged into the High Fidleity metaverse.
* @function Account.isLoggedIn
* @return {bool} true when user is logged into the High Fidelity metaverse.
*/
bool isLoggedIn();
void logOut();
public:
AccountScriptingInterface(QObject* parent = nullptr) {}
bool loggedIn() const;
};
#endif // hifi_AccountScriptingInterface_h

View file

@ -1,5 +1,5 @@
// //
// GlobalServicesScriptingInterface.cpp // AccountServicesScriptingInterface.cpp
// interface/src/scripting // interface/src/scripting
// //
// Created by Thijs Wenker on 9/10/14. // Created by Thijs Wenker on 9/10/14.
@ -14,41 +14,41 @@
#include "DiscoverabilityManager.h" #include "DiscoverabilityManager.h"
#include "ResourceCache.h" #include "ResourceCache.h"
#include "GlobalServicesScriptingInterface.h" #include "AccountServicesScriptingInterface.h"
GlobalServicesScriptingInterface::GlobalServicesScriptingInterface() { AccountServicesScriptingInterface::AccountServicesScriptingInterface() {
auto accountManager = DependencyManager::get<AccountManager>(); auto accountManager = DependencyManager::get<AccountManager>();
connect(accountManager.data(), &AccountManager::usernameChanged, this, &GlobalServicesScriptingInterface::onUsernameChanged); connect(accountManager.data(), &AccountManager::usernameChanged, this, &AccountServicesScriptingInterface::onUsernameChanged);
connect(accountManager.data(), &AccountManager::logoutComplete, this, &GlobalServicesScriptingInterface::loggedOut); connect(accountManager.data(), &AccountManager::logoutComplete, this, &AccountServicesScriptingInterface::loggedOut);
connect(accountManager.data(), &AccountManager::loginComplete, this, &GlobalServicesScriptingInterface::connected); connect(accountManager.data(), &AccountManager::loginComplete, this, &AccountServicesScriptingInterface::connected);
_downloading = false; _downloading = false;
QTimer* checkDownloadTimer = new QTimer(this); QTimer* checkDownloadTimer = new QTimer(this);
connect(checkDownloadTimer, &QTimer::timeout, this, &GlobalServicesScriptingInterface::checkDownloadInfo); connect(checkDownloadTimer, &QTimer::timeout, this, &AccountServicesScriptingInterface::checkDownloadInfo);
const int CHECK_DOWNLOAD_INTERVAL = MSECS_PER_SECOND / 2; const int CHECK_DOWNLOAD_INTERVAL = MSECS_PER_SECOND / 2;
checkDownloadTimer->start(CHECK_DOWNLOAD_INTERVAL); checkDownloadTimer->start(CHECK_DOWNLOAD_INTERVAL);
auto discoverabilityManager = DependencyManager::get<DiscoverabilityManager>(); auto discoverabilityManager = DependencyManager::get<DiscoverabilityManager>();
connect(discoverabilityManager.data(), &DiscoverabilityManager::discoverabilityModeChanged, connect(discoverabilityManager.data(), &DiscoverabilityManager::discoverabilityModeChanged,
this, &GlobalServicesScriptingInterface::discoverabilityModeChanged); this, &AccountServicesScriptingInterface::discoverabilityModeChanged);
_loggedIn = isLoggedIn(); _loggedIn = isLoggedIn();
emit loggedInChanged(_loggedIn); emit loggedInChanged(_loggedIn);
} }
GlobalServicesScriptingInterface::~GlobalServicesScriptingInterface() { AccountServicesScriptingInterface::~AccountServicesScriptingInterface() {
auto accountManager = DependencyManager::get<AccountManager>(); auto accountManager = DependencyManager::get<AccountManager>();
disconnect(accountManager.data(), &AccountManager::usernameChanged, this, &GlobalServicesScriptingInterface::onUsernameChanged); disconnect(accountManager.data(), &AccountManager::usernameChanged, this, &AccountServicesScriptingInterface::onUsernameChanged);
disconnect(accountManager.data(), &AccountManager::logoutComplete, this, &GlobalServicesScriptingInterface::loggedOut); disconnect(accountManager.data(), &AccountManager::logoutComplete, this, &AccountServicesScriptingInterface::loggedOut);
disconnect(accountManager.data(), &AccountManager::loginComplete, this, &GlobalServicesScriptingInterface::connected); disconnect(accountManager.data(), &AccountManager::loginComplete, this, &AccountServicesScriptingInterface::connected);
} }
GlobalServicesScriptingInterface* GlobalServicesScriptingInterface::getInstance() { AccountServicesScriptingInterface* AccountServicesScriptingInterface::getInstance() {
static GlobalServicesScriptingInterface sharedInstance; static AccountServicesScriptingInterface sharedInstance;
return &sharedInstance; return &sharedInstance;
} }
const QString GlobalServicesScriptingInterface::getUsername() const { const QString AccountServicesScriptingInterface::getUsername() const {
auto accountManager = DependencyManager::get<AccountManager>(); auto accountManager = DependencyManager::get<AccountManager>();
if (accountManager->isLoggedIn()) { if (accountManager->isLoggedIn()) {
return accountManager->getAccountInfo().getUsername(); return accountManager->getAccountInfo().getUsername();
@ -57,31 +57,31 @@ const QString GlobalServicesScriptingInterface::getUsername() const {
} }
} }
bool GlobalServicesScriptingInterface::isLoggedIn() { bool AccountServicesScriptingInterface::isLoggedIn() {
auto accountManager = DependencyManager::get<AccountManager>(); auto accountManager = DependencyManager::get<AccountManager>();
return accountManager->isLoggedIn(); return accountManager->isLoggedIn();
} }
bool GlobalServicesScriptingInterface::checkAndSignalForAccessToken() { bool AccountServicesScriptingInterface::checkAndSignalForAccessToken() {
auto accountManager = DependencyManager::get<AccountManager>(); auto accountManager = DependencyManager::get<AccountManager>();
return accountManager->checkAndSignalForAccessToken(); return accountManager->checkAndSignalForAccessToken();
} }
void GlobalServicesScriptingInterface::logOut() { void AccountServicesScriptingInterface::logOut() {
auto accountManager = DependencyManager::get<AccountManager>(); auto accountManager = DependencyManager::get<AccountManager>();
return accountManager->logout(); return accountManager->logout();
} }
void GlobalServicesScriptingInterface::loggedOut() { void AccountServicesScriptingInterface::loggedOut() {
emit GlobalServicesScriptingInterface::disconnected(QString("logout")); emit AccountServicesScriptingInterface::disconnected(QString("logout"));
} }
QString GlobalServicesScriptingInterface::getFindableBy() const { QString AccountServicesScriptingInterface::getFindableBy() const {
auto discoverabilityManager = DependencyManager::get<DiscoverabilityManager>(); auto discoverabilityManager = DependencyManager::get<DiscoverabilityManager>();
return DiscoverabilityManager::findableByString(discoverabilityManager->getDiscoverabilityMode()); return DiscoverabilityManager::findableByString(discoverabilityManager->getDiscoverabilityMode());
} }
void GlobalServicesScriptingInterface::setFindableBy(const QString& discoverabilityMode) { void AccountServicesScriptingInterface::setFindableBy(const QString& discoverabilityMode) {
auto discoverabilityManager = DependencyManager::get<DiscoverabilityManager>(); auto discoverabilityManager = DependencyManager::get<DiscoverabilityManager>();
if (discoverabilityMode.toLower() == "none") { if (discoverabilityMode.toLower() == "none") {
discoverabilityManager->setDiscoverabilityMode(Discoverability::None); discoverabilityManager->setDiscoverabilityMode(Discoverability::None);
@ -96,11 +96,11 @@ void GlobalServicesScriptingInterface::setFindableBy(const QString& discoverabil
} }
} }
void GlobalServicesScriptingInterface::discoverabilityModeChanged(Discoverability::Mode discoverabilityMode) { void AccountServicesScriptingInterface::discoverabilityModeChanged(Discoverability::Mode discoverabilityMode) {
emit findableByChanged(DiscoverabilityManager::findableByString(discoverabilityMode)); emit findableByChanged(DiscoverabilityManager::findableByString(discoverabilityMode));
} }
void GlobalServicesScriptingInterface::onUsernameChanged(const QString& username) { void AccountServicesScriptingInterface::onUsernameChanged(const QString& username) {
_loggedIn = (username != QString()); _loggedIn = (username != QString());
emit myUsernameChanged(username); emit myUsernameChanged(username);
emit loggedInChanged(_loggedIn); emit loggedInChanged(_loggedIn);
@ -135,7 +135,7 @@ void DownloadInfoResultFromScriptValue(const QScriptValue& object, DownloadInfoR
result.pending = object.property("pending").toVariant().toFloat(); result.pending = object.property("pending").toVariant().toFloat();
} }
DownloadInfoResult GlobalServicesScriptingInterface::getDownloadInfo() { DownloadInfoResult AccountServicesScriptingInterface::getDownloadInfo() {
DownloadInfoResult result; DownloadInfoResult result;
foreach(const auto& resource, ResourceCache::getLoadingRequests()) { foreach(const auto& resource, ResourceCache::getLoadingRequests()) {
result.downloading.append(resource->getProgress() * 100.0f); result.downloading.append(resource->getProgress() * 100.0f);
@ -144,7 +144,7 @@ DownloadInfoResult GlobalServicesScriptingInterface::getDownloadInfo() {
return result; return result;
} }
void GlobalServicesScriptingInterface::checkDownloadInfo() { void AccountServicesScriptingInterface::checkDownloadInfo() {
DownloadInfoResult downloadInfo = getDownloadInfo(); DownloadInfoResult downloadInfo = getDownloadInfo();
bool downloading = downloadInfo.downloading.count() > 0 || downloadInfo.pending > 0; bool downloading = downloadInfo.downloading.count() > 0 || downloadInfo.pending > 0;
@ -155,7 +155,7 @@ void GlobalServicesScriptingInterface::checkDownloadInfo() {
} }
} }
void GlobalServicesScriptingInterface::updateDownloadInfo() { void AccountServicesScriptingInterface::updateDownloadInfo() {
emit downloadInfoChanged(getDownloadInfo()); emit downloadInfoChanged(getDownloadInfo());
} }

View file

@ -1,5 +1,5 @@
// //
// GlobalServicesScriptingInterface.h // AccountServicesScriptingInterface.h
// interface/src/scripting // interface/src/scripting
// //
// Created by Thijs Wenker on 9/10/14. // Created by Thijs Wenker on 9/10/14.
@ -9,8 +9,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
// //
#ifndef hifi_GlobalServicesScriptingInterface_h #ifndef hifi_AccountServicesScriptingInterface_h
#define hifi_GlobalServicesScriptingInterface_h #define hifi_AccountServicesScriptingInterface_h
#include <QObject> #include <QObject>
#include <QScriptContext> #include <QScriptContext>
@ -32,7 +32,7 @@ Q_DECLARE_METATYPE(DownloadInfoResult)
QScriptValue DownloadInfoResultToScriptValue(QScriptEngine* engine, const DownloadInfoResult& result); QScriptValue DownloadInfoResultToScriptValue(QScriptEngine* engine, const DownloadInfoResult& result);
void DownloadInfoResultFromScriptValue(const QScriptValue& object, DownloadInfoResult& result); void DownloadInfoResultFromScriptValue(const QScriptValue& object, DownloadInfoResult& result);
class GlobalServicesScriptingInterface : public QObject { class AccountServicesScriptingInterface : public QObject {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QString username READ getUsername NOTIFY myUsernameChanged) Q_PROPERTY(QString username READ getUsername NOTIFY myUsernameChanged)
@ -41,7 +41,7 @@ class GlobalServicesScriptingInterface : public QObject {
Q_PROPERTY(QUrl metaverseServerURL READ getMetaverseServerURL) Q_PROPERTY(QUrl metaverseServerURL READ getMetaverseServerURL)
public: public:
static GlobalServicesScriptingInterface* getInstance(); static AccountServicesScriptingInterface* getInstance();
const QString getUsername() const; const QString getUsername() const;
bool loggedIn() const { return _loggedIn; } bool loggedIn() const { return _loggedIn; }
@ -74,11 +74,11 @@ signals:
void loggedInChanged(bool loggedIn); void loggedInChanged(bool loggedIn);
private: private:
GlobalServicesScriptingInterface(); AccountServicesScriptingInterface();
~GlobalServicesScriptingInterface(); ~AccountServicesScriptingInterface();
bool _downloading; bool _downloading;
bool _loggedIn{ false }; bool _loggedIn{ false };
}; };
#endif // hifi_GlobalServicesScriptingInterface_h #endif // hifi_AccountServicesScriptingInterface_h

View file

@ -411,6 +411,11 @@ int WindowScriptingInterface::getY() {
} }
void WindowScriptingInterface::copyToClipboard(const QString& text) { void WindowScriptingInterface::copyToClipboard(const QString& text) {
if (QThread::currentThread() != qApp->thread()) {
QMetaObject::invokeMethod(this, "copyToClipboard", Q_ARG(QString, text));
return;
}
qDebug() << "Copying"; qDebug() << "Copying";
QApplication::clipboard()->setText(text); QApplication::clipboard()->setText(text);
} }

View file

@ -42,7 +42,7 @@ void CustomPromptResultFromScriptValue(const QScriptValue& object, CustomPromptR
* @property {number} innerWidth - The width of the drawable area of the Interface window (i.e., without borders or other * @property {number} innerWidth - The width of the drawable area of the Interface window (i.e., without borders or other
* chrome), in pixels. <em>Read-only.</em> * chrome), in pixels. <em>Read-only.</em>
* @property {number} innerHeight - The height of the drawable area of the Interface window (i.e., without borders or other * @property {number} innerHeight - The height of the drawable area of the Interface window (i.e., without borders or other
* chrome) plus the height of the menu bar, in pixels. <em>Read-only.</em> * chrome), in pixels. <em>Read-only.</em>
* @property {object} location - Provides facilities for working with your current metaverse location. See {@link location}. * @property {object} location - Provides facilities for working with your current metaverse location. See {@link location}.
* @property {number} x - The x coordinate of the top left corner of the Interface window on the display. <em>Read-only.</em> * @property {number} x - The x coordinate of the top left corner of the Interface window on the display. <em>Read-only.</em>
* @property {number} y - The y coordinate of the top left corner of the Interface window on the display. <em>Read-only.</em> * @property {number} y - The y coordinate of the top left corner of the Interface window on the display. <em>Read-only.</em>
@ -301,7 +301,7 @@ public slots:
/**jsdoc /**jsdoc
* Get Interface's build number. * Get Interface's build number.
* @function Window.checkVersion * @function Window.checkVersion
* @returns {string} - Interface's build number. * @returns {string} Interface's build number.
*/ */
QString checkVersion(); QString checkVersion();
@ -327,7 +327,7 @@ public slots:
* full resolution is used (window dimensions in desktop mode; HMD display dimensions in HMD mode), otherwise one of the * full resolution is used (window dimensions in desktop mode; HMD display dimensions in HMD mode), otherwise one of the
* dimensions is adjusted in order to match the aspect ratio. * dimensions is adjusted in order to match the aspect ratio.
* @example <caption>Using the snapshot function and signals.</caption> * @example <caption>Using the snapshot function and signals.</caption>
* function onStillSnapshottaken(path, notify) { * function onStillSnapshotTaken(path, notify) {
* print("Still snapshot taken: " + path); * print("Still snapshot taken: " + path);
* print("Notify: " + notify); * print("Notify: " + notify);
* } * }
@ -340,7 +340,7 @@ public slots:
* print("Animated snapshot taken: " + animatedPath); * print("Animated snapshot taken: " + animatedPath);
* } * }
* *
* Window.stillSnapshotTaken.connect(onStillSnapshottaken); * Window.stillSnapshotTaken.connect(onStillSnapshotTaken);
* Window.processingGifStarted.connect(onProcessingGifStarted); * Window.processingGifStarted.connect(onProcessingGifStarted);
* Window.processingGifCompleted.connect(onProcessingGifCompleted); * Window.processingGifCompleted.connect(onProcessingGifCompleted);
* *
@ -555,7 +555,7 @@ signals:
/**jsdoc /**jsdoc
* Triggered when a still snapshot has been taken by calling {@link Window.takeSnapshot|takeSnapshot} with * Triggered when a still snapshot has been taken by calling {@link Window.takeSnapshot|takeSnapshot} with
* <code>includeAnimated = false</code>. * <code>includeAnimated = false</code> or {@link Window.takeSecondaryCameraSnapshot|takeSecondaryCameraSnapshot}.
* @function Window.stillSnapshotTaken * @function Window.stillSnapshotTaken
* @param {string} pathStillSnapshot - The path and name of the snapshot image file. * @param {string} pathStillSnapshot - The path and name of the snapshot image file.
* @param {boolean} notify - The value of the <code>notify</code> parameter that {@link Window.takeSnapshot|takeSnapshot} * @param {boolean} notify - The value of the <code>notify</code> parameter that {@link Window.takeSnapshot|takeSnapshot}

View file

@ -50,7 +50,7 @@
#include "ui/DomainConnectionModel.h" #include "ui/DomainConnectionModel.h"
#include "ui/AvatarInputs.h" #include "ui/AvatarInputs.h"
#include "avatar/AvatarManager.h" #include "avatar/AvatarManager.h"
#include "scripting/GlobalServicesScriptingInterface.h" #include "scripting/AccountServicesScriptingInterface.h"
#include <plugins/InputConfiguration.h> #include <plugins/InputConfiguration.h>
#include "ui/Snapshot.h" #include "ui/Snapshot.h"
#include "SoundCache.h" #include "SoundCache.h"
@ -192,7 +192,10 @@ void Web3DOverlay::setupQmlSurface() {
_webSurface->getSurfaceContext()->setContextProperty("offscreenFlags", flags); _webSurface->getSurfaceContext()->setContextProperty("offscreenFlags", flags);
_webSurface->getSurfaceContext()->setContextProperty("AddressManager", DependencyManager::get<AddressManager>().data()); _webSurface->getSurfaceContext()->setContextProperty("AddressManager", DependencyManager::get<AddressManager>().data());
_webSurface->getSurfaceContext()->setContextProperty("Account", GlobalServicesScriptingInterface::getInstance());
_webSurface->getSurfaceContext()->setContextProperty("Account", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED
_webSurface->getSurfaceContext()->setContextProperty("GlobalServices", AccountServicesScriptingInterface::getInstance()); // DEPRECATED - TO BE REMOVED
_webSurface->getSurfaceContext()->setContextProperty("AccountServices", AccountServicesScriptingInterface::getInstance());
// in Qt 5.10.0 there is already an "Audio" object in the QML context // in Qt 5.10.0 there is already an "Audio" object in the QML context
// though I failed to find it (from QtMultimedia??). So.. let it be "AudioScriptingInterface" // though I failed to find it (from QtMultimedia??). So.. let it be "AudioScriptingInterface"
@ -208,7 +211,6 @@ void Web3DOverlay::setupQmlSurface() {
_webSurface->getSurfaceContext()->setContextProperty("OctreeStats", DependencyManager::get<OctreeStatsProvider>().data()); _webSurface->getSurfaceContext()->setContextProperty("OctreeStats", DependencyManager::get<OctreeStatsProvider>().data());
_webSurface->getSurfaceContext()->setContextProperty("DCModel", DependencyManager::get<DomainConnectionModel>().data()); _webSurface->getSurfaceContext()->setContextProperty("DCModel", DependencyManager::get<DomainConnectionModel>().data());
_webSurface->getSurfaceContext()->setContextProperty("AvatarInputs", AvatarInputs::getInstance()); _webSurface->getSurfaceContext()->setContextProperty("AvatarInputs", AvatarInputs::getInstance());
_webSurface->getSurfaceContext()->setContextProperty("GlobalServices", GlobalServicesScriptingInterface::getInstance());
_webSurface->getSurfaceContext()->setContextProperty("AvatarList", DependencyManager::get<AvatarManager>().data()); _webSurface->getSurfaceContext()->setContextProperty("AvatarList", DependencyManager::get<AvatarManager>().data());
_webSurface->getSurfaceContext()->setContextProperty("DialogsManager", DialogsManagerScriptingInterface::getInstance()); _webSurface->getSurfaceContext()->setContextProperty("DialogsManager", DialogsManagerScriptingInterface::getInstance());
_webSurface->getSurfaceContext()->setContextProperty("InputConfiguration", DependencyManager::get<InputConfiguration>().data()); _webSurface->getSurfaceContext()->setContextProperty("InputConfiguration", DependencyManager::get<InputConfiguration>().data());

View file

@ -1,6 +1,6 @@
set(TARGET_NAME animation) set(TARGET_NAME animation)
setup_hifi_library(Network Script) setup_hifi_library(Network Script)
link_hifi_libraries(shared model fbx) link_hifi_libraries(shared graphics fbx)
include_hifi_library_headers(networking) include_hifi_library_headers(networking)
include_hifi_library_headers(gpu) include_hifi_library_headers(gpu)

View file

@ -13,8 +13,6 @@
#include "AnimationLogging.h" #include "AnimationLogging.h"
#include "AnimUtil.h" #include "AnimUtil.h"
bool AnimClip::usePreAndPostPoseFromAnim = true;
AnimClip::AnimClip(const QString& id, const QString& url, float startFrame, float endFrame, float timeScale, bool loopFlag, bool mirrorFlag) : AnimClip::AnimClip(const QString& id, const QString& url, float startFrame, float endFrame, float timeScale, bool loopFlag, bool mirrorFlag) :
AnimNode(AnimNode::Type::Clip, id), AnimNode(AnimNode::Type::Clip, id),
_startFrame(startFrame), _startFrame(startFrame),
@ -138,14 +136,8 @@ void AnimClip::copyFromNetworkAnim() {
if (skeletonJoint >= 0 && skeletonJoint < skeletonJointCount) { if (skeletonJoint >= 0 && skeletonJoint < skeletonJointCount) {
AnimPose preRot, postRot; AnimPose preRot, postRot;
if (usePreAndPostPoseFromAnim) { preRot = animSkeleton.getPreRotationPose(animJoint);
preRot = animSkeleton.getPreRotationPose(animJoint); postRot = animSkeleton.getPostRotationPose(animJoint);
postRot = animSkeleton.getPostRotationPose(animJoint);
} else {
// In order to support Blender, which does not have preRotation FBX support, we use the models defaultPose as the reference frame for the animations.
preRot = AnimPose(glm::vec3(1.0f), _skeleton->getRelativeBindPose(skeletonJoint).rot(), glm::vec3());
postRot = AnimPose::identity;
}
// cancel out scale // cancel out scale
preRot.scale() = glm::vec3(1.0f); preRot.scale() = glm::vec3(1.0f);

View file

@ -25,8 +25,6 @@ class AnimClip : public AnimNode {
public: public:
friend class AnimTests; friend class AnimTests;
static bool usePreAndPostPoseFromAnim;
AnimClip(const QString& id, const QString& url, float startFrame, float endFrame, float timeScale, bool loopFlag, bool mirrorFlag); AnimClip(const QString& id, const QString& url, float startFrame, float endFrame, float timeScale, bool loopFlag, bool mirrorFlag);
virtual ~AnimClip() override; virtual ~AnimClip() override;

View file

@ -1255,7 +1255,7 @@ void AnimInverseKinematics::initConstraints() {
// / / // / /
// O--O O--O // O--O O--O
loadDefaultPoses(_skeleton->getRelativeBindPoses()); loadDefaultPoses(_skeleton->getRelativeDefaultPoses());
int numJoints = (int)_defaultRelativePoses.size(); int numJoints = (int)_defaultRelativePoses.size();

View file

@ -33,7 +33,7 @@ AnimManipulator::~AnimManipulator() {
} }
const AnimPoseVec& AnimManipulator::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut) { const AnimPoseVec& AnimManipulator::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut) {
return overlay(animVars, context, dt, triggersOut, _skeleton->getRelativeBindPoses()); return overlay(animVars, context, dt, triggersOut, _skeleton->getRelativeDefaultPoses());
} }
const AnimPoseVec& AnimManipulator::overlay(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) { const AnimPoseVec& AnimManipulator::overlay(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) {

View file

@ -56,14 +56,6 @@ int AnimSkeleton::getChainDepth(int jointIndex) const {
} }
} }
const AnimPose& AnimSkeleton::getAbsoluteBindPose(int jointIndex) const {
return _absoluteBindPoses[jointIndex];
}
const AnimPose& AnimSkeleton::getRelativeBindPose(int jointIndex) const {
return _relativeBindPoses[jointIndex];
}
const AnimPose& AnimSkeleton::getRelativeDefaultPose(int jointIndex) const { const AnimPose& AnimSkeleton::getRelativeDefaultPose(int jointIndex) const {
return _relativeDefaultPoses[jointIndex]; return _relativeDefaultPoses[jointIndex];
} }
@ -164,8 +156,6 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector<FBXJoint>& joints)
_joints = joints; _joints = joints;
_jointsSize = (int)joints.size(); _jointsSize = (int)joints.size();
// build a cache of bind poses // build a cache of bind poses
_absoluteBindPoses.reserve(_jointsSize);
_relativeBindPoses.reserve(_jointsSize);
// build a chache of default poses // build a chache of default poses
_absoluteDefaultPoses.reserve(_jointsSize); _absoluteDefaultPoses.reserve(_jointsSize);
@ -192,28 +182,6 @@ void AnimSkeleton::buildSkeletonFromJoints(const std::vector<FBXJoint>& joints)
} else { } else {
_absoluteDefaultPoses.push_back(relDefaultPose); _absoluteDefaultPoses.push_back(relDefaultPose);
} }
// build relative and absolute bind poses
if (_joints[i].bindTransformFoundInCluster) {
// Use the FBXJoint::bindTransform, which is absolute model coordinates
// i.e. not relative to it's parent.
AnimPose absoluteBindPose(_joints[i].bindTransform);
_absoluteBindPoses.push_back(absoluteBindPose);
if (parentIndex >= 0) {
AnimPose inverseParentAbsoluteBindPose = _absoluteBindPoses[parentIndex].inverse();
_relativeBindPoses.push_back(inverseParentAbsoluteBindPose * absoluteBindPose);
} else {
_relativeBindPoses.push_back(absoluteBindPose);
}
} else {
// use default transform instead
_relativeBindPoses.push_back(relDefaultPose);
if (parentIndex >= 0) {
_absoluteBindPoses.push_back(_absoluteBindPoses[parentIndex] * relDefaultPose);
} else {
_absoluteBindPoses.push_back(relDefaultPose);
}
}
} }
for (int i = 0; i < _jointsSize; i++) { for (int i = 0; i < _jointsSize; i++) {
@ -251,8 +219,6 @@ void AnimSkeleton::dump(bool verbose) const {
qCDebug(animation) << " {"; qCDebug(animation) << " {";
qCDebug(animation) << " index =" << i; qCDebug(animation) << " index =" << i;
qCDebug(animation) << " name =" << getJointName(i); qCDebug(animation) << " name =" << getJointName(i);
qCDebug(animation) << " absBindPose =" << getAbsoluteBindPose(i);
qCDebug(animation) << " relBindPose =" << getRelativeBindPose(i);
qCDebug(animation) << " absDefaultPose =" << getAbsoluteDefaultPose(i); qCDebug(animation) << " absDefaultPose =" << getAbsoluteDefaultPose(i);
qCDebug(animation) << " relDefaultPose =" << getRelativeDefaultPose(i); qCDebug(animation) << " relDefaultPose =" << getRelativeDefaultPose(i);
if (verbose) { if (verbose) {
@ -287,8 +253,6 @@ void AnimSkeleton::dump(const AnimPoseVec& poses) const {
qCDebug(animation) << " {"; qCDebug(animation) << " {";
qCDebug(animation) << " index =" << i; qCDebug(animation) << " index =" << i;
qCDebug(animation) << " name =" << getJointName(i); qCDebug(animation) << " name =" << getJointName(i);
qCDebug(animation) << " absBindPose =" << getAbsoluteBindPose(i);
qCDebug(animation) << " relBindPose =" << getRelativeBindPose(i);
qCDebug(animation) << " absDefaultPose =" << getAbsoluteDefaultPose(i); qCDebug(animation) << " absDefaultPose =" << getAbsoluteDefaultPose(i);
qCDebug(animation) << " relDefaultPose =" << getRelativeDefaultPose(i); qCDebug(animation) << " relDefaultPose =" << getRelativeDefaultPose(i);
qCDebug(animation) << " pose =" << poses[i]; qCDebug(animation) << " pose =" << poses[i];

View file

@ -30,13 +30,6 @@ public:
int getNumJoints() const; int getNumJoints() const;
int getChainDepth(int jointIndex) const; int getChainDepth(int jointIndex) const;
// absolute pose, not relative to parent
const AnimPose& getAbsoluteBindPose(int jointIndex) const;
// relative to parent pose
const AnimPose& getRelativeBindPose(int jointIndex) const;
const AnimPoseVec& getRelativeBindPoses() const { return _relativeBindPoses; }
// the default poses are the orientations of the joints on frame 0. // the default poses are the orientations of the joints on frame 0.
const AnimPose& getRelativeDefaultPose(int jointIndex) const; const AnimPose& getRelativeDefaultPose(int jointIndex) const;
const AnimPoseVec& getRelativeDefaultPoses() const { return _relativeDefaultPoses; } const AnimPoseVec& getRelativeDefaultPoses() const { return _relativeDefaultPoses; }
@ -72,8 +65,6 @@ protected:
std::vector<FBXJoint> _joints; std::vector<FBXJoint> _joints;
int _jointsSize { 0 }; int _jointsSize { 0 };
AnimPoseVec _absoluteBindPoses;
AnimPoseVec _relativeBindPoses;
AnimPoseVec _relativeDefaultPoses; AnimPoseVec _relativeDefaultPoses;
AnimPoseVec _absoluteDefaultPoses; AnimPoseVec _absoluteDefaultPoses;
AnimPoseVec _relativePreRotationPoses; AnimPoseVec _relativePreRotationPoses;

View file

@ -179,7 +179,7 @@ void Rig::restoreRoleAnimation(const QString& role) {
} else { } else {
qCWarning(animation) << "Rig::restoreRoleAnimation could not find role " << role; qCWarning(animation) << "Rig::restoreRoleAnimation could not find role " << role;
} }
auto statesIter = _roleAnimStates.find(role); auto statesIter = _roleAnimStates.find(role);
if (statesIter != _roleAnimStates.end()) { if (statesIter != _roleAnimStates.end()) {
_roleAnimStates.erase(statesIter); _roleAnimStates.erase(statesIter);
@ -1050,52 +1050,6 @@ void Rig::updateAnimations(float deltaTime, const glm::mat4& rootTransform, cons
} }
} }
void Rig::inverseKinematics(int endIndex, glm::vec3 targetPosition, const glm::quat& targetRotation, float priority,
const QVector<int>& freeLineage, glm::mat4 rootTransform) {
ASSERT(false);
}
bool Rig::restoreJointPosition(int jointIndex, float fraction, float priority, const QVector<int>& freeLineage) {
ASSERT(false);
return false;
}
float Rig::getLimbLength(int jointIndex, const QVector<int>& freeLineage,
const glm::vec3 scale, const QVector<FBXJoint>& fbxJoints) const {
ASSERT(false);
return 1.0f;
}
glm::quat Rig::setJointRotationInBindFrame(int jointIndex, const glm::quat& rotation, float priority) {
ASSERT(false);
return glm::quat();
}
glm::vec3 Rig::getJointDefaultTranslationInConstrainedFrame(int jointIndex) {
ASSERT(false);
return glm::vec3();
}
glm::quat Rig::setJointRotationInConstrainedFrame(int jointIndex, glm::quat targetRotation, float priority, float mix) {
ASSERT(false);
return glm::quat();
}
bool Rig::getJointRotationInConstrainedFrame(int jointIndex, glm::quat& quatOut) const {
ASSERT(false);
return false;
}
void Rig::clearJointStatePriorities() {
ASSERT(false);
}
glm::quat Rig::getJointDefaultRotationInParentFrame(int jointIndex) {
ASSERT(false);
return glm::quat();
}
void Rig::updateFromEyeParameters(const EyeParameters& params) { void Rig::updateFromEyeParameters(const EyeParameters& params) {
updateEyeJoint(params.leftEyeJointIndex, params.modelTranslation, params.modelRotation, params.eyeLookAt, params.eyeSaccade); updateEyeJoint(params.leftEyeJointIndex, params.modelTranslation, params.modelRotation, params.eyeLookAt, params.eyeSaccade);
updateEyeJoint(params.rightEyeJointIndex, params.modelTranslation, params.modelRotation, params.eyeLookAt, params.eyeSaccade); updateEyeJoint(params.rightEyeJointIndex, params.modelTranslation, params.modelRotation, params.eyeLookAt, params.eyeSaccade);

View file

@ -172,36 +172,6 @@ public:
// Regardless of who started the animations or how many, update the joints. // Regardless of who started the animations or how many, update the joints.
void updateAnimations(float deltaTime, const glm::mat4& rootTransform, const glm::mat4& rigToWorldTransform); void updateAnimations(float deltaTime, const glm::mat4& rootTransform, const glm::mat4& rigToWorldTransform);
// legacy
void inverseKinematics(int endIndex, glm::vec3 targetPosition, const glm::quat& targetRotation, float priority,
const QVector<int>& freeLineage, glm::mat4 rootTransform);
// legacy
bool restoreJointPosition(int jointIndex, float fraction, float priority, const QVector<int>& freeLineage);
// legacy
float getLimbLength(int jointIndex, const QVector<int>& freeLineage,
const glm::vec3 scale, const QVector<FBXJoint>& fbxJoints) const;
// legacy
glm::quat setJointRotationInBindFrame(int jointIndex, const glm::quat& rotation, float priority);
// legacy
glm::vec3 getJointDefaultTranslationInConstrainedFrame(int jointIndex);
// legacy
glm::quat setJointRotationInConstrainedFrame(int jointIndex, glm::quat targetRotation,
float priority, float mix = 1.0f);
// legacy
bool getJointRotationInConstrainedFrame(int jointIndex, glm::quat& rotOut) const;
// legacy
glm::quat getJointDefaultRotationInParentFrame(int jointIndex);
// legacy
void clearJointStatePriorities();
void updateFromControllerParameters(const ControllerParameters& params, float dt); void updateFromControllerParameters(const ControllerParameters& params, float dt);
void updateFromEyeParameters(const EyeParameters& params); void updateFromEyeParameters(const EyeParameters& params);
@ -345,7 +315,7 @@ protected:
float firstFrame; float firstFrame;
float lastFrame; float lastFrame;
}; };
struct RoleAnimState { struct RoleAnimState {
RoleAnimState() {} RoleAnimState() {}
RoleAnimState(const QString& roleId, const QString& urlIn, float fpsIn, bool loopIn, float firstFrameIn, float lastFrameIn) : RoleAnimState(const QString& roleId, const QString& urlIn, float fpsIn, bool loopIn, float firstFrameIn, float lastFrameIn) :

View file

@ -1,7 +1,7 @@
set(TARGET_NAME avatars-renderer) set(TARGET_NAME avatars-renderer)
AUTOSCRIBE_SHADER_LIB(gpu model render render-utils) AUTOSCRIBE_SHADER_LIB(gpu graphics render render-utils)
setup_hifi_library(Widgets Network Script) setup_hifi_library(Widgets Network Script)
link_hifi_libraries(shared gpu model animation model-networking script-engine render render-utils image trackers entities-renderer) link_hifi_libraries(shared gpu graphics animation model-networking script-engine render render-utils image trackers entities-renderer)
include_hifi_library_headers(avatars) include_hifi_library_headers(avatars)
include_hifi_library_headers(networking) include_hifi_library_headers(networking)
include_hifi_library_headers(fbx) include_hifi_library_headers(fbx)

View file

@ -32,6 +32,8 @@
#include <shared/Camera.h> #include <shared/Camera.h>
#include <SoftAttachmentModel.h> #include <SoftAttachmentModel.h>
#include <render/TransitionStage.h> #include <render/TransitionStage.h>
#include "ModelEntityItem.h"
#include "RenderableModelEntityItem.h"
#include "Logging.h" #include "Logging.h"
@ -347,6 +349,65 @@ void Avatar::updateAvatarEntities() {
setAvatarEntityDataChanged(false); setAvatarEntityDataChanged(false);
} }
void Avatar::relayJointDataToChildren() {
forEachChild([&](SpatiallyNestablePointer child) {
if (child->getNestableType() == NestableType::Entity) {
auto modelEntity = std::dynamic_pointer_cast<RenderableModelEntityItem>(child);
if (modelEntity) {
if (modelEntity->getRelayParentJoints()) {
if (!modelEntity->getJointMapCompleted() || _reconstructSoftEntitiesJointMap) {
QStringList modelJointNames = modelEntity->getJointNames();
int numJoints = modelJointNames.count();
std::vector<int> map;
map.reserve(numJoints);
for (int jointIndex = 0; jointIndex < numJoints; jointIndex++) {
QString jointName = modelJointNames.at(jointIndex);
int avatarJointIndex = getJointIndex(jointName);
glm::quat jointRotation;
glm::vec3 jointTranslation;
if (avatarJointIndex < 0) {
jointRotation = modelEntity->getAbsoluteJointRotationInObjectFrame(jointIndex);
jointTranslation = modelEntity->getAbsoluteJointTranslationInObjectFrame(jointIndex);
map.push_back(-1);
} else {
int jointIndex = getJointIndex(jointName);
jointRotation = getJointRotation(jointIndex);
jointTranslation = getJointTranslation(jointIndex);
map.push_back(avatarJointIndex);
}
modelEntity->setLocalJointRotation(jointIndex, jointRotation);
modelEntity->setLocalJointTranslation(jointIndex, jointTranslation);
}
modelEntity->setJointMap(map);
} else {
QStringList modelJointNames = modelEntity->getJointNames();
int numJoints = modelJointNames.count();
for (int jointIndex = 0; jointIndex < numJoints; jointIndex++) {
int avatarJointIndex = modelEntity->avatarJointIndex(jointIndex);
glm::quat jointRotation;
glm::vec3 jointTranslation;
if (avatarJointIndex >=0) {
jointRotation = getJointRotation(avatarJointIndex);
jointTranslation = getJointTranslation(avatarJointIndex);
} else {
jointRotation = modelEntity->getAbsoluteJointRotationInObjectFrame(jointIndex);
jointTranslation = modelEntity->getAbsoluteJointTranslationInObjectFrame(jointIndex);
}
modelEntity->setLocalJointRotation(jointIndex, jointRotation);
modelEntity->setLocalJointTranslation(jointIndex, jointTranslation);
}
}
Transform avatarTransform = _skeletonModel->getTransform();
avatarTransform.setScale(_skeletonModel->getScale());
modelEntity->setOverrideTransform(avatarTransform, _skeletonModel->getOffset());
modelEntity->simulateRelayedJoints();
}
}
}
});
_reconstructSoftEntitiesJointMap = false;
}
void Avatar::simulate(float deltaTime, bool inView) { void Avatar::simulate(float deltaTime, bool inView) {
PROFILE_RANGE(simulation, "simulate"); PROFILE_RANGE(simulation, "simulate");
@ -379,6 +440,7 @@ void Avatar::simulate(float deltaTime, bool inView) {
} }
head->setScale(getModelScale()); head->setScale(getModelScale());
head->simulate(deltaTime); head->simulate(deltaTime);
relayJointDataToChildren();
} else { } else {
// a non-full update is still required so that the position, rotation, scale and bounds of the skeletonModel are updated. // a non-full update is still required so that the position, rotation, scale and bounds of the skeletonModel are updated.
_skeletonModel->simulate(deltaTime, false); _skeletonModel->simulate(deltaTime, false);
@ -1197,6 +1259,7 @@ void Avatar::setModelURLFinished(bool success) {
invalidateJointIndicesCache(); invalidateJointIndicesCache();
_isAnimatingScale = true; _isAnimatingScale = true;
_reconstructSoftEntitiesJointMap = true;
if (!success && _skeletonModelURL != AvatarData::defaultFullAvatarModelUrl()) { if (!success && _skeletonModelURL != AvatarData::defaultFullAvatarModelUrl()) {
const int MAX_SKELETON_DOWNLOAD_ATTEMPTS = 4; // NOTE: we don't want to be as generous as ResourceCache is, we only want 4 attempts const int MAX_SKELETON_DOWNLOAD_ATTEMPTS = 4; // NOTE: we don't want to be as generous as ResourceCache is, we only want 4 attempts

View file

@ -330,6 +330,7 @@ protected:
// protected methods... // protected methods...
bool isLookingAtMe(AvatarSharedPointer avatar) const; bool isLookingAtMe(AvatarSharedPointer avatar) const;
void relayJointDataToChildren();
void fade(render::Transaction& transaction, render::Transition::Type type); void fade(render::Transaction& transaction, render::Transition::Type type);
@ -382,6 +383,7 @@ protected:
bool _isAnimatingScale { false }; bool _isAnimatingScale { false };
bool _mustFadeIn { false }; bool _mustFadeIn { false };
bool _isFading { false }; bool _isFading { false };
bool _reconstructSoftEntitiesJointMap { false };
float _modelScale { 1.0f }; float _modelScale { 1.0f };
static int _jointConesID; static int _jointConesID;

View file

@ -237,30 +237,14 @@ bool SkeletonModel::getRightHandPosition(glm::vec3& position) const {
return getJointPositionInWorldFrame(getRightHandJointIndex(), position); return getJointPositionInWorldFrame(getRightHandJointIndex(), position);
} }
bool SkeletonModel::restoreLeftHandPosition(float fraction, float priority) {
return restoreJointPosition(getLeftHandJointIndex(), fraction, priority);
}
bool SkeletonModel::getLeftShoulderPosition(glm::vec3& position) const { bool SkeletonModel::getLeftShoulderPosition(glm::vec3& position) const {
return getJointPositionInWorldFrame(getLastFreeJointIndex(getLeftHandJointIndex()), position); return getJointPositionInWorldFrame(getLastFreeJointIndex(getLeftHandJointIndex()), position);
} }
float SkeletonModel::getLeftArmLength() const {
return getLimbLength(getLeftHandJointIndex());
}
bool SkeletonModel::restoreRightHandPosition(float fraction, float priority) {
return restoreJointPosition(getRightHandJointIndex(), fraction, priority);
}
bool SkeletonModel::getRightShoulderPosition(glm::vec3& position) const { bool SkeletonModel::getRightShoulderPosition(glm::vec3& position) const {
return getJointPositionInWorldFrame(getLastFreeJointIndex(getRightHandJointIndex()), position); return getJointPositionInWorldFrame(getLastFreeJointIndex(getRightHandJointIndex()), position);
} }
float SkeletonModel::getRightArmLength() const {
return getLimbLength(getRightHandJointIndex());
}
bool SkeletonModel::getHeadPosition(glm::vec3& headPosition) const { bool SkeletonModel::getHeadPosition(glm::vec3& headPosition) const {
return isActive() && getJointPositionInWorldFrame(getFBXGeometry().headJointIndex, headPosition); return isActive() && getJointPositionInWorldFrame(getFBXGeometry().headJointIndex, headPosition);
} }

View file

@ -57,11 +57,6 @@ public:
/// \return true whether or not the position was found /// \return true whether or not the position was found
bool getRightHandPosition(glm::vec3& position) const; bool getRightHandPosition(glm::vec3& position) const;
/// Restores some fraction of the default position of the left hand.
/// \param fraction the fraction of the default position to restore
/// \return whether or not the left hand joint was found
bool restoreLeftHandPosition(float fraction = 1.0f, float priority = 1.0f);
/// Gets the position of the left shoulder. /// Gets the position of the left shoulder.
/// \return whether or not the left shoulder joint was found /// \return whether or not the left shoulder joint was found
bool getLeftShoulderPosition(glm::vec3& position) const; bool getLeftShoulderPosition(glm::vec3& position) const;
@ -69,18 +64,10 @@ public:
/// Returns the extended length from the left hand to its last free ancestor. /// Returns the extended length from the left hand to its last free ancestor.
float getLeftArmLength() const; float getLeftArmLength() const;
/// Restores some fraction of the default position of the right hand.
/// \param fraction the fraction of the default position to restore
/// \return whether or not the right hand joint was found
bool restoreRightHandPosition(float fraction = 1.0f, float priority = 1.0f);
/// Gets the position of the right shoulder. /// Gets the position of the right shoulder.
/// \return whether or not the right shoulder joint was found /// \return whether or not the right shoulder joint was found
bool getRightShoulderPosition(glm::vec3& position) const; bool getRightShoulderPosition(glm::vec3& position) const;
/// Returns the extended length from the right hand to its first free ancestor.
float getRightArmLength() const;
/// Returns the position of the head joint. /// Returns the position of the head joint.
/// \return whether or not the head was found /// \return whether or not the head was found
bool getHeadPosition(glm::vec3& headPosition) const; bool getHeadPosition(glm::vec3& headPosition) const;

View file

@ -530,9 +530,13 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
destinationBuffer += numValidityBytes; // Move pointer past the validity bytes destinationBuffer += numValidityBytes; // Move pointer past the validity bytes
// sentJointDataOut and lastSentJointData might be the same vector
// build sentJointDataOut locally and then swap it at the end.
QVector<JointData> localSentJointDataOut;
if (sentJointDataOut) { if (sentJointDataOut) {
sentJointDataOut->resize(_jointData.size()); // Make sure the destination is resized before using it localSentJointDataOut.resize(numJoints); // Make sure the destination is resized before using it
} }
float minRotationDOT = !distanceAdjust ? AVATAR_MIN_ROTATION_DOT : getDistanceBasedMinRotationDOT(viewerPosition); float minRotationDOT = !distanceAdjust ? AVATAR_MIN_ROTATION_DOT : getDistanceBasedMinRotationDOT(viewerPosition);
for (int i = 0; i < _jointData.size(); i++) { for (int i = 0; i < _jointData.size(); i++) {
@ -552,8 +556,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
destinationBuffer += packOrientationQuatToSixBytes(destinationBuffer, data.rotation); destinationBuffer += packOrientationQuatToSixBytes(destinationBuffer, data.rotation);
if (sentJointDataOut) { if (sentJointDataOut) {
auto jointDataOut = *sentJointDataOut; localSentJointDataOut[i].rotation = data.rotation;
jointDataOut[i].rotation = data.rotation;
} }
} }
@ -602,8 +605,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
packFloatVec3ToSignedTwoByteFixed(destinationBuffer, data.translation, TRANSLATION_COMPRESSION_RADIX); packFloatVec3ToSignedTwoByteFixed(destinationBuffer, data.translation, TRANSLATION_COMPRESSION_RADIX);
if (sentJointDataOut) { if (sentJointDataOut) {
auto jointDataOut = *sentJointDataOut; localSentJointDataOut[i].translation = data.translation;
jointDataOut[i].translation = data.translation;
} }
} }
@ -646,6 +648,11 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
if (outboundDataRateOut) { if (outboundDataRateOut) {
outboundDataRateOut->jointDataRate.increment(numBytes); outboundDataRateOut->jointDataRate.increment(numBytes);
} }
if (sentJointDataOut) {
// Push new sent joint data to sentJointDataOut
sentJointDataOut->swap(localSentJointDataOut);
}
} }
int avatarDataSize = destinationBuffer - startPosition; int avatarDataSize = destinationBuffer - startPosition;

View file

@ -358,7 +358,7 @@ class AvatarData : public QObject, public SpatiallyNestable {
Q_PROPERTY(QString displayName READ getDisplayName WRITE setDisplayName NOTIFY displayNameChanged) Q_PROPERTY(QString displayName READ getDisplayName WRITE setDisplayName NOTIFY displayNameChanged)
// sessionDisplayName is sanitized, defaulted version displayName that is defined by the AvatarMixer rather than by Interface clients. // sessionDisplayName is sanitized, defaulted version displayName that is defined by the AvatarMixer rather than by Interface clients.
// The result is unique among all avatars present at the time. // The result is unique among all avatars present at the time.
Q_PROPERTY(QString sessionDisplayName READ getSessionDisplayName WRITE setSessionDisplayName) Q_PROPERTY(QString sessionDisplayName READ getSessionDisplayName WRITE setSessionDisplayName NOTIFY sessionDisplayNameChanged)
Q_PROPERTY(bool lookAtSnappingEnabled MEMBER _lookAtSnappingEnabled NOTIFY lookAtSnappingChanged) Q_PROPERTY(bool lookAtSnappingEnabled MEMBER _lookAtSnappingEnabled NOTIFY lookAtSnappingChanged)
Q_PROPERTY(QString skeletonModelURL READ getSkeletonModelURLFromScript WRITE setSkeletonModelURLFromScript) Q_PROPERTY(QString skeletonModelURL READ getSkeletonModelURLFromScript WRITE setSkeletonModelURLFromScript)
Q_PROPERTY(QVector<AttachmentData> attachmentData READ getAttachmentData WRITE setAttachmentData) Q_PROPERTY(QVector<AttachmentData> attachmentData READ getAttachmentData WRITE setAttachmentData)
@ -685,6 +685,7 @@ public:
signals: signals:
void displayNameChanged(); void displayNameChanged();
void sessionDisplayNameChanged();
void lookAtSnappingChanged(bool enabled); void lookAtSnappingChanged(bool enabled);
void sessionUUIDChanged(); void sessionUUIDChanged();

View file

@ -15,6 +15,7 @@ ScriptAvatarData::ScriptAvatarData(AvatarSharedPointer avatarData) :
_avatarData(avatarData) _avatarData(avatarData)
{ {
QObject::connect(avatarData.get(), &AvatarData::displayNameChanged, this, &ScriptAvatarData::displayNameChanged); QObject::connect(avatarData.get(), &AvatarData::displayNameChanged, this, &ScriptAvatarData::displayNameChanged);
QObject::connect(avatarData.get(), &AvatarData::sessionDisplayNameChanged, this, &ScriptAvatarData::sessionDisplayNameChanged);
QObject::connect(avatarData.get(), &AvatarData::lookAtSnappingChanged, this, &ScriptAvatarData::lookAtSnappingChanged); QObject::connect(avatarData.get(), &AvatarData::lookAtSnappingChanged, this, &ScriptAvatarData::lookAtSnappingChanged);
} }

View file

@ -44,7 +44,7 @@ class ScriptAvatarData : public QObject {
// //
Q_PROPERTY(QUuid sessionUUID READ getSessionUUID) Q_PROPERTY(QUuid sessionUUID READ getSessionUUID)
Q_PROPERTY(QString displayName READ getDisplayName NOTIFY displayNameChanged) Q_PROPERTY(QString displayName READ getDisplayName NOTIFY displayNameChanged)
Q_PROPERTY(QString sessionDisplayName READ getSessionDisplayName) Q_PROPERTY(QString sessionDisplayName READ getSessionDisplayName NOTIFY sessionDisplayNameChanged)
Q_PROPERTY(bool isReplicated READ getIsReplicated) Q_PROPERTY(bool isReplicated READ getIsReplicated)
Q_PROPERTY(bool lookAtSnappingEnabled READ getLookAtSnappingEnabled NOTIFY lookAtSnappingChanged) Q_PROPERTY(bool lookAtSnappingEnabled READ getLookAtSnappingEnabled NOTIFY lookAtSnappingChanged)
@ -131,6 +131,7 @@ public:
signals: signals:
void displayNameChanged(); void displayNameChanged();
void sessionDisplayNameChanged();
void lookAtSnappingChanged(bool enabled); void lookAtSnappingChanged(bool enabled);
public slots: public slots:

View file

@ -1,7 +1,7 @@
set(TARGET_NAME baking) set(TARGET_NAME baking)
setup_hifi_library(Concurrent) setup_hifi_library(Concurrent)
link_hifi_libraries(shared model networking ktx image fbx) link_hifi_libraries(shared graphics networking ktx image fbx)
include_hifi_library_headers(gpu) include_hifi_library_headers(gpu)
add_dependency_external_projects(draco) add_dependency_external_projects(draco)

View file

@ -5,7 +5,7 @@ link_hifi_libraries(shared plugins ui-plugins gl ui render-utils ${PLATFORM_GL_B
include_hifi_library_headers(gpu) include_hifi_library_headers(gpu)
include_hifi_library_headers(model-networking) include_hifi_library_headers(model-networking)
include_hifi_library_headers(networking) include_hifi_library_headers(networking)
include_hifi_library_headers(model) include_hifi_library_headers(graphics)
include_hifi_library_headers(fbx) include_hifi_library_headers(fbx)
include_hifi_library_headers(image) include_hifi_library_headers(image)
include_hifi_library_headers(ktx) include_hifi_library_headers(ktx)

View file

@ -1,7 +1,7 @@
set(TARGET_NAME entities-renderer) set(TARGET_NAME entities-renderer)
AUTOSCRIBE_SHADER_LIB(gpu model procedural render render-utils) AUTOSCRIBE_SHADER_LIB(gpu graphics procedural render render-utils)
setup_hifi_library(Widgets Network Script) setup_hifi_library(Widgets Network Script)
link_hifi_libraries(shared gpu procedural model model-networking script-engine render render-utils image ui pointers) link_hifi_libraries(shared gpu procedural graphics model-networking script-engine render render-utils image ui pointers)
include_hifi_library_headers(networking) include_hifi_library_headers(networking)
include_hifi_library_headers(gl) include_hifi_library_headers(gl)
include_hifi_library_headers(ktx) include_hifi_library_headers(ktx)

View file

@ -52,9 +52,9 @@ void LightEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint
float exponent = entity->getExponent(); float exponent = entity->getExponent();
float cutoff = glm::radians(entity->getCutoff()); float cutoff = glm::radians(entity->getCutoff());
if (!entity->getIsSpotlight()) { if (!entity->getIsSpotlight()) {
light->setType(model::Light::POINT); light->setType(graphics::Light::POINT);
} else { } else {
light->setType(model::Light::SPOT); light->setType(graphics::Light::SPOT);
light->setSpotAngle(cutoff); light->setSpotAngle(cutoff);
light->setSpotExponent(exponent); light->setSpotExponent(exponent);

View file

@ -558,10 +558,10 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
if (type == SHAPE_TYPE_STATIC_MESH) { if (type == SHAPE_TYPE_STATIC_MESH) {
// copy into triangleIndices // copy into triangleIndices
triangleIndices.reserve((int32_t)((gpu::Size)(triangleIndices.size()) + indices.getNumElements())); triangleIndices.reserve((int32_t)((gpu::Size)(triangleIndices.size()) + indices.getNumElements()));
gpu::BufferView::Iterator<const model::Mesh::Part> partItr = parts.cbegin<const model::Mesh::Part>(); gpu::BufferView::Iterator<const graphics::Mesh::Part> partItr = parts.cbegin<const graphics::Mesh::Part>();
while (partItr != parts.cend<const model::Mesh::Part>()) { while (partItr != parts.cend<const graphics::Mesh::Part>()) {
auto numIndices = partItr->_numIndices; auto numIndices = partItr->_numIndices;
if (partItr->_topology == model::Mesh::TRIANGLES) { if (partItr->_topology == graphics::Mesh::TRIANGLES) {
// TODO: assert rather than workaround after we start sanitizing FBXMesh higher up // TODO: assert rather than workaround after we start sanitizing FBXMesh higher up
//assert(numIndices % TRIANGLE_STRIDE == 0); //assert(numIndices % TRIANGLE_STRIDE == 0);
numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader
@ -572,7 +572,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
triangleIndices.push_back(*indexItr + meshIndexOffset); triangleIndices.push_back(*indexItr + meshIndexOffset);
++indexItr; ++indexItr;
} }
} else if (partItr->_topology == model::Mesh::TRIANGLE_STRIP) { } else if (partItr->_topology == graphics::Mesh::TRIANGLE_STRIP) {
// TODO: resurrect assert after we start sanitizing FBXMesh higher up // TODO: resurrect assert after we start sanitizing FBXMesh higher up
//assert(numIndices > 2); //assert(numIndices > 2);
@ -593,7 +593,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
// the rest use previous and next index // the rest use previous and next index
uint32_t triangleCount = 1; uint32_t triangleCount = 1;
while (indexItr != indexEnd) { while (indexItr != indexEnd) {
if ((*indexItr) != model::Mesh::PRIMITIVE_RESTART_INDEX) { if ((*indexItr) != graphics::Mesh::PRIMITIVE_RESTART_INDEX) {
if (triangleCount % 2 == 0) { if (triangleCount % 2 == 0) {
// even triangles use first two indices in order // even triangles use first two indices in order
triangleIndices.push_back(*(indexItr - 2) + meshIndexOffset); triangleIndices.push_back(*(indexItr - 2) + meshIndexOffset);
@ -613,12 +613,12 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
} }
} else if (type == SHAPE_TYPE_SIMPLE_COMPOUND) { } else if (type == SHAPE_TYPE_SIMPLE_COMPOUND) {
// for each mesh copy unique part indices, separated by special bogus (flag) index values // for each mesh copy unique part indices, separated by special bogus (flag) index values
gpu::BufferView::Iterator<const model::Mesh::Part> partItr = parts.cbegin<const model::Mesh::Part>(); gpu::BufferView::Iterator<const graphics::Mesh::Part> partItr = parts.cbegin<const graphics::Mesh::Part>();
while (partItr != parts.cend<const model::Mesh::Part>()) { while (partItr != parts.cend<const graphics::Mesh::Part>()) {
// collect unique list of indices for this part // collect unique list of indices for this part
std::set<int32_t> uniqueIndices; std::set<int32_t> uniqueIndices;
auto numIndices = partItr->_numIndices; auto numIndices = partItr->_numIndices;
if (partItr->_topology == model::Mesh::TRIANGLES) { if (partItr->_topology == graphics::Mesh::TRIANGLES) {
// TODO: assert rather than workaround after we start sanitizing FBXMesh higher up // TODO: assert rather than workaround after we start sanitizing FBXMesh higher up
//assert(numIndices% TRIANGLE_STRIDE == 0); //assert(numIndices% TRIANGLE_STRIDE == 0);
numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader numIndices -= numIndices % TRIANGLE_STRIDE; // WORKAROUND lack of sanity checking in FBXReader
@ -629,7 +629,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
uniqueIndices.insert(*indexItr); uniqueIndices.insert(*indexItr);
++indexItr; ++indexItr;
} }
} else if (partItr->_topology == model::Mesh::TRIANGLE_STRIP) { } else if (partItr->_topology == graphics::Mesh::TRIANGLE_STRIP) {
// TODO: resurrect assert after we start sanitizing FBXMesh higher up // TODO: resurrect assert after we start sanitizing FBXMesh higher up
//assert(numIndices > TRIANGLE_STRIDE - 1); //assert(numIndices > TRIANGLE_STRIDE - 1);
@ -644,7 +644,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
// the rest use previous and next index // the rest use previous and next index
uint32_t triangleCount = 1; uint32_t triangleCount = 1;
while (indexItr != indexEnd) { while (indexItr != indexEnd) {
if ((*indexItr) != model::Mesh::PRIMITIVE_RESTART_INDEX) { if ((*indexItr) != graphics::Mesh::PRIMITIVE_RESTART_INDEX) {
if (triangleCount % 2 == 0) { if (triangleCount % 2 == 0) {
// EVEN triangles use first two indices in order // EVEN triangles use first two indices in order
uniqueIndices.insert(*(indexItr - 2)); uniqueIndices.insert(*(indexItr - 2));
@ -708,6 +708,26 @@ void RenderableModelEntityItem::setCollisionShape(const btCollisionShape* shape)
} }
} }
void RenderableModelEntityItem::setJointMap(std::vector<int> jointMap) {
if (jointMap.size() > 0) {
_jointMap = jointMap;
_jointMapCompleted = true;
return;
}
_jointMapCompleted = false;
};
int RenderableModelEntityItem::avatarJointIndex(int modelJointIndex) {
int result = -1;
int mapSize = (int) _jointMap.size();
if (modelJointIndex >=0 && modelJointIndex < mapSize) {
result = _jointMap[modelJointIndex];
}
return result;
}
bool RenderableModelEntityItem::contains(const glm::vec3& point) const { bool RenderableModelEntityItem::contains(const glm::vec3& point) const {
auto model = getModel(); auto model = getModel();
if (EntityItem::contains(point) && model && _compoundShapeResource && _compoundShapeResource->isLoaded()) { if (EntityItem::contains(point) && model && _compoundShapeResource && _compoundShapeResource->isLoaded()) {
@ -813,6 +833,10 @@ bool RenderableModelEntityItem::setAbsoluteJointTranslationInObjectFrame(int ind
return setLocalJointTranslation(index, jointRelativePose.trans()); return setLocalJointTranslation(index, jointRelativePose.trans());
} }
bool RenderableModelEntityItem::getJointMapCompleted() {
return _jointMapCompleted;
}
glm::quat RenderableModelEntityItem::getLocalJointRotation(int index) const { glm::quat RenderableModelEntityItem::getLocalJointRotation(int index) const {
auto model = getModel(); auto model = getModel();
if (model) { if (model) {
@ -835,6 +859,13 @@ glm::vec3 RenderableModelEntityItem::getLocalJointTranslation(int index) const {
return glm::vec3(); return glm::vec3();
} }
void RenderableModelEntityItem::setOverrideTransform(const Transform& transform, const glm::vec3& offset) {
auto model = getModel();
if (model) {
model->overrideModelTransformAndOffset(transform, offset);
}
}
bool RenderableModelEntityItem::setLocalJointRotation(int index, const glm::quat& rotation) { bool RenderableModelEntityItem::setLocalJointRotation(int index, const glm::quat& rotation) {
autoResizeJointArrays(); autoResizeJointArrays();
bool result = false; bool result = false;
@ -929,6 +960,26 @@ bool RenderableModelEntityItem::getMeshes(MeshProxyList& result) {
return !result.isEmpty(); return !result.isEmpty();
} }
void RenderableModelEntityItem::simulateRelayedJoints() {
ModelPointer model = getModel();
if (model && model->isLoaded()) {
copyAnimationJointDataToModel();
model->simulate(0.0f);
model->updateRenderItems();
}
}
void RenderableModelEntityItem::stopModelOverrideIfNoParent() {
auto model = getModel();
if (model) {
bool overriding = model->isOverridingModelTransformAndOffset();
QUuid parentID = getParentID();
if (overriding && (!_relayParentJoints || parentID.isNull())) {
model->stopTransformAndOffsetOverride();
}
}
}
void RenderableModelEntityItem::copyAnimationJointDataToModel() { void RenderableModelEntityItem::copyAnimationJointDataToModel() {
auto model = getModel(); auto model = getModel();
if (!model || !model->isLoaded()) { if (!model || !model->isLoaded()) {
@ -1280,6 +1331,7 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
} }
entity->updateModelBounds(); entity->updateModelBounds();
entity->stopModelOverrideIfNoParent();
if (model->isVisible() != _visible) { if (model->isVisible() != _visible) {
// FIXME: this seems like it could be optimized if we tracked our last known visible state in // FIXME: this seems like it could be optimized if we tracked our last known visible state in
@ -1295,7 +1347,7 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
ShapeType type = entity->getShapeType(); ShapeType type = entity->getShapeType();
if (DependencyManager::get<EntityTreeRenderer>()->shouldRenderDebugHulls() && type != SHAPE_TYPE_STATIC_MESH && type != SHAPE_TYPE_NONE) { if (DependencyManager::get<EntityTreeRenderer>()->shouldRenderDebugHulls() && type != SHAPE_TYPE_STATIC_MESH && type != SHAPE_TYPE_NONE) {
// NOTE: it is OK if _collisionMeshKey is nullptr // NOTE: it is OK if _collisionMeshKey is nullptr
model::MeshPointer mesh = collisionMeshCache.getMesh(_collisionMeshKey); graphics::MeshPointer mesh = collisionMeshCache.getMesh(_collisionMeshKey);
// NOTE: the model will render the collisionGeometry if it has one // NOTE: the model will render the collisionGeometry if it has one
_model->setCollisionMesh(mesh); _model->setCollisionMesh(mesh);
} else { } else {
@ -1304,7 +1356,7 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
collisionMeshCache.releaseMesh(_collisionMeshKey); collisionMeshCache.releaseMesh(_collisionMeshKey);
} }
// clear model's collision geometry // clear model's collision geometry
model::MeshPointer mesh = nullptr; graphics::MeshPointer mesh = nullptr;
_model->setCollisionMesh(mesh); _model->setCollisionMesh(mesh);
} }
} }

View file

@ -81,8 +81,14 @@ public:
void setCollisionShape(const btCollisionShape* shape) override; void setCollisionShape(const btCollisionShape* shape) override;
virtual bool contains(const glm::vec3& point) const override; virtual bool contains(const glm::vec3& point) const override;
void stopModelOverrideIfNoParent();
virtual bool shouldBePhysical() const override; virtual bool shouldBePhysical() const override;
void simulateRelayedJoints();
bool getJointMapCompleted();
void setJointMap(std::vector<int> jointMap);
int avatarJointIndex(int modelJointIndex);
void setOverrideTransform(const Transform& transform, const glm::vec3& offset);
// these are in the frame of this object (model space) // these are in the frame of this object (model space)
virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override; virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override;
@ -90,7 +96,6 @@ public:
virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) override; virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) override;
virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) override; virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) override;
virtual glm::quat getLocalJointRotation(int index) const override; virtual glm::quat getLocalJointRotation(int index) const override;
virtual glm::vec3 getLocalJointTranslation(int index) const override; virtual glm::vec3 getLocalJointTranslation(int index) const override;
virtual bool setLocalJointRotation(int index, const glm::quat& rotation) override; virtual bool setLocalJointRotation(int index, const glm::quat& rotation) override;
@ -119,7 +124,9 @@ private:
void getCollisionGeometryResource(); void getCollisionGeometryResource();
GeometryResource::Pointer _compoundShapeResource; GeometryResource::Pointer _compoundShapeResource;
bool _jointMapCompleted { false };
bool _originalTexturesRead { false }; bool _originalTexturesRead { false };
std::vector<int> _jointMap;
QVariantMap _originalTextures; QVariantMap _originalTextures;
bool _dimensionsInitialized { true }; bool _dimensionsInitialized { true };
bool _needsJointSimulation { false }; bool _needsJointSimulation { false };

View file

@ -65,7 +65,7 @@
#pragma warning(pop) #pragma warning(pop)
#endif #endif
#include "model/Geometry.h" #include "graphics/Geometry.h"
#include "StencilMaskPass.h" #include "StencilMaskPass.h"
@ -1060,7 +1060,7 @@ void RenderablePolyVoxEntityItem::recomputeMesh() {
auto entity = std::static_pointer_cast<RenderablePolyVoxEntityItem>(getThisPointer()); auto entity = std::static_pointer_cast<RenderablePolyVoxEntityItem>(getThisPointer());
QtConcurrent::run([entity, voxelSurfaceStyle] { QtConcurrent::run([entity, voxelSurfaceStyle] {
model::MeshPointer mesh(new model::Mesh()); graphics::MeshPointer mesh(new graphics::Mesh());
// A mesh object to hold the result of surface extraction // A mesh object to hold the result of surface extraction
PolyVox::SurfaceMesh<PolyVox::PositionMaterialNormal> polyVoxMesh; PolyVox::SurfaceMesh<PolyVox::PositionMaterialNormal> polyVoxMesh;
@ -1122,18 +1122,18 @@ void RenderablePolyVoxEntityItem::recomputeMesh() {
sizeof(PolyVox::PositionMaterialNormal), sizeof(PolyVox::PositionMaterialNormal),
gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ))); gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)));
std::vector<model::Mesh::Part> parts; std::vector<graphics::Mesh::Part> parts;
parts.emplace_back(model::Mesh::Part((model::Index)0, // startIndex parts.emplace_back(graphics::Mesh::Part((graphics::Index)0, // startIndex
(model::Index)vecIndices.size(), // numIndices (graphics::Index)vecIndices.size(), // numIndices
(model::Index)0, // baseVertex (graphics::Index)0, // baseVertex
model::Mesh::TRIANGLES)); // topology graphics::Mesh::TRIANGLES)); // topology
mesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(model::Mesh::Part), mesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(graphics::Mesh::Part),
(gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL)); (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL));
entity->setMesh(mesh); entity->setMesh(mesh);
}); });
} }
void RenderablePolyVoxEntityItem::setMesh(model::MeshPointer mesh) { void RenderablePolyVoxEntityItem::setMesh(graphics::MeshPointer mesh) {
// this catches the payload from recomputeMesh // this catches the payload from recomputeMesh
bool neighborsNeedUpdate; bool neighborsNeedUpdate;
withWriteLock([&] { withWriteLock([&] {
@ -1164,7 +1164,7 @@ void RenderablePolyVoxEntityItem::computeShapeInfoWorker() {
PolyVoxSurfaceStyle voxelSurfaceStyle; PolyVoxSurfaceStyle voxelSurfaceStyle;
glm::vec3 voxelVolumeSize; glm::vec3 voxelVolumeSize;
model::MeshPointer mesh; graphics::MeshPointer mesh;
withReadLock([&] { withReadLock([&] {
voxelSurfaceStyle = _voxelSurfaceStyle; voxelSurfaceStyle = _voxelSurfaceStyle;
@ -1582,7 +1582,7 @@ void PolyVoxEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& s
void PolyVoxEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { void PolyVoxEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
_lastVoxelToWorldMatrix = entity->voxelToWorldMatrix(); _lastVoxelToWorldMatrix = entity->voxelToWorldMatrix();
model::MeshPointer newMesh; graphics::MeshPointer newMesh;
entity->withReadLock([&] { entity->withReadLock([&] {
newMesh = entity->_mesh; newMesh = entity->_mesh;
}); });

View file

@ -21,8 +21,8 @@
#include <gpu/Forward.h> #include <gpu/Forward.h>
#include <gpu/Context.h> #include <gpu/Context.h>
#include <model/Forward.h> #include <graphics/Forward.h>
#include <model/Geometry.h> #include <graphics/Geometry.h>
#include <TextureCache.h> #include <TextureCache.h>
#include <PolyVoxEntityItem.h> #include <PolyVoxEntityItem.h>
@ -104,7 +104,7 @@ public:
void forEachVoxelValue(const ivec3& voxelSize, std::function<void(const ivec3&, uint8_t)> thunk); void forEachVoxelValue(const ivec3& voxelSize, std::function<void(const ivec3&, uint8_t)> thunk);
QByteArray volDataToArray(quint16 voxelXSize, quint16 voxelYSize, quint16 voxelZSize) const; QByteArray volDataToArray(quint16 voxelXSize, quint16 voxelYSize, quint16 voxelZSize) const;
void setMesh(model::MeshPointer mesh); void setMesh(graphics::MeshPointer mesh);
void setCollisionPoints(ShapeInfo::PointCollection points, AABox box); void setCollisionPoints(ShapeInfo::PointCollection points, AABox box);
PolyVox::SimpleVolume<uint8_t>* getVolData() { return _volData.get(); } PolyVox::SimpleVolume<uint8_t>* getVolData() { return _volData.get(); }
@ -134,7 +134,7 @@ private:
// may not match _voxelVolumeSize. // may not match _voxelVolumeSize.
bool _meshDirty { true }; // does collision-shape need to be recomputed? bool _meshDirty { true }; // does collision-shape need to be recomputed?
bool _meshReady{ false }; bool _meshReady{ false };
model::MeshPointer _mesh; graphics::MeshPointer _mesh;
ShapeInfo _shapeInfo; ShapeInfo _shapeInfo;
@ -178,7 +178,7 @@ private:
bool _hasTransitioned{ false }; bool _hasTransitioned{ false };
#endif #endif
model::MeshPointer _mesh; graphics::MeshPointer _mesh;
std::array<NetworkTexturePointer, 3> _xyzTextures; std::array<NetworkTexturePointer, 3> _xyzTextures;
glm::vec3 _lastVoxelVolumeSize; glm::vec3 _lastVoxelVolumeSize;
glm::mat4 _lastVoxelToWorldMatrix; glm::mat4 _lastVoxelToWorldMatrix;

View file

@ -13,7 +13,7 @@
#include <gpu/Batch.h> #include <gpu/Batch.h>
#include <model/Stage.h> #include <graphics/Stage.h>
#include <DependencyManager.h> #include <DependencyManager.h>
#include <GeometryCache.h> #include <GeometryCache.h>
@ -162,28 +162,31 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) {
} }
if (_visible) { if (_visible) {
// Finally, push the light visible in the frame // Finally, push the lights visible in the frame
//
// If component is disabled then push component off state
// else if component is enabled then push current state
// (else mode is inherit, the value from the parent zone will be used
//
if (_keyLightMode == COMPONENT_MODE_DISABLED) { if (_keyLightMode == COMPONENT_MODE_DISABLED) {
_stage->_currentFrame.pushSunLight(_stage->getSunOffLight()); _stage->_currentFrame.pushSunLight(_stage->getSunOffLight());
} else if (_keyLightMode == COMPONENT_MODE_ENABLED) { } else if (_keyLightMode == COMPONENT_MODE_ENABLED) {
_stage->_currentFrame.pushSunLight(_sunIndex); _stage->_currentFrame.pushSunLight(_sunIndex);
} }
// The background only if the mode is not inherit
if (_skyboxMode == COMPONENT_MODE_DISABLED) { if (_skyboxMode == COMPONENT_MODE_DISABLED) {
_backgroundStage->_currentFrame.pushBackground(INVALID_INDEX); _backgroundStage->_currentFrame.pushBackground(INVALID_INDEX);
} else if (_skyboxMode == COMPONENT_MODE_ENABLED) { } else if (_skyboxMode == COMPONENT_MODE_ENABLED) {
_backgroundStage->_currentFrame.pushBackground(_backgroundIndex); _backgroundStage->_currentFrame.pushBackground(_backgroundIndex);
} }
// The ambient light only if it has a valid texture to render with
if (_ambientLightMode == COMPONENT_MODE_DISABLED) { if (_ambientLightMode == COMPONENT_MODE_DISABLED) {
_stage->_currentFrame.pushAmbientLight(_stage->getAmbientOffLight()); _stage->_currentFrame.pushAmbientLight(_stage->getAmbientOffLight());
} else if (_ambientLightMode == COMPONENT_MODE_ENABLED) { } else if (_ambientLightMode == COMPONENT_MODE_ENABLED) {
_stage->_currentFrame.pushAmbientLight(_ambientIndex); _stage->_currentFrame.pushAmbientLight(_ambientIndex);
} }
// Haze only if the mode is not inherit // Haze only if the mode is not inherit, as the model deals with on/off
if (_hazeMode != COMPONENT_MODE_INHERIT) { if (_hazeMode != COMPONENT_MODE_INHERIT) {
_hazeStage->_currentFrame.pushHaze(_hazeIndex); _hazeStage->_currentFrame.pushHaze(_hazeIndex);
} }
@ -319,7 +322,7 @@ void ZoneEntityRenderer::updateKeySunFromEntity(const TypedEntityPointer& entity
setKeyLightMode((ComponentMode)entity->getKeyLightMode()); setKeyLightMode((ComponentMode)entity->getKeyLightMode());
const auto& sunLight = editSunLight(); const auto& sunLight = editSunLight();
sunLight->setType(model::Light::SUN); sunLight->setType(graphics::Light::SUN);
sunLight->setPosition(_lastPosition); sunLight->setPosition(_lastPosition);
sunLight->setOrientation(_lastRotation); sunLight->setOrientation(_lastRotation);
@ -333,7 +336,7 @@ void ZoneEntityRenderer::updateAmbientLightFromEntity(const TypedEntityPointer&
setAmbientLightMode((ComponentMode)entity->getAmbientLightMode()); setAmbientLightMode((ComponentMode)entity->getAmbientLightMode());
const auto& ambientLight = editAmbientLight(); const auto& ambientLight = editAmbientLight();
ambientLight->setType(model::Light::AMBIENT); ambientLight->setType(graphics::Light::AMBIENT);
ambientLight->setPosition(_lastPosition); ambientLight->setPosition(_lastPosition);
ambientLight->setOrientation(_lastRotation); ambientLight->setOrientation(_lastRotation);
@ -357,23 +360,23 @@ void ZoneEntityRenderer::updateHazeFromEntity(const TypedEntityPointer& entity)
haze->setHazeActive(hazeMode == COMPONENT_MODE_ENABLED); haze->setHazeActive(hazeMode == COMPONENT_MODE_ENABLED);
haze->setAltitudeBased(_hazeProperties.getHazeAltitudeEffect()); haze->setAltitudeBased(_hazeProperties.getHazeAltitudeEffect());
haze->setHazeRangeFactor(model::Haze::convertHazeRangeToHazeRangeFactor(_hazeProperties.getHazeRange())); haze->setHazeRangeFactor(graphics::Haze::convertHazeRangeToHazeRangeFactor(_hazeProperties.getHazeRange()));
xColor hazeColor = _hazeProperties.getHazeColor(); xColor hazeColor = _hazeProperties.getHazeColor();
haze->setHazeColor(glm::vec3(hazeColor.red / 255.0, hazeColor.green / 255.0, hazeColor.blue / 255.0)); haze->setHazeColor(glm::vec3(hazeColor.red / 255.0, hazeColor.green / 255.0, hazeColor.blue / 255.0));
xColor hazeGlareColor = _hazeProperties.getHazeGlareColor(); xColor hazeGlareColor = _hazeProperties.getHazeGlareColor();
haze->setHazeGlareColor(glm::vec3(hazeGlareColor.red / 255.0, hazeGlareColor.green / 255.0, hazeGlareColor.blue / 255.0)); haze->setHazeGlareColor(glm::vec3(hazeGlareColor.red / 255.0, hazeGlareColor.green / 255.0, hazeGlareColor.blue / 255.0));
haze->setHazeEnableGlare(_hazeProperties.getHazeEnableGlare()); haze->setHazeEnableGlare(_hazeProperties.getHazeEnableGlare());
haze->setHazeGlareBlend(model::Haze::convertGlareAngleToPower(_hazeProperties.getHazeGlareAngle())); haze->setHazeGlareBlend(graphics::Haze::convertGlareAngleToPower(_hazeProperties.getHazeGlareAngle()));
float hazeAltitude = _hazeProperties.getHazeCeiling() - _hazeProperties.getHazeBaseRef(); float hazeAltitude = _hazeProperties.getHazeCeiling() - _hazeProperties.getHazeBaseRef();
haze->setHazeAltitudeFactor(model::Haze::convertHazeAltitudeToHazeAltitudeFactor(hazeAltitude)); haze->setHazeAltitudeFactor(graphics::Haze::convertHazeAltitudeToHazeAltitudeFactor(hazeAltitude));
haze->setHazeBaseReference(_hazeProperties.getHazeBaseRef()); haze->setHazeBaseReference(_hazeProperties.getHazeBaseRef());
haze->setHazeBackgroundBlend(_hazeProperties.getHazeBackgroundBlend()); haze->setHazeBackgroundBlend(_hazeProperties.getHazeBackgroundBlend());
haze->setHazeAttenuateKeyLight(_hazeProperties.getHazeAttenuateKeyLight()); haze->setHazeAttenuateKeyLight(_hazeProperties.getHazeAttenuateKeyLight());
haze->setHazeKeyLightRangeFactor(model::Haze::convertHazeRangeToHazeRangeFactor(_hazeProperties.getHazeKeyLightRange())); haze->setHazeKeyLightRangeFactor(graphics::Haze::convertHazeRangeToHazeRangeFactor(_hazeProperties.getHazeKeyLightRange()));
haze->setHazeKeyLightAltitudeFactor(model::Haze::convertHazeAltitudeToHazeAltitudeFactor(_hazeProperties.getHazeKeyLightAltitude())); haze->setHazeKeyLightAltitudeFactor(graphics::Haze::convertHazeAltitudeToHazeAltitudeFactor(_hazeProperties.getHazeKeyLightAltitude()));
haze->setZoneTransform(entity->getTransform().getMatrix()); haze->setZoneTransform(entity->getTransform().getMatrix());
} }

View file

@ -13,9 +13,9 @@
#define hifi_RenderableZoneEntityItem_h #define hifi_RenderableZoneEntityItem_h
#include <ZoneEntityItem.h> #include <ZoneEntityItem.h>
#include <model/Skybox.h> #include <graphics/Skybox.h>
#include <model/Haze.h> #include <graphics/Haze.h>
#include <model/Stage.h> #include <graphics/Stage.h>
#include <LightStage.h> #include <LightStage.h>
#include <BackgroundStage.h> #include <BackgroundStage.h>
#include <HazeStage.h> #include <HazeStage.h>
@ -63,11 +63,11 @@ private:
void setSkyboxColor(const glm::vec3& color); void setSkyboxColor(const glm::vec3& color);
void setProceduralUserData(const QString& userData); void setProceduralUserData(const QString& userData);
model::LightPointer editSunLight() { _needSunUpdate = true; return _sunLight; } graphics::LightPointer editSunLight() { _needSunUpdate = true; return _sunLight; }
model::LightPointer editAmbientLight() { _needAmbientUpdate = true; return _ambientLight; } graphics::LightPointer editAmbientLight() { _needAmbientUpdate = true; return _ambientLight; }
model::SunSkyStagePointer editBackground() { _needBackgroundUpdate = true; return _background; } graphics::SunSkyStagePointer editBackground() { _needBackgroundUpdate = true; return _background; }
model::SkyboxPointer editSkybox() { return editBackground()->getSkybox(); } graphics::SkyboxPointer editSkybox() { return editBackground()->getSkybox(); }
model::HazePointer editHaze() { _needHazeUpdate = true; return _haze; } graphics::HazePointer editHaze() { _needHazeUpdate = true; return _haze; }
bool _needsInitialSimulation{ true }; bool _needsInitialSimulation{ true };
glm::vec3 _lastPosition; glm::vec3 _lastPosition;
@ -83,10 +83,10 @@ private:
#endif #endif
LightStagePointer _stage; LightStagePointer _stage;
const model::LightPointer _sunLight{ std::make_shared<model::Light>() }; const graphics::LightPointer _sunLight{ std::make_shared<graphics::Light>() };
const model::LightPointer _ambientLight{ std::make_shared<model::Light>() }; const graphics::LightPointer _ambientLight{ std::make_shared<graphics::Light>() };
const model::SunSkyStagePointer _background{ std::make_shared<model::SunSkyStage>() }; const graphics::SunSkyStagePointer _background{ std::make_shared<graphics::SunSkyStage>() };
const model::HazePointer _haze{ std::make_shared<model::Haze>() }; const graphics::HazePointer _haze{ std::make_shared<graphics::Haze>() };
ComponentMode _keyLightMode { COMPONENT_MODE_INHERIT }; ComponentMode _keyLightMode { COMPONENT_MODE_INHERIT };
ComponentMode _ambientLightMode { COMPONENT_MODE_INHERIT }; ComponentMode _ambientLightMode { COMPONENT_MODE_INHERIT };

View file

@ -11,7 +11,7 @@
// 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
// //
<@include model/Material.slh@> <@include graphics/Material.slh@>
<@include DeferredBufferWrite.slh@> <@include DeferredBufferWrite.slh@>
in vec3 _normal; in vec3 _normal;

View file

@ -11,7 +11,7 @@
// 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
// //
<@include model/Material.slh@> <@include graphics/Material.slh@>
<@include DeferredBufferWrite.slh@> <@include DeferredBufferWrite.slh@>
<@include Fade.slh@> <@include Fade.slh@>

View file

@ -1,4 +1,4 @@
set(TARGET_NAME entities) set(TARGET_NAME entities)
setup_hifi_library(Network Script) setup_hifi_library(Network Script)
include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}") include_directories(SYSTEM "${OPENSSL_INCLUDE_DIR}")
link_hifi_libraries(shared networking octree avatars model) link_hifi_libraries(shared networking octree avatars graphics)

View file

@ -395,6 +395,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
CHECK_PROPERTY_CHANGE(PROP_SHAPE, shape); CHECK_PROPERTY_CHANGE(PROP_SHAPE, shape);
CHECK_PROPERTY_CHANGE(PROP_DPI, dpi); CHECK_PROPERTY_CHANGE(PROP_DPI, dpi);
CHECK_PROPERTY_CHANGE(PROP_RELAY_PARENT_JOINTS, relayParentJoints);
changedProperties += _animation.getChangedProperties(); changedProperties += _animation.getChangedProperties();
changedProperties += _keyLight.getChangedProperties(); changedProperties += _keyLight.getChangedProperties();
@ -527,6 +528,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_ROTATIONS, jointRotations); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_ROTATIONS, jointRotations);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_TRANSLATIONS_SET, jointTranslationsSet); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_TRANSLATIONS_SET, jointTranslationsSet);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_TRANSLATIONS, jointTranslations); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_JOINT_TRANSLATIONS, jointTranslations);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_RELAY_PARENT_JOINTS, relayParentJoints);
} }
if (_type == EntityTypes::Model || _type == EntityTypes::Zone || _type == EntityTypes::ParticleEffect) { if (_type == EntityTypes::Model || _type == EntityTypes::Zone || _type == EntityTypes::ParticleEffect) {
@ -755,6 +757,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusSpread, float, setRadiusSpread); COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusSpread, float, setRadiusSpread);
COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusStart, float, setRadiusStart); COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusStart, float, setRadiusStart);
COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusFinish, float, setRadiusFinish); COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusFinish, float, setRadiusFinish);
COPY_PROPERTY_FROM_QSCRIPTVALUE(relayParentJoints, bool, setRelayParentJoints);
// Certifiable Properties // Certifiable Properties
COPY_PROPERTY_FROM_QSCRIPTVALUE(itemName, QString, setItemName); COPY_PROPERTY_FROM_QSCRIPTVALUE(itemName, QString, setItemName);
@ -1163,6 +1166,7 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue
ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector<glm::quat>); ADD_PROPERTY_TO_MAP(PROP_JOINT_ROTATIONS, JointRotations, jointRotations, QVector<glm::quat>);
ADD_PROPERTY_TO_MAP(PROP_JOINT_TRANSLATIONS_SET, JointTranslationsSet, jointTranslationsSet, QVector<bool>); ADD_PROPERTY_TO_MAP(PROP_JOINT_TRANSLATIONS_SET, JointTranslationsSet, jointTranslationsSet, QVector<bool>);
ADD_PROPERTY_TO_MAP(PROP_JOINT_TRANSLATIONS, JointTranslations, jointTranslations, QVector<glm::vec3>); ADD_PROPERTY_TO_MAP(PROP_JOINT_TRANSLATIONS, JointTranslations, jointTranslations, QVector<glm::vec3>);
ADD_PROPERTY_TO_MAP(PROP_RELAY_PARENT_JOINTS, RelayParentJoints, relayParentJoints, bool);
ADD_PROPERTY_TO_MAP(PROP_SHAPE, Shape, shape, QString); ADD_PROPERTY_TO_MAP(PROP_SHAPE, Shape, shape, QString);
@ -1386,6 +1390,7 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy
APPEND_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS, properties.getJointRotations()); APPEND_ENTITY_PROPERTY(PROP_JOINT_ROTATIONS, properties.getJointRotations());
APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS_SET, properties.getJointTranslationsSet()); APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS_SET, properties.getJointTranslationsSet());
APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS, properties.getJointTranslations()); APPEND_ENTITY_PROPERTY(PROP_JOINT_TRANSLATIONS, properties.getJointTranslations());
APPEND_ENTITY_PROPERTY(PROP_RELAY_PARENT_JOINTS, properties.getRelayParentJoints());
} }
if (properties.getType() == EntityTypes::Light) { if (properties.getType() == EntityTypes::Light) {
@ -1745,6 +1750,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_ROTATIONS, QVector<glm::quat>, setJointRotations); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_ROTATIONS, QVector<glm::quat>, setJointRotations);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_TRANSLATIONS_SET, QVector<bool>, setJointTranslationsSet); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_TRANSLATIONS_SET, QVector<bool>, setJointTranslationsSet);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_TRANSLATIONS, QVector<glm::vec3>, setJointTranslations); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_JOINT_TRANSLATIONS, QVector<glm::vec3>, setJointTranslations);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RELAY_PARENT_JOINTS, bool, setRelayParentJoints);
} }
if (properties.getType() == EntityTypes::Light) { if (properties.getType() == EntityTypes::Light) {
@ -2089,6 +2095,7 @@ void EntityItemProperties::markAllChanged() {
_owningAvatarIDChanged = true; _owningAvatarIDChanged = true;
_dpiChanged = true; _dpiChanged = true;
_relayParentJointsChanged = true;
} }
// The minimum bounding box for the entity. // The minimum bounding box for the entity.
@ -2455,6 +2462,9 @@ QList<QString> EntityItemProperties::listChangedProperties() {
if (jointTranslationsChanged()) { if (jointTranslationsChanged()) {
out += "jointTranslations"; out += "jointTranslations";
} }
if (relayParentJointsChanged()) {
out += "relayParentJoints";
}
if (queryAACubeChanged()) { if (queryAACubeChanged()) {
out += "queryAACube"; out += "queryAACube";
} }

View file

@ -255,6 +255,7 @@ public:
DEFINE_PROPERTY_REF(PROP_LAST_EDITED_BY, LastEditedBy, lastEditedBy, QUuid, ENTITY_ITEM_DEFAULT_LAST_EDITED_BY); DEFINE_PROPERTY_REF(PROP_LAST_EDITED_BY, LastEditedBy, lastEditedBy, QUuid, ENTITY_ITEM_DEFAULT_LAST_EDITED_BY);
DEFINE_PROPERTY_REF(PROP_SERVER_SCRIPTS, ServerScripts, serverScripts, QString, ENTITY_ITEM_DEFAULT_SERVER_SCRIPTS); DEFINE_PROPERTY_REF(PROP_SERVER_SCRIPTS, ServerScripts, serverScripts, QString, ENTITY_ITEM_DEFAULT_SERVER_SCRIPTS);
DEFINE_PROPERTY(PROP_RELAY_PARENT_JOINTS, RelayParentJoints, relayParentJoints, bool, ENTITY_ITEM_DEFAULT_RELAY_PARENT_JOINTS);
static QString getComponentModeString(uint32_t mode); static QString getComponentModeString(uint32_t mode);
static QString getComponentModeAsString(uint32_t mode); static QString getComponentModeAsString(uint32_t mode);

View file

@ -92,4 +92,6 @@ const uint16_t ENTITY_ITEM_DEFAULT_DPI = 30;
const QUuid ENTITY_ITEM_DEFAULT_LAST_EDITED_BY = QUuid(); const QUuid ENTITY_ITEM_DEFAULT_LAST_EDITED_BY = QUuid();
const bool ENTITY_ITEM_DEFAULT_RELAY_PARENT_JOINTS = false;
#endif // hifi_EntityItemPropertiesDefaults_h #endif // hifi_EntityItemPropertiesDefaults_h

View file

@ -40,6 +40,7 @@ enum EntityPropertyList {
PROP_ANIMATION_FRAME_INDEX, PROP_ANIMATION_FRAME_INDEX,
PROP_ANIMATION_PLAYING, PROP_ANIMATION_PLAYING,
PROP_ANIMATION_ALLOW_TRANSLATION, PROP_ANIMATION_ALLOW_TRANSLATION,
PROP_RELAY_PARENT_JOINTS,
// these properties are supported by the EntityItem base class // these properties are supported by the EntityItem base class
PROP_REGISTRATION_POINT, PROP_REGISTRATION_POINT,

View file

@ -2283,30 +2283,35 @@ bool EntityTree::readFromMap(QVariantMap& map) {
properties.setOwningAvatarID(myNodeID); properties.setOwningAvatarID(myNodeID);
} }
// Fix for older content not containing these fields in the zones // Fix for older content not containing mode fields in the zones
if (needsConversion && (properties.getType() == EntityTypes::EntityType::Zone)) { if (needsConversion && (properties.getType() == EntityTypes::EntityType::Zone)) {
// The legacy version had no keylight mode - this is set to on
properties.setKeyLightMode(COMPONENT_MODE_ENABLED);
// The ambient URL has been moved from "keyLight" to "ambientLight" // The ambient URL has been moved from "keyLight" to "ambientLight"
if (entityMap.contains("keyLight")) { if (entityMap.contains("keyLight")) {
QVariantMap keyLightObject = entityMap["keyLight"].toMap(); QVariantMap keyLightObject = entityMap["keyLight"].toMap();
properties.getAmbientLight().setAmbientURL(keyLightObject["ambientURL"].toString()); properties.getAmbientLight().setAmbientURL(keyLightObject["ambientURL"].toString());
} }
// Copy the skybox URL if the ambient URL is empty, as this is the legacy behaviour
// Use skybox value only if it is not empty, else set ambientMode to inherit (to use default URL)
properties.setAmbientLightMode(COMPONENT_MODE_ENABLED);
if (properties.getAmbientLight().getAmbientURL() == "") {
if (properties.getSkybox().getURL() != "") {
properties.getAmbientLight().setAmbientURL(properties.getSkybox().getURL());
} else {
properties.setAmbientLightMode(COMPONENT_MODE_INHERIT);
}
}
// The background should be enabled if the mode is skybox // The background should be enabled if the mode is skybox
// Note that if the values are default then they are not stored in the JSON file // Note that if the values are default then they are not stored in the JSON file
if (entityMap.contains("backgroundMode") && (entityMap["backgroundMode"].toString() == "skybox")) { if (entityMap.contains("backgroundMode") && (entityMap["backgroundMode"].toString() == "skybox")) {
properties.setSkyboxMode(COMPONENT_MODE_ENABLED); properties.setSkyboxMode(COMPONENT_MODE_ENABLED);
} else {
// Copy the skybox URL if the ambient URL is empty, as this is the legacy behaviour
if (properties.getAmbientLight().getAmbientURL() == "") {
properties.getAmbientLight().setAmbientURL(properties.getSkybox().getURL());
}
} else {
properties.setSkyboxMode(COMPONENT_MODE_INHERIT); properties.setSkyboxMode(COMPONENT_MODE_INHERIT);
} }
// The legacy version had no keylight/ambient modes - these are always on
properties.setKeyLightMode(COMPONENT_MODE_ENABLED);
properties.setAmbientLightMode(COMPONENT_MODE_ENABLED);
} }
EntityItemPointer entity = addEntity(entityItemID, properties); EntityItemPointer entity = addEntity(entityItemID, properties);

View file

@ -62,7 +62,7 @@ EntityItemProperties ModelEntityItem::getProperties(EntityPropertyFlags desiredP
COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointRotations, getJointRotations); COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointRotations, getJointRotations);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointTranslationsSet, getJointTranslationsSet); COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointTranslationsSet, getJointTranslationsSet);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointTranslations, getJointTranslations); COPY_ENTITY_PROPERTY_TO_PROPERTIES(jointTranslations, getJointTranslations);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(relayParentJoints, getRelayParentJoints);
_animationProperties.getProperties(properties); _animationProperties.getProperties(properties);
return properties; return properties;
} }
@ -80,6 +80,7 @@ bool ModelEntityItem::setProperties(const EntityItemProperties& properties) {
SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointRotations, setJointRotations); SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointRotations, setJointRotations);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointTranslationsSet, setJointTranslationsSet); SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointTranslationsSet, setJointTranslationsSet);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointTranslations, setJointTranslations); SET_ENTITY_PROPERTY_FROM_PROPERTIES(jointTranslations, setJointTranslations);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(relayParentJoints, setRelayParentJoints);
bool somethingChangedInAnimations = _animationProperties.setProperties(properties); bool somethingChangedInAnimations = _animationProperties.setProperties(properties);
@ -115,6 +116,7 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
READ_ENTITY_PROPERTY(PROP_MODEL_URL, QString, setModelURL); READ_ENTITY_PROPERTY(PROP_MODEL_URL, QString, setModelURL);
READ_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL); READ_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL);
READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures);
READ_ENTITY_PROPERTY(PROP_RELAY_PARENT_JOINTS, bool, setRelayParentJoints);
int bytesFromAnimation; int bytesFromAnimation;
withWriteLock([&] { withWriteLock([&] {
@ -155,6 +157,7 @@ EntityPropertyFlags ModelEntityItem::getEntityProperties(EncodeBitstreamParams&
requestedProperties += PROP_JOINT_ROTATIONS; requestedProperties += PROP_JOINT_ROTATIONS;
requestedProperties += PROP_JOINT_TRANSLATIONS_SET; requestedProperties += PROP_JOINT_TRANSLATIONS_SET;
requestedProperties += PROP_JOINT_TRANSLATIONS; requestedProperties += PROP_JOINT_TRANSLATIONS;
requestedProperties += PROP_RELAY_PARENT_JOINTS;
return requestedProperties; return requestedProperties;
} }
@ -173,6 +176,7 @@ void ModelEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBit
APPEND_ENTITY_PROPERTY(PROP_MODEL_URL, getModelURL()); APPEND_ENTITY_PROPERTY(PROP_MODEL_URL, getModelURL());
APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, getCompoundShapeURL()); APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, getCompoundShapeURL());
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures()); APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures());
APPEND_ENTITY_PROPERTY(PROP_RELAY_PARENT_JOINTS, getRelayParentJoints());
withReadLock([&] { withReadLock([&] {
_animationProperties.appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties, _animationProperties.appendSubclassData(packetData, params, entityTreeElementExtraEncodeData, requestedProperties,
@ -267,9 +271,9 @@ void ModelEntityItem::updateFrameCount() {
if (!getAnimationHold() && getAnimationIsPlaying()) { if (!getAnimationHold() && getAnimationIsPlaying()) {
float deltaTime = (float)interval / (float)USECS_PER_SECOND; float deltaTime = (float)interval / (float)USECS_PER_SECOND;
_currentFrame += (deltaTime * getAnimationFPS()); _currentFrame += (deltaTime * getAnimationFPS());
if (_currentFrame > getAnimationLastFrame()) { if (_currentFrame > getAnimationLastFrame() + 1) {
if (getAnimationLoop()) { if (getAnimationLoop() && getAnimationFirstFrame() != getAnimationLastFrame()) {
_currentFrame = getAnimationFirstFrame() + (int)(glm::floor(_currentFrame - getAnimationFirstFrame())) % (updatedFrameCount - 1); _currentFrame = getAnimationFirstFrame() + (int)(_currentFrame - getAnimationFirstFrame()) % updatedFrameCount;
} else { } else {
_currentFrame = getAnimationLastFrame(); _currentFrame = getAnimationLastFrame();
} }
@ -586,6 +590,18 @@ QString ModelEntityItem::getModelURL() const {
}); });
} }
void ModelEntityItem::setRelayParentJoints(bool relayJoints) {
withWriteLock([&] {
_relayParentJoints = relayJoints;
});
}
bool ModelEntityItem::getRelayParentJoints() const {
return resultWithReadLock<bool>([&] {
return _relayParentJoints;
});
}
QString ModelEntityItem::getCompoundShapeURL() const { QString ModelEntityItem::getCompoundShapeURL() const {
return _compoundShapeURL.get(); return _compoundShapeURL.get();
} }

View file

@ -99,6 +99,9 @@ public:
void setAnimationHold(bool hold); void setAnimationHold(bool hold);
bool getAnimationHold() const; bool getAnimationHold() const;
void setRelayParentJoints(bool relayJoints);
bool getRelayParentJoints() const;
void setAnimationFirstFrame(float firstFrame); void setAnimationFirstFrame(float firstFrame);
float getAnimationFirstFrame() const; float getAnimationFirstFrame() const;
@ -157,6 +160,7 @@ protected:
rgbColor _color; rgbColor _color;
QString _modelURL; QString _modelURL;
bool _relayParentJoints;
ThreadSafeValueCache<QString> _compoundShapeURL; ThreadSafeValueCache<QString> _compoundShapeURL;

View file

@ -1,7 +1,7 @@
set(TARGET_NAME fbx) set(TARGET_NAME fbx)
setup_hifi_library() setup_hifi_library()
link_hifi_libraries(shared model networking image) link_hifi_libraries(shared graphics networking image)
include_hifi_library_headers(gpu image) include_hifi_library_headers(gpu image)
target_draco() target_draco()

View file

@ -25,8 +25,8 @@
#include <Extents.h> #include <Extents.h>
#include <Transform.h> #include <Transform.h>
#include <model/Geometry.h> #include <graphics/Geometry.h>
#include <model/Material.h> #include <graphics/Material.h>
static const QByteArray FBX_BINARY_PROLOG = "Kaydara FBX Binary "; static const QByteArray FBX_BINARY_PROLOG = "Kaydara FBX Binary ";
static const int FBX_HEADER_BYTES_BEFORE_VERSION = 23; static const int FBX_HEADER_BYTES_BEFORE_VERSION = 23;
@ -183,7 +183,7 @@ public:
QString materialID; QString materialID;
QString name; QString name;
QString shadingModel; QString shadingModel;
model::MaterialPointer _material; graphics::MaterialPointer _material;
FBXTexture normalTexture; FBXTexture normalTexture;
FBXTexture albedoTexture; FBXTexture albedoTexture;
@ -238,7 +238,7 @@ public:
unsigned int meshIndex; // the order the meshes appeared in the object file unsigned int meshIndex; // the order the meshes appeared in the object file
model::MeshPointer _mesh; graphics::MeshPointer _mesh;
bool wasCompressed { false }; bool wasCompressed { false };
}; };

View file

@ -72,7 +72,7 @@ Extents FBXGeometry::getUnscaledMeshExtents() const {
return scaledExtents; return scaledExtents;
} }
// TODO: Move to model::Mesh when Sam's ready // TODO: Move to graphics::Mesh when Sam's ready
bool FBXGeometry::convexHullContains(const glm::vec3& point) const { bool FBXGeometry::convexHullContains(const glm::vec3& point) const {
if (!getUnscaledMeshExtents().containsPoint(point)) { if (!getUnscaledMeshExtents().containsPoint(point)) {
return false; return false;
@ -148,6 +148,59 @@ glm::vec3 parseVec3(const QString& string) {
return value; return value;
} }
enum RotationOrder {
OrderXYZ = 0,
OrderXZY,
OrderYZX,
OrderYXZ,
OrderZXY,
OrderZYX,
OrderSphericXYZ
};
bool haveReportedUnhandledRotationOrder = false; // Report error only once per FBX file.
glm::vec3 convertRotationToXYZ(int rotationOrder, const glm::vec3& rotation) {
// Convert rotation with given rotation order to have order XYZ.
if (rotationOrder == OrderXYZ) {
return rotation;
}
glm::quat xyzRotation;
switch (rotationOrder) {
case OrderXZY:
xyzRotation = glm::quat(glm::radians(glm::vec3(0, rotation.y, 0)))
* (glm::quat(glm::radians(glm::vec3(0, 0, rotation.z))) * glm::quat(glm::radians(glm::vec3(rotation.x, 0, 0))));
break;
case OrderYZX:
xyzRotation = glm::quat(glm::radians(glm::vec3(rotation.x, 0, 0)))
* (glm::quat(glm::radians(glm::vec3(0, 0, rotation.z))) * glm::quat(glm::radians(glm::vec3(0, rotation.y, 0))));
break;
case OrderYXZ:
xyzRotation = glm::quat(glm::radians(glm::vec3(0, 0, rotation.z)))
* (glm::quat(glm::radians(glm::vec3(rotation.x, 0, 0))) * glm::quat(glm::radians(glm::vec3(0, rotation.y, 0))));
break;
case OrderZXY:
xyzRotation = glm::quat(glm::radians(glm::vec3(0, rotation.y, 0)))
* (glm::quat(glm::radians(glm::vec3(rotation.x, 0, 0))) * glm::quat(glm::radians(glm::vec3(0, 0, rotation.z))));
break;
case OrderZYX:
xyzRotation = glm::quat(glm::radians(glm::vec3(rotation.x, 0, 0)))
* (glm::quat(glm::radians(glm::vec3(0, rotation.y, 0))) * glm::quat(glm::radians(glm::vec3(0, 0, rotation.z))));
break;
default:
// FIXME: Handle OrderSphericXYZ.
if (!haveReportedUnhandledRotationOrder) {
qCDebug(modelformat) << "ERROR: Unhandled rotation order in FBX file:" << rotationOrder;
haveReportedUnhandledRotationOrder = true;
}
return rotation;
}
return glm::degrees(safeEulerAngles(xyzRotation));
}
QString processID(const QString& id) { QString processID(const QString& id) {
// Blender (at least) prepends a type to the ID, so strip it out // Blender (at least) prepends a type to the ID, so strip it out
return id.mid(id.lastIndexOf(':') + 1); return id.mid(id.lastIndexOf(':') + 1);
@ -630,6 +683,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
glm::vec3 ambientColor; glm::vec3 ambientColor;
QString hifiGlobalNodeID; QString hifiGlobalNodeID;
unsigned int meshIndex = 0; unsigned int meshIndex = 0;
haveReportedUnhandledRotationOrder = false;
foreach (const FBXNode& child, node.children) { foreach (const FBXNode& child, node.children) {
if (child.name == "FBXHeaderExtension") { if (child.name == "FBXHeaderExtension") {
@ -731,6 +785,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
glm::vec3 translation; glm::vec3 translation;
// NOTE: the euler angles as supplied by the FBX file are in degrees // NOTE: the euler angles as supplied by the FBX file are in degrees
glm::vec3 rotationOffset; glm::vec3 rotationOffset;
int rotationOrder = OrderXYZ; // Default rotation order set in "Definitions" node is assumed to be XYZ.
glm::vec3 preRotation, rotation, postRotation; glm::vec3 preRotation, rotation, postRotation;
glm::vec3 scale = glm::vec3(1.0f, 1.0f, 1.0f); glm::vec3 scale = glm::vec3(1.0f, 1.0f, 1.0f);
glm::vec3 scalePivot, rotationPivot, scaleOffset; glm::vec3 scalePivot, rotationPivot, scaleOffset;
@ -764,6 +819,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
index = 4; index = 4;
} }
if (properties) { if (properties) {
static const QVariant ROTATION_ORDER = QByteArray("RotationOrder");
static const QVariant GEOMETRIC_TRANSLATION = QByteArray("GeometricTranslation"); static const QVariant GEOMETRIC_TRANSLATION = QByteArray("GeometricTranslation");
static const QVariant GEOMETRIC_ROTATION = QByteArray("GeometricRotation"); static const QVariant GEOMETRIC_ROTATION = QByteArray("GeometricRotation");
static const QVariant GEOMETRIC_SCALING = QByteArray("GeometricScaling"); static const QVariant GEOMETRIC_SCALING = QByteArray("GeometricScaling");
@ -790,6 +846,9 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
if (childProperty == LCL_TRANSLATION) { if (childProperty == LCL_TRANSLATION) {
translation = getVec3(property.properties, index); translation = getVec3(property.properties, index);
} else if (childProperty == ROTATION_ORDER) {
rotationOrder = property.properties.at(index).toInt();
} else if (childProperty == ROTATION_OFFSET) { } else if (childProperty == ROTATION_OFFSET) {
rotationOffset = getVec3(property.properties, index); rotationOffset = getVec3(property.properties, index);
@ -797,13 +856,13 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
rotationPivot = getVec3(property.properties, index); rotationPivot = getVec3(property.properties, index);
} else if (childProperty == PRE_ROTATION) { } else if (childProperty == PRE_ROTATION) {
preRotation = getVec3(property.properties, index); preRotation = convertRotationToXYZ(rotationOrder, getVec3(property.properties, index));
} else if (childProperty == LCL_ROTATION) { } else if (childProperty == LCL_ROTATION) {
rotation = getVec3(property.properties, index); rotation = convertRotationToXYZ(rotationOrder, getVec3(property.properties, index));
} else if (childProperty == POST_ROTATION) { } else if (childProperty == POST_ROTATION) {
postRotation = getVec3(property.properties, index); postRotation = convertRotationToXYZ(rotationOrder, getVec3(property.properties, index));
} else if (childProperty == SCALING_PIVOT) { } else if (childProperty == SCALING_PIVOT) {
scalePivot = getVec3(property.properties, index); scalePivot = getVec3(property.properties, index);

View file

@ -27,8 +27,8 @@
#include <Extents.h> #include <Extents.h>
#include <Transform.h> #include <Transform.h>
#include <model/Geometry.h> #include <graphics/Geometry.h>
#include <model/Material.h> #include <graphics/Material.h>
class QIODevice; class QIODevice;
class FBXNode; class FBXNode;

View file

@ -279,7 +279,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
} }
// Finally create the true material representation // Finally create the true material representation
material._material = std::make_shared<model::Material>(); material._material = std::make_shared<graphics::Material>();
// Emissive color is the mix of emissiveColor with emissiveFactor // Emissive color is the mix of emissiveColor with emissiveFactor
auto emissive = material.emissiveColor * (isMaterialLambert ? 1.0f : material.emissiveFactor); // In lambert there is not emissiveFactor auto emissive = material.emissiveColor * (isMaterialLambert ? 1.0f : material.emissiveFactor); // In lambert there is not emissiveFactor
@ -293,7 +293,7 @@ void FBXReader::consolidateFBXMaterials(const QVariantHash& mapping) {
material._material->setRoughness(material.roughness); material._material->setRoughness(material.roughness);
material._material->setMetallic(material.metallic); material._material->setMetallic(material.metallic);
} else { } else {
material._material->setRoughness(model::Material::shininessToRoughness(material.shininess)); material._material->setRoughness(graphics::Material::shininessToRoughness(material.shininess));
float metallic = std::max(material.specularColor.x, std::max(material.specularColor.y, material.specularColor.z)); float metallic = std::max(material.specularColor.x, std::max(material.specularColor.y, material.specularColor.z));
material._material->setMetallic(metallic); material._material->setMetallic(metallic);

View file

@ -584,7 +584,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
} }
FBXMesh& fbxMesh = extractedMesh; FBXMesh& fbxMesh = extractedMesh;
model::MeshPointer mesh(new model::Mesh()); graphics::MeshPointer mesh(new graphics::Mesh());
// Grab the vertices in a buffer // Grab the vertices in a buffer
auto vb = std::make_shared<gpu::Buffer>(); auto vb = std::make_shared<gpu::Buffer>();
@ -603,7 +603,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
if (!blendShape.normals.empty() && blendShape.tangents.empty()) { if (!blendShape.normals.empty() && blendShape.tangents.empty()) {
// Fill with a dummy value to force tangents to be present if there are normals // Fill with a dummy value to force tangents to be present if there are normals
blendShape.tangents.reserve(blendShape.normals.size()); blendShape.tangents.reserve(blendShape.normals.size());
std::fill_n(std::back_inserter(fbxMesh.tangents), blendShape.normals.size(), Vectors::UNIT_X); std::fill_n(std::back_inserter(blendShape.tangents), blendShape.normals.size(), Vectors::UNIT_X);
} }
} }
@ -721,45 +721,45 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
if (normalsSize) { if (normalsSize) {
mesh->addAttribute(gpu::Stream::NORMAL, mesh->addAttribute(gpu::Stream::NORMAL,
model::BufferView(attribBuffer, normalsOffset, normalsAndTangentsSize, graphics::BufferView(attribBuffer, normalsOffset, normalsAndTangentsSize,
normalsAndTangentsStride, FBX_NORMAL_ELEMENT)); normalsAndTangentsStride, FBX_NORMAL_ELEMENT));
mesh->addAttribute(gpu::Stream::TANGENT, mesh->addAttribute(gpu::Stream::TANGENT,
model::BufferView(attribBuffer, tangentsOffset, normalsAndTangentsSize, graphics::BufferView(attribBuffer, tangentsOffset, normalsAndTangentsSize,
normalsAndTangentsStride, FBX_NORMAL_ELEMENT)); normalsAndTangentsStride, FBX_NORMAL_ELEMENT));
} }
if (colorsSize) { if (colorsSize) {
mesh->addAttribute(gpu::Stream::COLOR, mesh->addAttribute(gpu::Stream::COLOR,
model::BufferView(attribBuffer, colorsOffset, colorsSize, FBX_COLOR_ELEMENT)); graphics::BufferView(attribBuffer, colorsOffset, colorsSize, FBX_COLOR_ELEMENT));
} }
if (texCoordsSize) { if (texCoordsSize) {
mesh->addAttribute(gpu::Stream::TEXCOORD, mesh->addAttribute(gpu::Stream::TEXCOORD,
model::BufferView( attribBuffer, texCoordsOffset, texCoordsSize, graphics::BufferView( attribBuffer, texCoordsOffset, texCoordsSize,
gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV))); gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV)));
} }
if (texCoords1Size) { if (texCoords1Size) {
mesh->addAttribute( gpu::Stream::TEXCOORD1, mesh->addAttribute( gpu::Stream::TEXCOORD1,
model::BufferView(attribBuffer, texCoords1Offset, texCoords1Size, graphics::BufferView(attribBuffer, texCoords1Offset, texCoords1Size,
gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV))); gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV)));
} else if (texCoordsSize) { } else if (texCoordsSize) {
mesh->addAttribute(gpu::Stream::TEXCOORD1, mesh->addAttribute(gpu::Stream::TEXCOORD1,
model::BufferView(attribBuffer, texCoordsOffset, texCoordsSize, graphics::BufferView(attribBuffer, texCoordsOffset, texCoordsSize,
gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV))); gpu::Element(gpu::VEC2, gpu::HALF, gpu::UV)));
} }
if (clusterIndicesSize) { if (clusterIndicesSize) {
if (fbxMesh.clusters.size() < UINT8_MAX) { if (fbxMesh.clusters.size() < UINT8_MAX) {
mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX,
model::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize, graphics::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize,
gpu::Element(gpu::VEC4, gpu::UINT8, gpu::XYZW))); gpu::Element(gpu::VEC4, gpu::UINT8, gpu::XYZW)));
} else { } else {
mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX, mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_INDEX,
model::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize, graphics::BufferView(attribBuffer, clusterIndicesOffset, clusterIndicesSize,
gpu::Element(gpu::VEC4, gpu::UINT16, gpu::XYZW))); gpu::Element(gpu::VEC4, gpu::UINT16, gpu::XYZW)));
} }
} }
if (clusterWeightsSize) { if (clusterWeightsSize) {
mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT, mesh->addAttribute(gpu::Stream::SKIN_CLUSTER_WEIGHT,
model::BufferView(attribBuffer, clusterWeightsOffset, clusterWeightsSize, graphics::BufferView(attribBuffer, clusterWeightsOffset, clusterWeightsSize,
gpu::Element(gpu::VEC4, gpu::NUINT16, gpu::XYZW))); gpu::Element(gpu::VEC4, gpu::NUINT16, gpu::XYZW)));
} }
@ -780,12 +780,12 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
int indexNum = 0; int indexNum = 0;
int offset = 0; int offset = 0;
std::vector< model::Mesh::Part > parts; std::vector< graphics::Mesh::Part > parts;
if (extractedMesh.parts.size() > 1) { if (extractedMesh.parts.size() > 1) {
indexNum = 0; indexNum = 0;
} }
foreach(const FBXMeshPart& part, extractedMesh.parts) { foreach(const FBXMeshPart& part, extractedMesh.parts) {
model::Mesh::Part modelPart(indexNum, 0, 0, model::Mesh::TRIANGLES); graphics::Mesh::Part modelPart(indexNum, 0, 0, graphics::Mesh::TRIANGLES);
if (part.quadTrianglesIndices.size()) { if (part.quadTrianglesIndices.size()) {
indexBuffer->setSubData(offset, indexBuffer->setSubData(offset,
@ -813,7 +813,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
if (parts.size()) { if (parts.size()) {
auto pb = std::make_shared<gpu::Buffer>(); auto pb = std::make_shared<gpu::Buffer>();
pb->setData(parts.size() * sizeof(model::Mesh::Part), (const gpu::Byte*) parts.data()); pb->setData(parts.size() * sizeof(graphics::Mesh::Part), (const gpu::Byte*) parts.data());
gpu::BufferView pbv(pb, gpu::Element(gpu::VEC4, gpu::UINT32, gpu::XYZW)); gpu::BufferView pbv(pb, gpu::Element(gpu::VEC4, gpu::UINT32, gpu::XYZW));
mesh->setPartBuffer(pbv); mesh->setPartBuffer(pbv);
} else { } else {
@ -821,7 +821,7 @@ void FBXReader::buildModelMesh(FBXMesh& extractedMesh, const QString& url) {
return; return;
} }
// model::Box box = // graphics::Box box =
mesh->evalPartBound(0); mesh->evalPartBound(0);
extractedMesh._mesh = mesh; extractedMesh._mesh = mesh;

View file

@ -748,7 +748,7 @@ bool GLTFReader::buildGeometry(FBXGeometry& geometry, const QUrl& url) {
QString& matid = materialIDs[i]; QString& matid = materialIDs[i];
geometry.materials[matid] = FBXMaterial(); geometry.materials[matid] = FBXMaterial();
FBXMaterial& fbxMaterial = geometry.materials[matid]; FBXMaterial& fbxMaterial = geometry.materials[matid];
fbxMaterial._material = std::make_shared<model::Material>(); fbxMaterial._material = std::make_shared<graphics::Material>();
setFBXMaterial(fbxMaterial, _file.materials[i]); setFBXMaterial(fbxMaterial, _file.materials[i]);
} }

View file

@ -750,8 +750,8 @@ FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping,
objMaterial.opacity); objMaterial.opacity);
FBXMaterial& fbxMaterial = geometry.materials[materialID]; FBXMaterial& fbxMaterial = geometry.materials[materialID];
fbxMaterial.materialID = materialID; fbxMaterial.materialID = materialID;
fbxMaterial._material = std::make_shared<model::Material>(); fbxMaterial._material = std::make_shared<graphics::Material>();
model::MaterialPointer modelMaterial = fbxMaterial._material; graphics::MaterialPointer modelMaterial = fbxMaterial._material;
if (!objMaterial.diffuseTextureFilename.isEmpty()) { if (!objMaterial.diffuseTextureFilename.isEmpty()) {
fbxMaterial.albedoTexture.filename = objMaterial.diffuseTextureFilename; fbxMaterial.albedoTexture.filename = objMaterial.diffuseTextureFilename;
@ -763,7 +763,7 @@ FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping,
modelMaterial->setEmissive(fbxMaterial.emissiveColor); modelMaterial->setEmissive(fbxMaterial.emissiveColor);
modelMaterial->setAlbedo(fbxMaterial.diffuseColor); modelMaterial->setAlbedo(fbxMaterial.diffuseColor);
modelMaterial->setMetallic(glm::length(fbxMaterial.specularColor)); modelMaterial->setMetallic(glm::length(fbxMaterial.specularColor));
modelMaterial->setRoughness(model::Material::shininessToRoughness(fbxMaterial.shininess)); modelMaterial->setRoughness(graphics::Material::shininessToRoughness(fbxMaterial.shininess));
if (fbxMaterial.opacity <= 0.0f) { if (fbxMaterial.opacity <= 0.0f) {
modelMaterial->setOpacity(1.0f); modelMaterial->setOpacity(1.0f);

View file

@ -11,7 +11,7 @@
#include <QFile> #include <QFile>
#include <QFileInfo> #include <QFileInfo>
#include "model/Geometry.h" #include "graphics/Geometry.h"
#include "OBJWriter.h" #include "OBJWriter.h"
#include "ModelFormatLogging.h" #include "ModelFormatLogging.h"
@ -105,13 +105,13 @@ bool writeOBJToTextStream(QTextStream& out, QList<MeshPointer> meshes) {
const gpu::BufferView& partBuffer = mesh->getPartBuffer(); const gpu::BufferView& partBuffer = mesh->getPartBuffer();
const gpu::BufferView& indexBuffer = mesh->getIndexBuffer(); const gpu::BufferView& indexBuffer = mesh->getIndexBuffer();
model::Index partCount = (model::Index)mesh->getNumParts(); graphics::Index partCount = (graphics::Index)mesh->getNumParts();
for (int partIndex = 0; partIndex < partCount; partIndex++) { for (int partIndex = 0; partIndex < partCount; partIndex++) {
const model::Mesh::Part& part = partBuffer.get<model::Mesh::Part>(partIndex); const graphics::Mesh::Part& part = partBuffer.get<graphics::Mesh::Part>(partIndex);
out << "g part-" << nth++ << "\n"; out << "g part-" << nth++ << "\n";
// model::Mesh::TRIANGLES // graphics::Mesh::TRIANGLES
// TODO -- handle other formats // TODO -- handle other formats
gpu::BufferView::Iterator<const uint32_t> indexItr = indexBuffer.cbegin<uint32_t>(); gpu::BufferView::Iterator<const uint32_t> indexItr = indexBuffer.cbegin<uint32_t>();
indexItr += part._startIndex; indexItr += part._startIndex;

View file

@ -15,9 +15,9 @@
#include <QString> #include <QString>
#include <QList> #include <QList>
#include <model/Geometry.h> #include <graphics/Geometry.h>
using MeshPointer = std::shared_ptr<model::Mesh>; using MeshPointer = std::shared_ptr<graphics::Mesh>;
bool writeOBJToTextStream(QTextStream& out, QList<MeshPointer> meshes); bool writeOBJToTextStream(QTextStream& out, QList<MeshPointer> meshes);
bool writeOBJToFile(QString path, QList<MeshPointer> meshes); bool writeOBJToFile(QString path, QList<MeshPointer> meshes);

View file

@ -1,4 +1,4 @@
set(TARGET_NAME model) set(TARGET_NAME graphics)
AUTOSCRIBE_SHADER_LIB(gpu model) AUTOSCRIBE_SHADER_LIB(gpu graphics)
setup_hifi_library() setup_hifi_library()
link_hifi_libraries(shared ktx gpu image) link_hifi_libraries(shared ktx gpu image)

View file

@ -1,6 +1,6 @@
// //
// Asset.cpp // Asset.cpp
// libraries/model/src/model // libraries/graphics/src/graphics
// //
// Created by Sam Gateau on 08/21/2015. // Created by Sam Gateau on 08/21/2015.
// Copyright 2015 High Fidelity, Inc. // Copyright 2015 High Fidelity, Inc.
@ -10,7 +10,7 @@
// //
#include "Asset.h" #include "Asset.h"
using namespace model; using namespace graphics;
Asset::Asset() { Asset::Asset() {
} }

View file

@ -1,6 +1,6 @@
// //
// Asset.h // Asset.h
// libraries/model/src/model // libraries/graphics/src/graphics
// //
// Created by Sam Gateau on 08/21/2015. // Created by Sam Gateau on 08/21/2015.
// Copyright 2015 High Fidelity, Inc. // Copyright 2015 High Fidelity, Inc.
@ -17,7 +17,7 @@
#include "Material.h" #include "Material.h"
#include "Geometry.h" #include "Geometry.h"
namespace model { namespace graphics {
template <class T> template <class T>
class Table { class Table {

View file

@ -1,6 +1,6 @@
// //
// Forward.h // Forward.h
// libraries/model/src/model // libraries/graphics/src/graphics
// //
// Created by Bradley Austin Davis on 2017/06/21 // Created by Bradley Austin Davis on 2017/06/21
// Copyright 2013-2017 High Fidelity, Inc. // Copyright 2013-2017 High Fidelity, Inc.
@ -11,7 +11,7 @@
#ifndef hifi_model_Forward_h #ifndef hifi_model_Forward_h
#define hifi_model_Forward_h #define hifi_model_Forward_h
namespace model { namespace graphics {
class Mesh; class Mesh;
using MeshPointer = std::shared_ptr<Mesh>; using MeshPointer = std::shared_ptr<Mesh>;
} }

View file

@ -1,6 +1,6 @@
// //
// Geometry.cpp // Geometry.cpp
// libraries/model/src/model // libraries/graphics/src/graphics
// //
// Created by Sam Gateau on 12/5/2014. // Created by Sam Gateau on 12/5/2014.
// Copyright 2014 High Fidelity, Inc. // Copyright 2014 High Fidelity, Inc.
@ -13,7 +13,7 @@
#include <glm/gtc/packing.hpp> #include <glm/gtc/packing.hpp>
using namespace model; using namespace graphics;
Mesh::Mesh() : Mesh::Mesh() :
_vertexBuffer(gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)), _vertexBuffer(gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ)),
@ -137,7 +137,7 @@ Box Mesh::evalPartsBound(int partStart, int partEnd) const {
} }
model::MeshPointer Mesh::map(std::function<glm::vec3(glm::vec3)> vertexFunc, graphics::MeshPointer Mesh::map(std::function<glm::vec3(glm::vec3)> vertexFunc,
std::function<glm::vec3(glm::vec3)> colorFunc, std::function<glm::vec3(glm::vec3)> colorFunc,
std::function<glm::vec3(glm::vec3)> normalFunc, std::function<glm::vec3(glm::vec3)> normalFunc,
std::function<uint32_t(uint32_t)> indexFunc) const { std::function<uint32_t(uint32_t)> indexFunc) const {
@ -223,7 +223,7 @@ model::MeshPointer Mesh::map(std::function<glm::vec3(glm::vec3)> vertexFunc,
indexDataCursor += sizeof(index); indexDataCursor += sizeof(index);
} }
model::MeshPointer result(new model::Mesh()); graphics::MeshPointer result(new graphics::Mesh());
gpu::Element vertexElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ); gpu::Element vertexElement = gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ);
gpu::Buffer* resultVertexBuffer = new gpu::Buffer(vertexSize, resultVertexData.get()); gpu::Buffer* resultVertexBuffer = new gpu::Buffer(vertexSize, resultVertexData.get());
@ -252,12 +252,12 @@ model::MeshPointer Mesh::map(std::function<glm::vec3(glm::vec3)> vertexFunc,
// TODO -- shouldn't assume just one part // TODO -- shouldn't assume just one part
std::vector<model::Mesh::Part> parts; std::vector<graphics::Mesh::Part> parts;
parts.emplace_back(model::Mesh::Part((model::Index)0, // startIndex parts.emplace_back(graphics::Mesh::Part((graphics::Index)0, // startIndex
(model::Index)result->getNumIndices(), // numIndices (graphics::Index)result->getNumIndices(), // numIndices
(model::Index)0, // baseVertex (graphics::Index)0, // baseVertex
model::Mesh::TRIANGLES)); // topology graphics::Mesh::TRIANGLES)); // topology
result->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(model::Mesh::Part), result->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(graphics::Mesh::Part),
(gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL)); (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL));
return result; return result;
@ -350,9 +350,9 @@ MeshPointer Mesh::createIndexedTriangles_P3F(uint32_t numVertices, uint32_t numI
} }
std::vector<model::Mesh::Part> parts; std::vector<graphics::Mesh::Part> parts;
parts.push_back(model::Mesh::Part(0, numIndices, 0, model::Mesh::TRIANGLES)); parts.push_back(graphics::Mesh::Part(0, numIndices, 0, graphics::Mesh::TRIANGLES));
mesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(model::Mesh::Part), (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL)); mesh->setPartBuffer(gpu::BufferView(new gpu::Buffer(parts.size() * sizeof(graphics::Mesh::Part), (gpu::Byte*) parts.data()), gpu::Element::PART_DRAWCALL));
return mesh; return mesh;
} }

View file

@ -1,6 +1,6 @@
// //
// Geometry.h // Geometry.h
// libraries/model/src/model // libraries/graphics/src/graphics
// //
// Created by Sam Gateau on 12/5/2014. // Created by Sam Gateau on 12/5/2014.
// Copyright 2014 High Fidelity, Inc. // Copyright 2014 High Fidelity, Inc.
@ -18,7 +18,7 @@
#include <gpu/Resource.h> #include <gpu/Resource.h>
#include <gpu/Stream.h> #include <gpu/Stream.h>
namespace model { namespace graphics {
typedef gpu::BufferView::Index Index; typedef gpu::BufferView::Index Index;
typedef gpu::BufferView BufferView; typedef gpu::BufferView BufferView;
typedef AABox Box; typedef AABox Box;
@ -40,7 +40,7 @@ public:
typedef gpu::Stream::Format VertexFormat; typedef gpu::Stream::Format VertexFormat;
typedef std::map< Slot, BufferView > BufferViewMap; typedef std::map< Slot, BufferView > BufferViewMap;
typedef model::Vec3 Vec3; typedef graphics::Vec3 Vec3;
Mesh(); Mesh();
Mesh(const Mesh& mesh); Mesh(const Mesh& mesh);

View file

@ -6,6 +6,6 @@
// 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
// //
#include "ModelLogging.h" #include "GraphicsLogging.h"
Q_LOGGING_CATEGORY(modelLog, "hifi.model") Q_LOGGING_CATEGORY(graphicsLog, "hifi.graphics")

View file

@ -1,5 +1,5 @@
// //
// ModelLogging.h // GraphicsLogging.h
// hifi // hifi
// //
// Created by Sam Gateau on 9/20/15. // Created by Sam Gateau on 9/20/15.
@ -11,4 +11,4 @@
#include <QLoggingCategory> #include <QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(modelLog) Q_DECLARE_LOGGING_CATEGORY(graphicsLog)

View file

@ -1,6 +1,6 @@
// //
// Haze.cpp // Haze.cpp
// libraries/model/src/model // libraries/graphics/src/graphics
// //
// Created by Nissim Hadar on 9/13/2017. // Created by Nissim Hadar on 9/13/2017.
// Copyright 2014 High Fidelity, Inc. // Copyright 2014 High Fidelity, Inc.
@ -12,7 +12,7 @@
#include <memory> #include <memory>
#include "Haze.h" #include "Haze.h"
using namespace model; using namespace graphics;
const float Haze::INITIAL_HAZE_RANGE{ 1000.0f }; const float Haze::INITIAL_HAZE_RANGE{ 1000.0f };
const float Haze::INITIAL_HAZE_HEIGHT{ 200.0f }; const float Haze::INITIAL_HAZE_HEIGHT{ 200.0f };

View file

@ -1,6 +1,6 @@
// //
// MakeHaze.h // MakeHaze.h
// libraries/model/src/model // libraries/graphics/src/graphics
// //
// Created by Nissim Hadar on 9/13/2017. // Created by Nissim Hadar on 9/13/2017.
// Copyright 2014 High Fidelity, Inc. // Copyright 2014 High Fidelity, Inc.
@ -17,7 +17,7 @@
#include "Transform.h" #include "Transform.h"
#include "NumericalConstants.h" #include "NumericalConstants.h"
namespace model { namespace graphics {
// Haze range is defined here as the range the visibility is reduced by 95% // Haze range is defined here as the range the visibility is reduced by 95%
// Haze altitude is defined here as the altitude (above 0) that the haze is reduced by 95% // Haze altitude is defined here as the altitude (above 0) that the haze is reduced by 95%

View file

@ -1,6 +1,6 @@
// //
// Light.cpp // Light.cpp
// libraries/model/src/model // libraries/graphics/src/graphics
// //
// Created by Sam Gateau on 1/26/2014. // Created by Sam Gateau on 1/26/2014.
// Copyright 2014 High Fidelity, Inc. // Copyright 2014 High Fidelity, Inc.
@ -10,7 +10,7 @@
// //
#include "Light.h" #include "Light.h"
using namespace model; using namespace graphics;
Light::Light() { Light::Light() {
updateLightRadius(); updateLightRadius();

View file

@ -1,6 +1,6 @@
// //
// Light.h // Light.h
// libraries/model/src/model // libraries/graphics/src/graphics
// //
// Created by Sam Gateau on 12/10/2014. // Created by Sam Gateau on 12/10/2014.
// Copyright 2014 High Fidelity, Inc. // Copyright 2014 High Fidelity, Inc.
@ -19,7 +19,7 @@
#include "gpu/Resource.h" #include "gpu/Resource.h"
#include "gpu/Texture.h" #include "gpu/Texture.h"
namespace model { namespace graphics {
typedef gpu::BufferView UniformBufferView; typedef gpu::BufferView UniformBufferView;
typedef gpu::TextureView TextureView; typedef gpu::TextureView TextureView;
typedef glm::vec3 Vec3; typedef glm::vec3 Vec3;

View file

@ -11,8 +11,8 @@
<@if not MODEL_LIGHT_SLH@> <@if not MODEL_LIGHT_SLH@>
<@def MODEL_LIGHT_SLH@> <@def MODEL_LIGHT_SLH@>
<@include model/LightVolume.shared.slh@> <@include graphics/LightVolume.shared.slh@>
<@include model/LightIrradiance.shared.slh@> <@include graphics/LightIrradiance.shared.slh@>
// NOw lets define Light // NOw lets define Light
struct Light { struct Light {
@ -30,7 +30,7 @@ float getLightIntensity(Light l) { return lightIrradiance_getIntensity(l.irradia
vec3 getLightIrradiance(Light l) { return lightIrradiance_getIrradiance(l.irradiance); } vec3 getLightIrradiance(Light l) { return lightIrradiance_getIrradiance(l.irradiance); }
// AMbient lighting needs extra info provided from a different Buffer // AMbient lighting needs extra info provided from a different Buffer
<@include model/SphericalHarmonics.shared.slh@> <@include graphics/SphericalHarmonics.shared.slh@>
// Light Ambient // Light Ambient
struct LightAmbient { struct LightAmbient {
vec4 _ambient; vec4 _ambient;

View file

@ -3,7 +3,7 @@
#define LightVolume_Shared_slh #define LightVolume_Shared_slh
// Light.shared.slh // Light.shared.slh
// libraries/model/src/model // libraries/graphics/src/graphics
// //
// Created by Sam Gateau on 14/9/2016. // Created by Sam Gateau on 14/9/2016.
// Copyright 2014 High Fidelity, Inc. // Copyright 2014 High Fidelity, Inc.

View file

@ -1,6 +1,6 @@
// //
// Material.cpp // Material.cpp
// libraries/model/src/model // libraries/graphics/src/graphics
// //
// Created by Sam Gateau on 12/10/2014. // Created by Sam Gateau on 12/10/2014.
// Copyright 2014 High Fidelity, Inc. // Copyright 2014 High Fidelity, Inc.
@ -12,7 +12,7 @@
#include "TextureMap.h" #include "TextureMap.h"
using namespace model; using namespace graphics;
using namespace gpu; using namespace gpu;
Material::Material() : Material::Material() :

View file

@ -1,6 +1,6 @@
// //
// Material.h // Material.h
// libraries/model/src/model // libraries/graphics/src/graphics
// //
// Created by Sam Gateau on 12/10/2014. // Created by Sam Gateau on 12/10/2014.
// Copyright 2014 High Fidelity, Inc. // Copyright 2014 High Fidelity, Inc.
@ -20,7 +20,7 @@
#include <gpu/Resource.h> #include <gpu/Resource.h>
namespace model { namespace graphics {
class TextureMap; class TextureMap;
typedef std::shared_ptr< TextureMap > TextureMapPointer; typedef std::shared_ptr< TextureMap > TextureMapPointer;

Some files were not shown because too many files have changed in this diff Show more