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

This commit is contained in:
RebeccaStankus 2019-06-19 10:14:04 -07:00
commit feaea12b24
21 changed files with 461 additions and 124 deletions

View file

@ -33,7 +33,7 @@ If you do not wish to use the Python installation bundled with Visual Studio, yo
Download and install the latest version of CMake 3.9. Download and install the latest version of CMake 3.9.
Download the file named win64-x64 Installer from the [CMake Website](https://cmake.org/download/). You can access the installer on this [3.9 Version page](https://cmake.org/files/v3.9/). During installation, make sure to check "Add CMake to system PATH for all users" when prompted. Download the file named win64-x64 Installer from the [CMake Website](https://cmake.org/download/). You can access the installer on this [3.14 Version page](https://cmake.org/files/v3.14/). During installation, make sure to check "Add CMake to system PATH for all users" when prompted.
### Step 3. Create VCPKG environment variable ### Step 3. Create VCPKG environment variable
In the next step, you will use CMake to build High Fidelity. By default, the CMake process builds dependency files in Windows' `%TEMP%` directory, which is periodically cleared by the operating system. To prevent you from having to re-build the dependencies in the event that Windows clears that directory, we recommend that you create a `HIFI_VCPKG_BASE` environment variable linked to a directory somewhere on your machine. That directory will contain all dependency files until you manually remove them. In the next step, you will use CMake to build High Fidelity. By default, the CMake process builds dependency files in Windows' `%TEMP%` directory, which is periodically cleared by the operating system. To prevent you from having to re-build the dependencies in the event that Windows clears that directory, we recommend that you create a `HIFI_VCPKG_BASE` environment variable linked to a directory somewhere on your machine. That directory will contain all dependency files until you manually remove them.

View file

@ -739,6 +739,10 @@ void DomainServer::setupNodeListAndAssignments() {
connect(nodeList.data(), &LimitedNodeList::nodeAdded, this, &DomainServer::nodeAdded); connect(nodeList.data(), &LimitedNodeList::nodeAdded, this, &DomainServer::nodeAdded);
connect(nodeList.data(), &LimitedNodeList::nodeKilled, this, &DomainServer::nodeKilled); connect(nodeList.data(), &LimitedNodeList::nodeKilled, this, &DomainServer::nodeKilled);
connect(nodeList.data(), &LimitedNodeList::localSockAddrChanged, this,
[this](const HifiSockAddr& localSockAddr) {
DependencyManager::get<LimitedNodeList>()->putLocalPortIntoSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, this, localSockAddr.getPort());
});
// register as the packet receiver for the types we want // register as the packet receiver for the types we want
PacketReceiver& packetReceiver = nodeList->getPacketReceiver(); PacketReceiver& packetReceiver = nodeList->getPacketReceiver();

View file

@ -94,6 +94,7 @@ Item {
text: MyAvatar.sessionDisplayName === "" ? MyAvatar.displayName : MyAvatar.sessionDisplayName text: MyAvatar.sessionDisplayName === "" ? MyAvatar.displayName : MyAvatar.sessionDisplayName
maximumLength: 256 maximumLength: 256
clip: true clip: true
selectByMouse: true
anchors.fill: parent anchors.fill: parent
onEditingFinished: { onEditingFinished: {
if (MyAvatar.displayName !== text) { if (MyAvatar.displayName !== text) {

View file

@ -17,6 +17,7 @@ import "./audio" as AudioSettings
import "./general" as GeneralSettings import "./general" as GeneralSettings
import "./vr" as VrSettings import "./vr" as VrSettings
import "./dev" as DevSettings import "./dev" as DevSettings
import "./about" as AboutSettings
Rectangle { Rectangle {
property string activeTabView: "generalTabView" property string activeTabView: "generalTabView"
@ -76,6 +77,10 @@ Rectangle {
tabTitle: "VR" tabTitle: "VR"
tabViewName: "vrTabView" tabViewName: "vrTabView"
} }
ListElement {
tabTitle: "About"
tabViewName: "aboutTabView"
}
ListElement { ListElement {
tabTitle: "Dev" tabTitle: "Dev"
tabViewName: "devTabView" tabViewName: "devTabView"
@ -103,7 +108,7 @@ Rectangle {
delegate: Item { delegate: Item {
visible: model.tabTitle !== "Dev" || (model.tabTitle === "Dev" && root.developerModeEnabled) visible: model.tabTitle !== "Dev" || (model.tabTitle === "Dev" && root.developerModeEnabled)
width: tabTitleText.paintedWidth + 64 width: tabTitleText.paintedWidth + 32
height: parent.height height: parent.height
HifiStylesUit.GraphikRegular { HifiStylesUit.GraphikRegular {
@ -163,6 +168,12 @@ Rectangle {
anchors.fill: parent anchors.fill: parent
} }
AboutSettings.About {
id: aboutTabViewContainer
visible: activeTabView === "aboutTabView"
anchors.fill: parent
}
SimplifiedControls.VerticalScrollBar { SimplifiedControls.VerticalScrollBar {
parent: { parent: {
if (activeTabView === "generalTabView") { if (activeTabView === "generalTabView") {
@ -173,6 +184,8 @@ Rectangle {
vrTabViewContainer vrTabViewContainer
} else if (activeTabView === "devTabView") { } else if (activeTabView === "devTabView") {
devTabViewContainer devTabViewContainer
} else if (activeTabView === "aboutTabView") {
aboutTabViewContainer
} }
} }
} }

View file

@ -0,0 +1,218 @@
//
// About.qml
//
// Created by Zach Fox on 2019-06-18
// Copyright 2019 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
import QtQuick 2.10
import QtQuick.Controls 2.3
import "../../simplifiedConstants" as SimplifiedConstants
import "../../simplifiedControls" as SimplifiedControls
import stylesUit 1.0 as HifiStylesUit
import QtQuick.Layouts 1.3
Flickable {
id: root
contentWidth: parent.width
contentHeight: aboutColumnLayout.height
clip: true
onVisibleChanged: {
if (visible) {
root.contentX = 0;
root.contentY = 0;
}
}
SimplifiedConstants.SimplifiedConstants {
id: simplifiedUI
}
ColumnLayout {
id: aboutColumnLayout
anchors.left: parent.left
anchors.leftMargin: 26
anchors.right: parent.right
anchors.rightMargin: 26
anchors.top: parent.top
spacing: 0
Image {
source: "images/logo.png"
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: 16
Layout.preferredWidth: 200
Layout.preferredHeight: 150
fillMode: Image.PreserveAspectFit
mipmap: true
}
ColumnLayout {
id: platformInfoContainer
Layout.preferredWidth: parent.width
Layout.bottomMargin: 24
spacing: 0
HifiStylesUit.GraphikSemiBold {
text: "Version " + Window.checkVersion()
Layout.alignment: Qt.AlignHCenter
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikSemiBold {
text: "Platform Info"
Layout.maximumWidth: parent.width
Layout.topMargin: 8
Layout.bottomMargin: 8
height: paintedHeight
size: 22
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikRegular {
text: "<b>Computer Vendor/Model:</b>"
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
Component.onCompleted: {
var computer = JSON.parse(PlatformInfo.getComputer());
var computerVendor = computer.vendor;
if (computerVendor.length === 0) {
computerVendor = "Unknown";
}
var computerModel = computer.model;
if (computerModel.length === 0) {
computerModel = "Unknown";
}
text = "<b>Computer Vendor/Model:</b> " + computerVendor + "/" + computerModel;
}
}
HifiStylesUit.GraphikRegular {
text: "<b>Profiled Platform Tier:</b> " + PlatformInfo.getTierProfiled()
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikRegular {
text: "<b>OS Type:</b> " + PlatformInfo.getOperatingSystemType()
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikRegular {
text: "<b>CPU:</b> " + PlatformInfo.getCPUBrand()
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikRegular {
text: "<b># CPUs:</b> " + PlatformInfo.getNumCPUs()
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikRegular {
text: "<b># CPU Cores:</b> " + PlatformInfo.getNumLogicalCores()
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikRegular {
text: "<b>RAM:</b> " + PlatformInfo.getTotalSystemMemoryMB() + " MB"
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikRegular {
text: "<b>GPU:</b> " + PlatformInfo.getGraphicsCardType()
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikRegular {
text: "<b>VR Hand Controllers:</b> " + (PlatformInfo.hasRiftControllers() ? "Rift" : (PlatformInfo.hasViveControllers() ? "Vive" : "None"))
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
SimplifiedControls.Button {
Layout.topMargin: 8
width: 200
height: 32
text: "Copy to Clipboard"
onClicked: {
Window.copyToClipboard(root.buildPlatformInfoTextToCopy());
}
}
}
}
function buildPlatformInfoTextToCopy() {
var textToCopy = "**About Interface**\n";
textToCopy += "Interface Version: " + Window.checkVersion() + "\n";
textToCopy += "\n**Platform Info**\n";
var computer = JSON.parse(PlatformInfo.getComputer());
var computerVendor = computer.vendor;
if (computerVendor.length === 0) {
computerVendor = "Unknown";
}
var computerModel = computer.model;
if (computerModel.length === 0) {
computerModel = "Unknown";
}
textToCopy += "Computer Vendor/Model: " + computerVendor + "/" + computerModel + "\n";
textToCopy += "Profiled Platform Tier: " + PlatformInfo.getTierProfiled() + "\n";
textToCopy += "OS Type: " + PlatformInfo.getOperatingSystemType() + "\n";
textToCopy += "CPU: " + PlatformInfo.getCPUBrand() + "\n";
textToCopy += "# CPUs: " + PlatformInfo.getNumCPUs() + "\n";
textToCopy += "# CPU Cores: " + PlatformInfo.getNumLogicalCores() + "\n";
textToCopy += "RAM: " + PlatformInfo.getTotalSystemMemoryMB() + " MB\n";
textToCopy += "GPU: " + PlatformInfo.getGraphicsCardType() + "\n";
textToCopy += "VR Hand Controllers: " + (PlatformInfo.hasRiftControllers() ? "Rift" : (PlatformInfo.hasViveControllers() ? "Vive" : "None"));
return textToCopy;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -1416,6 +1416,10 @@ void MyAvatar::setEnableDebugDrawAnimPose(bool isEnabled) {
} }
} }
void MyAvatar::setDebugDrawAnimPoseName(QString poseName) {
_debugDrawAnimPoseName.set(poseName);
}
void MyAvatar::setEnableDebugDrawPosition(bool isEnabled) { void MyAvatar::setEnableDebugDrawPosition(bool isEnabled) {
if (isEnabled) { if (isEnabled) {
const glm::vec4 red(1.0f, 0.0f, 0.0f, 1.0f); const glm::vec4 red(1.0f, 0.0f, 0.0f, 1.0f);
@ -3086,15 +3090,26 @@ void MyAvatar::postUpdate(float deltaTime, const render::ScenePointer& scene) {
} }
if (_enableDebugDrawAnimPose && animSkeleton) { if (_enableDebugDrawAnimPose && animSkeleton) {
// build absolute AnimPoseVec from rig
AnimPoseVec absPoses; AnimPoseVec absPoses;
const Rig& rig = _skeletonModel->getRig(); const Rig& rig = _skeletonModel->getRig();
const glm::vec4 CYAN(0.1f, 0.6f, 0.6f, 1.0f);
QString name = _debugDrawAnimPoseName.get();
if (name.isEmpty()) {
// build absolute AnimPoseVec from rig transforms. i.e. the same that are used for rendering.
absPoses.reserve(rig.getJointStateCount()); absPoses.reserve(rig.getJointStateCount());
for (int i = 0; i < rig.getJointStateCount(); i++) { for (int i = 0; i < rig.getJointStateCount(); i++) {
absPoses.push_back(AnimPose(rig.getJointTransform(i))); absPoses.push_back(AnimPose(rig.getJointTransform(i)));
} }
glm::vec4 cyan(0.1f, 0.6f, 0.6f, 1.0f); AnimDebugDraw::getInstance().addAbsolutePoses("myAvatarAnimPoses", animSkeleton, absPoses, xform, CYAN);
AnimDebugDraw::getInstance().addAbsolutePoses("myAvatarAnimPoses", animSkeleton, absPoses, xform, cyan); } else {
AnimNode::ConstPointer node = rig.findAnimNodeByName(name);
if (node) {
rig.buildAbsoluteRigPoses(node->getPoses(), absPoses);
AnimDebugDraw::getInstance().addAbsolutePoses("myAvatarAnimPoses", animSkeleton, absPoses, xform, CYAN);
}
}
} }
} }

View file

@ -2018,12 +2018,20 @@ public slots:
void setEnableDebugDrawDefaultPose(bool isEnabled); void setEnableDebugDrawDefaultPose(bool isEnabled);
/**jsdoc /**jsdoc
* Displays animation debug graphics. * Displays animation debug graphics. By default it shows the animation poses used for rendering.
* However, the property MyAvatar.setDebugDrawAnimPoseName can be used to draw a specific animation node.
* @function MyAvatar.setEnableDebugDrawAnimPose * @function MyAvatar.setEnableDebugDrawAnimPose
* @param {boolean} enabled - <code>true</code> to show the debug graphics, <code>false</code> to hide. * @param {boolean} enabled - <code>true</code> to show the debug graphics, <code>false</code> to hide.
*/ */
void setEnableDebugDrawAnimPose(bool isEnabled); void setEnableDebugDrawAnimPose(bool isEnabled);
/**jsdoc
* If set it determines which animation debug graphics to draw, when MyAvatar.setEnableDebugDrawAnimPose is set to true.
* @function MyAvatar.setDebugDrawAnimPoseName
* @param {boolean} enabled - <code>true</code> to show the debug graphics, <code>false</code> to hide.
*/
void setDebugDrawAnimPoseName(QString poseName);
/**jsdoc /**jsdoc
* Displays position debug graphics. * Displays position debug graphics.
* @function MyAvatar.setEnableDebugDrawPosition * @function MyAvatar.setEnableDebugDrawPosition
@ -2666,6 +2674,8 @@ private:
bool _enableDebugDrawIKChains { false }; bool _enableDebugDrawIKChains { false };
bool _enableDebugDrawDetailedCollision { false }; bool _enableDebugDrawDetailedCollision { false };
ThreadSafeValueCache<QString> _debugDrawAnimPoseName;
mutable bool _cauterizationNeedsUpdate { false }; // do we need to scan children and update their "cauterized" state? mutable bool _cauterizationNeedsUpdate { false }; // do we need to scan children and update their "cauterized" state?
AudioListenerMode _audioListenerMode; AudioListenerMode _audioListenerMode;

View file

@ -10,10 +10,13 @@
#include "AnimClip.h" #include "AnimClip.h"
#include <assert.h>
#include "GLMHelpers.h" #include "GLMHelpers.h"
#include "AnimationLogging.h" #include "AnimationLogging.h"
#include "AnimUtil.h" #include "AnimUtil.h"
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),
@ -107,6 +110,19 @@ static std::vector<int> buildJointIndexMap(const AnimSkeleton& dstSkeleton, cons
return jointIndexMap; return jointIndexMap;
} }
#ifdef USE_CUSTOM_ASSERT
#undef ASSERT
#define ASSERT(x) \
do { \
if (!(x)) { \
int* bad_ptr = 0; \
*bad_ptr = 0x0badf00d; \
} \
} while (0)
#else
#define ASSERT assert
#endif
void AnimClip::copyFromNetworkAnim() { void AnimClip::copyFromNetworkAnim() {
assert(_networkAnim && _networkAnim->isLoaded() && _skeleton); assert(_networkAnim && _networkAnim->isLoaded() && _skeleton);
_anim.clear(); _anim.clear();
@ -165,11 +181,14 @@ void AnimClip::copyFromNetworkAnim() {
for (int frame = 0; frame < animFrameCount; frame++) { for (int frame = 0; frame < animFrameCount; frame++) {
const HFMAnimationFrame& animFrame = animModel.animationFrames[frame]; const HFMAnimationFrame& animFrame = animModel.animationFrames[frame];
ASSERT(frame >= 0 && frame < (int)animModel.animationFrames.size());
// extract the full rotations from the animFrame (including pre and post rotations from the animModel). // extract the full rotations from the animFrame (including pre and post rotations from the animModel).
std::vector<glm::quat> animRotations; std::vector<glm::quat> animRotations;
animRotations.reserve(animJointCount); animRotations.reserve(animJointCount);
for (int i = 0; i < animJointCount; i++) { for (int i = 0; i < animJointCount; i++) {
ASSERT(i >= 0 && i < (int)animModel.joints.size());
ASSERT(i >= 0 && i < (int)animFrame.rotations.size());
animRotations.push_back(animModel.joints[i].preRotation * animFrame.rotations[i] * animModel.joints[i].postRotation); animRotations.push_back(animModel.joints[i].preRotation * animFrame.rotations[i] * animModel.joints[i].postRotation);
} }
@ -180,10 +199,12 @@ void AnimClip::copyFromNetworkAnim() {
std::vector<glm::quat> avatarRotations; std::vector<glm::quat> avatarRotations;
avatarRotations.reserve(avatarJointCount); avatarRotations.reserve(avatarJointCount);
for (int avatarJointIndex = 0; avatarJointIndex < avatarJointCount; avatarJointIndex++) { for (int avatarJointIndex = 0; avatarJointIndex < avatarJointCount; avatarJointIndex++) {
ASSERT(avatarJointIndex >= 0 && avatarJointIndex < (int)avatarToAnimJointIndexMap.size());
int animJointIndex = avatarToAnimJointIndexMap[avatarJointIndex]; int animJointIndex = avatarToAnimJointIndexMap[avatarJointIndex];
if (animJointIndex >= 0) { if (animJointIndex >= 0) {
// This joint is in both animation and avatar. // This joint is in both animation and avatar.
// Set the absolute rotation directly // Set the absolute rotation directly
ASSERT(animJointIndex >= 0 && animJointIndex < (int)animRotations.size());
avatarRotations.push_back(animRotations[animJointIndex]); avatarRotations.push_back(animRotations[animJointIndex]);
} else { } else {
// This joint is NOT in the animation at all. // This joint is NOT in the animation at all.
@ -192,6 +213,7 @@ void AnimClip::copyFromNetworkAnim() {
glm::quat avatarParentAbsoluteRot; glm::quat avatarParentAbsoluteRot;
int avatarParentJointIndex = avatarSkeleton->getParentIndex(avatarJointIndex); int avatarParentJointIndex = avatarSkeleton->getParentIndex(avatarJointIndex);
if (avatarParentJointIndex >= 0) { if (avatarParentJointIndex >= 0) {
ASSERT(avatarParentJointIndex >= 0 && avatarParentJointIndex < (int)avatarRotations.size());
avatarParentAbsoluteRot = avatarRotations[avatarParentJointIndex]; avatarParentAbsoluteRot = avatarRotations[avatarParentJointIndex];
} }
avatarRotations.push_back(avatarParentAbsoluteRot * avatarRelativeDefaultRot); avatarRotations.push_back(avatarParentAbsoluteRot * avatarRelativeDefaultRot);
@ -201,6 +223,7 @@ void AnimClip::copyFromNetworkAnim() {
// convert avatar rotations into relative frame // convert avatar rotations into relative frame
avatarSkeleton->convertAbsoluteRotationsToRelative(avatarRotations); avatarSkeleton->convertAbsoluteRotationsToRelative(avatarRotations);
ASSERT(frame >= 0 && frame < (int)_anim.size());
_anim[frame].reserve(avatarJointCount); _anim[frame].reserve(avatarJointCount);
for (int avatarJointIndex = 0; avatarJointIndex < avatarJointCount; avatarJointIndex++) { for (int avatarJointIndex = 0; avatarJointIndex < avatarJointCount; avatarJointIndex++) {
const AnimPose& avatarDefaultPose = avatarSkeleton->getRelativeDefaultPose(avatarJointIndex); const AnimPose& avatarDefaultPose = avatarSkeleton->getRelativeDefaultPose(avatarJointIndex);
@ -209,12 +232,15 @@ void AnimClip::copyFromNetworkAnim() {
glm::vec3 relativeScale = avatarDefaultPose.scale(); glm::vec3 relativeScale = avatarDefaultPose.scale();
glm::vec3 relativeTranslation; glm::vec3 relativeTranslation;
ASSERT(avatarJointIndex >= 0 && avatarJointIndex < (int)avatarToAnimJointIndexMap.size());
int animJointIndex = avatarToAnimJointIndexMap[avatarJointIndex]; int animJointIndex = avatarToAnimJointIndexMap[avatarJointIndex];
if (animJointIndex >= 0) { if (animJointIndex >= 0) {
// This joint is in both animation and avatar. // This joint is in both animation and avatar.
ASSERT(animJointIndex >= 0 && animJointIndex < (int)animFrame.translations.size());
const glm::vec3& animTrans = animFrame.translations[animJointIndex]; const glm::vec3& animTrans = animFrame.translations[animJointIndex];
// retarget translation from animation to avatar // retarget translation from animation to avatar
ASSERT(animJointIndex >= 0 && animJointIndex < (int)animModel.animationFrames[0].translations.size());
const glm::vec3& animZeroTrans = animModel.animationFrames[0].translations[animJointIndex]; const glm::vec3& animZeroTrans = animModel.animationFrames[0].translations[animJointIndex];
relativeTranslation = avatarDefaultPose.trans() + boneLengthScale * (animTrans - animZeroTrans); relativeTranslation = avatarDefaultPose.trans() + boneLengthScale * (animTrans - animZeroTrans);
} else { } else {
@ -224,6 +250,7 @@ void AnimClip::copyFromNetworkAnim() {
} }
// build the final pose // build the final pose
ASSERT(avatarJointIndex >= 0 && avatarJointIndex < (int)avatarRotations.size());
_anim[frame].push_back(AnimPose(relativeScale, avatarRotations[avatarJointIndex], relativeTranslation)); _anim[frame].push_back(AnimPose(relativeScale, avatarRotations[avatarJointIndex], relativeTranslation));
} }
} }

View file

@ -98,6 +98,8 @@ public:
return result; return result;
} }
const AnimPoseVec& getPoses() const { return getPosesInternal(); }
protected: protected:
virtual void setCurrentFrameInternal(float frame) {} virtual void setCurrentFrameInternal(float frame) {}

View file

@ -2232,6 +2232,14 @@ void Rig::initAnimGraph(const QUrl& url) {
} }
} }
AnimNode::ConstPointer Rig::findAnimNodeByName(const QString& name) const {
if (_animNode) {
return _animNode->findByName(name);
} else {
return nullptr;
}
}
bool Rig::getModelRegistrationPoint(glm::vec3& modelRegistrationPointOut) const { bool Rig::getModelRegistrationPoint(glm::vec3& modelRegistrationPointOut) const {
if (_animSkeleton && _rootJointIndex >= 0) { if (_animSkeleton && _rootJointIndex >= 0) {
modelRegistrationPointOut = _geometryOffset * -_animSkeleton->getAbsoluteDefaultPose(_rootJointIndex).trans(); modelRegistrationPointOut = _geometryOffset * -_animSkeleton->getAbsoluteDefaultPose(_rootJointIndex).trans();
@ -2258,7 +2266,7 @@ void Rig::applyOverridePoses() {
} }
} }
void Rig::buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut) { void Rig::buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut) const {
DETAILED_PERFORMANCE_TIMER("buildAbsolute"); DETAILED_PERFORMANCE_TIMER("buildAbsolute");
if (!_animSkeleton) { if (!_animSkeleton) {
return; return;

View file

@ -196,6 +196,7 @@ public:
void initAnimGraph(const QUrl& url); void initAnimGraph(const QUrl& url);
AnimNode::ConstPointer getAnimNode() const { return _animNode; } AnimNode::ConstPointer getAnimNode() const { return _animNode; }
AnimNode::ConstPointer findAnimNodeByName(const QString& name) const;
AnimSkeleton::ConstPointer getAnimSkeleton() const { return _animSkeleton; } AnimSkeleton::ConstPointer getAnimSkeleton() const { return _animSkeleton; }
QScriptValue addAnimationStateHandler(QScriptValue handler, QScriptValue propertiesList); QScriptValue addAnimationStateHandler(QScriptValue handler, QScriptValue propertiesList);
void removeAnimationStateHandler(QScriptValue handler); void removeAnimationStateHandler(QScriptValue handler);
@ -243,7 +244,7 @@ public:
Flow& getFlow() { return _internalFlow; } Flow& getFlow() { return _internalFlow; }
float getUnscaledEyeHeight() const; float getUnscaledEyeHeight() const;
void buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut) const;
signals: signals:
void onLoadComplete(); void onLoadComplete();
@ -252,7 +253,6 @@ protected:
bool isIndexValid(int index) const { return _animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints(); } bool isIndexValid(int index) const { return _animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints(); }
void updateAnimationStateHandlers(); void updateAnimationStateHandlers();
void applyOverridePoses(); void applyOverridePoses();
void buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut);
void updateHead(bool headEnabled, bool hipsEnabled, const AnimPose& headMatrix); void updateHead(bool headEnabled, bool hipsEnabled, const AnimPose& headMatrix);
void updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnabled, bool hipsEstimated, void updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnabled, bool hipsEstimated,

View file

@ -35,16 +35,6 @@ static const double SQRT2 = 1.41421356237309504880;
static const double FIXQ31 = 2147483648.0; static const double FIXQ31 = 2147483648.0;
static const double FIXQ32 = 4294967296.0; static const double FIXQ32 = 4294967296.0;
// Round an integer to the next power-of-two, at compile time.
// VS2013 does not support constexpr so macros are used instead.
#define SETBITS0(x) (x)
#define SETBITS1(x) (SETBITS0(x) | (SETBITS0(x) >> 1))
#define SETBITS2(x) (SETBITS1(x) | (SETBITS1(x) >> 2))
#define SETBITS3(x) (SETBITS2(x) | (SETBITS2(x) >> 4))
#define SETBITS4(x) (SETBITS3(x) | (SETBITS3(x) >> 8))
#define SETBITS5(x) (SETBITS4(x) | (SETBITS4(x) >> 16))
#define NEXTPOW2(x) (SETBITS5((x) - 1) + 1)
// //
// Allpass delay modulation // Allpass delay modulation
// //
@ -111,6 +101,18 @@ static const int M_AP19 = 113;
static const int M_AP20 = 107; static const int M_AP20 = 107;
static const int M_AP21 = 127; static const int M_AP21 = 127;
// Round an integer to the next power-of-two, at compile time
constexpr uint32_t NEXTPOW2(uint32_t n) {
n -= 1;
n |= (n >> 1);
n |= (n >> 2);
n |= (n >> 4);
n |= (n >> 8);
n |= (n >> 16);
n += 1;
return n;
}
// //
// Filter design tools using analog-matched response. // Filter design tools using analog-matched response.
// All filter types approximate the s-plane response, including cutoff > Nyquist. // All filter types approximate the s-plane response, including cutoff > Nyquist.
@ -1796,6 +1798,18 @@ void AudioReverb::render(float** inputs, float** outputs, int numFrames) {
#include <emmintrin.h> #include <emmintrin.h>
// unaligned load/store without undefined behavior
static inline __m128i mm_loadu_si32(void const* mem_addr) {
int32_t temp;
memcpy(&temp, mem_addr, sizeof(int32_t));
return _mm_cvtsi32_si128(temp);
}
static inline void mm_storeu_si32(void* mem_addr, __m128i a) {
int32_t temp = _mm_cvtsi128_si32(a);
memcpy(mem_addr, &temp, sizeof(int32_t));
}
// convert int16_t to float, deinterleave stereo // convert int16_t to float, deinterleave stereo
void AudioReverb::convertInput(const int16_t* input, float** outputs, int numFrames) { void AudioReverb::convertInput(const int16_t* input, float** outputs, int numFrames) {
__m128 scale = _mm_set1_ps(1/32768.0f); __m128 scale = _mm_set1_ps(1/32768.0f);
@ -1816,7 +1830,7 @@ void AudioReverb::convertInput(const int16_t* input, float** outputs, int numFra
_mm_storeu_ps(&outputs[1][i], f1); _mm_storeu_ps(&outputs[1][i], f1);
} }
for (; i < numFrames; i++) { for (; i < numFrames; i++) {
__m128i a0 = _mm_cvtsi32_si128(*(int32_t*)&input[2*i]); __m128i a0 = mm_loadu_si32((__m128i*)&input[2*i]);
__m128i a1 = a0; __m128i a1 = a0;
// deinterleave and sign-extend // deinterleave and sign-extend
@ -1887,7 +1901,7 @@ void AudioReverb::convertOutput(float** inputs, int16_t* output, int numFrames)
// interleave // interleave
a0 = _mm_unpacklo_epi16(a0, a1); a0 = _mm_unpacklo_epi16(a0, a1);
*(int32_t*)&output[2*i] = _mm_cvtsi128_si32(a0); mm_storeu_si32((__m128i*)&output[2*i], a0);
} }
} }

View file

@ -793,6 +793,18 @@ int AudioSRC::multirateFilter4(const float* input0, const float* input1, const f
#include <emmintrin.h> // SSE2 #include <emmintrin.h> // SSE2
// unaligned load/store without undefined behavior
static inline __m128i mm_loadu_si32(void const* mem_addr) {
int32_t temp;
memcpy(&temp, mem_addr, sizeof(int32_t));
return _mm_cvtsi32_si128(temp);
}
static inline void mm_storeu_si32(void* mem_addr, __m128i a) {
int32_t temp = _mm_cvtsi128_si32(a);
memcpy(mem_addr, &temp, sizeof(int32_t));
}
// convert int16_t to float, deinterleave stereo // convert int16_t to float, deinterleave stereo
void AudioSRC::convertInput(const int16_t* input, float** outputs, int numFrames) { void AudioSRC::convertInput(const int16_t* input, float** outputs, int numFrames) {
__m128 scale = _mm_set1_ps(1/32768.0f); __m128 scale = _mm_set1_ps(1/32768.0f);
@ -839,7 +851,7 @@ void AudioSRC::convertInput(const int16_t* input, float** outputs, int numFrames
_mm_storeu_ps(&outputs[1][i], f1); _mm_storeu_ps(&outputs[1][i], f1);
} }
for (; i < numFrames; i++) { for (; i < numFrames; i++) {
__m128i a0 = _mm_cvtsi32_si128(*(int32_t*)&input[2*i]); __m128i a0 = mm_loadu_si32((__m128i*)&input[2*i]);
__m128i a1 = a0; __m128i a1 = a0;
// deinterleave and sign-extend // deinterleave and sign-extend
@ -878,9 +890,9 @@ void AudioSRC::convertInput(const int16_t* input, float** outputs, int numFrames
_mm_storeu_ps(&outputs[3][i], _mm_shuffle_ps(f1, f3, _MM_SHUFFLE(3,1,3,1))); _mm_storeu_ps(&outputs[3][i], _mm_shuffle_ps(f1, f3, _MM_SHUFFLE(3,1,3,1)));
} }
for (; i < numFrames; i++) { for (; i < numFrames; i++) {
__m128i a0 = _mm_cvtsi32_si128(*(int32_t*)&input[4*i+0]); __m128i a0 = mm_loadu_si32((__m128i*)&input[4*i+0]);
__m128i a1 = a0; __m128i a1 = a0;
__m128i a2 = _mm_cvtsi32_si128(*(int32_t*)&input[4*i+2]); __m128i a2 = mm_loadu_si32((__m128i*)&input[4*i+2]);
__m128i a3 = a2; __m128i a3 = a2;
// deinterleave and sign-extend // deinterleave and sign-extend
@ -986,7 +998,7 @@ void AudioSRC::convertOutput(float** inputs, int16_t* output, int numFrames) {
// interleave // interleave
a0 = _mm_unpacklo_epi16(a0, a1); a0 = _mm_unpacklo_epi16(a0, a1);
*(int32_t*)&output[2*i] = _mm_cvtsi128_si32(a0); mm_storeu_si32((__m128i*)&output[2*i], a0);
} }
} else if (_numChannels == 4) { } else if (_numChannels == 4) {

View file

@ -996,7 +996,7 @@ void LimitedNodeList::sendSTUNRequest() {
const int NUM_INITIAL_STUN_REQUESTS_BEFORE_FAIL = 10; const int NUM_INITIAL_STUN_REQUESTS_BEFORE_FAIL = 10;
if (!_hasCompletedInitialSTUN) { if (!_hasCompletedInitialSTUN) {
qCDebug(networking) << "Sending intial stun request to" << STUN_SERVER_HOSTNAME; qCDebug(networking) << "Sending initial stun request to" << STUN_SERVER_HOSTNAME;
if (_numInitialSTUNRequests > NUM_INITIAL_STUN_REQUESTS_BEFORE_FAIL) { if (_numInitialSTUNRequests > NUM_INITIAL_STUN_REQUESTS_BEFORE_FAIL) {
// we're still trying to do our initial STUN we're over the fail threshold // we're still trying to do our initial STUN we're over the fail threshold
@ -1185,7 +1185,7 @@ void LimitedNodeList::stopInitialSTUNUpdate(bool success) {
// We now setup a timer here to fire every so often to check that our IP address has not changed. // We now setup a timer here to fire every so often to check that our IP address has not changed.
// Or, if we failed - if will check if we can eventually get a public socket // Or, if we failed - if will check if we can eventually get a public socket
const int STUN_IP_ADDRESS_CHECK_INTERVAL_MSECS = 30 * 1000; const int STUN_IP_ADDRESS_CHECK_INTERVAL_MSECS = 10 * 1000;
QTimer* stunOccasionalTimer = new QTimer { this }; QTimer* stunOccasionalTimer = new QTimer { this };
connect(stunOccasionalTimer, &QTimer::timeout, this, &LimitedNodeList::sendSTUNRequest); connect(stunOccasionalTimer, &QTimer::timeout, this, &LimitedNodeList::sendSTUNRequest);
@ -1243,15 +1243,22 @@ void LimitedNodeList::errorTestingLocalSocket() {
} }
void LimitedNodeList::setLocalSocket(const HifiSockAddr& sockAddr) { void LimitedNodeList::setLocalSocket(const HifiSockAddr& sockAddr) {
if (sockAddr != _localSockAddr) { if (sockAddr.getAddress() != _localSockAddr.getAddress()) {
if (_localSockAddr.isNull()) { if (_localSockAddr.isNull()) {
qCInfo(networking) << "Local socket is" << sockAddr; qCInfo(networking) << "Local socket is" << sockAddr;
_localSockAddr = sockAddr;
} else { } else {
qCInfo(networking) << "Local socket has changed from" << _localSockAddr << "to" << sockAddr; qCInfo(networking) << "Local socket has changed from" << _localSockAddr << "to" << sockAddr;
_localSockAddr = sockAddr;
if (_hasTCPCheckedLocalSocket) { // Force a port change for NAT:
reset();
_nodeSocket.rebind(0);
_localSockAddr.setPort(_nodeSocket.localPort());
qCInfo(networking) << "Local port changed to" << _localSockAddr.getPort();
}
} }
_localSockAddr = sockAddr;
emit localSockAddrChanged(_localSockAddr); emit localSockAddrChanged(_localSockAddr);
} }
} }

View file

@ -33,6 +33,7 @@ using namespace udt;
Socket::Socket(QObject* parent, bool shouldChangeSocketOptions) : Socket::Socket(QObject* parent, bool shouldChangeSocketOptions) :
QObject(parent), QObject(parent),
_udpSocket(parent),
_readyReadBackupTimer(new QTimer(this)), _readyReadBackupTimer(new QTimer(this)),
_shouldChangeSocketOptions(shouldChangeSocketOptions) _shouldChangeSocketOptions(shouldChangeSocketOptions)
{ {
@ -50,6 +51,7 @@ Socket::Socket(QObject* parent, bool shouldChangeSocketOptions) :
} }
void Socket::bind(const QHostAddress& address, quint16 port) { void Socket::bind(const QHostAddress& address, quint16 port) {
_udpSocket.bind(address, port); _udpSocket.bind(address, port);
if (_shouldChangeSocketOptions) { if (_shouldChangeSocketOptions) {
@ -75,7 +77,7 @@ void Socket::rebind() {
} }
void Socket::rebind(quint16 localPort) { void Socket::rebind(quint16 localPort) {
_udpSocket.close(); _udpSocket.abort();
bind(QHostAddress::AnyIPv4, localPort); bind(QHostAddress::AnyIPv4, localPort);
} }

View file

@ -37,7 +37,6 @@ void packDeferredFragment(vec3 normal, float alpha, vec3 albedo, float roughness
_fragColor0 = vec4(albedo, mix(packShadedMetallic(metallic), packScatteringMetallic(metallic), check)); _fragColor0 = vec4(albedo, mix(packShadedMetallic(metallic), packScatteringMetallic(metallic), check));
_fragColor1 = vec4(packNormal(normal), clamp(roughness, 0.0, 1.0)); _fragColor1 = vec4(packNormal(normal), clamp(roughness, 0.0, 1.0));
_fragColor2 = vec4(mix(emissive, vec3(scattering), check), occlusion); _fragColor2 = vec4(mix(emissive, vec3(scattering), check), occlusion);
_fragColor3 = vec4(isEmissiveEnabled() * emissive, 1.0); _fragColor3 = vec4(isEmissiveEnabled() * emissive, 1.0);
} }
@ -49,7 +48,6 @@ void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 albedo, float r
_fragColor0 = vec4(albedo, packLightmappedMetallic(metallic)); _fragColor0 = vec4(albedo, packLightmappedMetallic(metallic));
_fragColor1 = vec4(packNormal(normal), clamp(roughness, 0.0, 1.0)); _fragColor1 = vec4(packNormal(normal), clamp(roughness, 0.0, 1.0));
_fragColor2 = vec4(isLightmapEnabled() * lightmap, 1.0); _fragColor2 = vec4(isLightmapEnabled() * lightmap, 1.0);
_fragColor3 = vec4(isLightmapEnabled() * lightmap * albedo, 1.0); _fragColor3 = vec4(isLightmapEnabled() * lightmap * albedo, 1.0);
} }
@ -59,7 +57,7 @@ void packDeferredFragmentUnlit(vec3 normal, float alpha, vec3 color) {
} }
_fragColor0 = vec4(color, packUnlit()); _fragColor0 = vec4(color, packUnlit());
_fragColor1 = vec4(packNormal(normal), 1.0); _fragColor1 = vec4(packNormal(normal), 1.0);
// _fragColor2 = vec4(vec3(0.0), 1.0); _fragColor2 = vec4(vec3(0.0), 1.0);
_fragColor3 = vec4(color, 1.0); _fragColor3 = vec4(color, 1.0);
} }
@ -69,7 +67,8 @@ void packDeferredFragmentTranslucent(vec3 normal, float alpha, vec3 albedo, floa
} }
_fragColor0 = vec4(albedo.rgb, alpha); _fragColor0 = vec4(albedo.rgb, alpha);
_fragColor1 = vec4(packNormal(normal), clamp(roughness, 0.0, 1.0)); _fragColor1 = vec4(packNormal(normal), clamp(roughness, 0.0, 1.0));
_fragColor2 = vec4(vec3(0.0), 1.0);
_fragColor3 = vec4(0.0);
} }
<@endif@> <@endif@>

View file

@ -41,33 +41,17 @@ namespace gr {
using namespace render; using namespace render;
struct LightLocations { static void loadLightProgram(int programId, bool lightVolume, gpu::PipelinePointer& program);
bool shadowTransform{ false };
void initialize(const gpu::ShaderPointer& program) {
shadowTransform = program->getReflection().validUniformBuffer(ru::Buffer::ShadowParams);
}
};
static void loadLightProgram(int programId, bool lightVolume, gpu::PipelinePointer& program, LightLocationsPtr& locations);
void DeferredLightingEffect::init() { void DeferredLightingEffect::init() {
_directionalAmbientSphereLightLocations = std::make_shared<LightLocations>(); loadLightProgram(shader::render_utils::program::directional_ambient_light, false, _directionalAmbientSphereLight);
_directionalSkyboxLightLocations = std::make_shared<LightLocations>(); loadLightProgram(shader::render_utils::program::directional_skybox_light, false, _directionalSkyboxLight);
_directionalAmbientSphereLightShadowLocations = std::make_shared<LightLocations>(); loadLightProgram(shader::render_utils::program::directional_ambient_light_shadow, false, _directionalAmbientSphereLightShadow);
_directionalSkyboxLightShadowLocations = std::make_shared<LightLocations>(); loadLightProgram(shader::render_utils::program::directional_skybox_light_shadow, false, _directionalSkyboxLightShadow);
_localLightLocations = std::make_shared<LightLocations>(); loadLightProgram(shader::render_utils::program::local_lights_shading, true, _localLight);
_localLightOutlineLocations = std::make_shared<LightLocations>(); loadLightProgram(shader::render_utils::program::local_lights_drawOutline, true, _localLightOutline);
loadLightProgram(shader::render_utils::program::directional_ambient_light, false, _directionalAmbientSphereLight, _directionalAmbientSphereLightLocations);
loadLightProgram(shader::render_utils::program::directional_skybox_light, false, _directionalSkyboxLight, _directionalSkyboxLightLocations);
loadLightProgram(shader::render_utils::program::directional_ambient_light_shadow, false, _directionalAmbientSphereLightShadow, _directionalAmbientSphereLightShadowLocations);
loadLightProgram(shader::render_utils::program::directional_skybox_light_shadow, false, _directionalSkyboxLightShadow, _directionalSkyboxLightShadowLocations);
loadLightProgram(shader::render_utils::program::local_lights_shading, true, _localLight, _localLightLocations);
loadLightProgram(shader::render_utils::program::local_lights_drawOutline, true, _localLightOutline, _localLightOutlineLocations);
} }
// FIXME: figure out how to move lightFrame into a varying in GeometryCache and RenderPipelines // FIXME: figure out how to move lightFrame into a varying in GeometryCache and RenderPipelines
@ -123,15 +107,9 @@ void DeferredLightingEffect::unsetLocalLightsBatch(gpu::Batch& batch) {
batch.setUniformBuffer(ru::Buffer::LightClusterFrustumGrid, nullptr); batch.setUniformBuffer(ru::Buffer::LightClusterFrustumGrid, nullptr);
} }
static gpu::ShaderPointer makeLightProgram(int programId, LightLocationsPtr& locations) { static void loadLightProgram(int programId, bool lightVolume, gpu::PipelinePointer& pipeline) {
gpu::ShaderPointer program = gpu::Shader::createProgram(programId); gpu::ShaderPointer program = gpu::Shader::createProgram(programId);
locations->initialize(program);
return program;
}
static void loadLightProgram(int programId, bool lightVolume, gpu::PipelinePointer& pipeline, LightLocationsPtr& locations) {
gpu::ShaderPointer program = makeLightProgram(programId, locations);
auto state = std::make_shared<gpu::State>(); auto state = std::make_shared<gpu::State>();
state->setColorWriteMask(true, true, true, false); state->setColorWriteMask(true, true, true, false);
@ -456,7 +434,6 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
// Setup the global directional pass pipeline // Setup the global directional pass pipeline
auto program = deferredLightingEffect->_directionalSkyboxLight; auto program = deferredLightingEffect->_directionalSkyboxLight;
LightLocationsPtr locations = deferredLightingEffect->_directionalSkyboxLightLocations;
{ {
if (keyLightCastShadows) { if (keyLightCastShadows) {
@ -464,20 +441,16 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
// otherwise use the ambient sphere version // otherwise use the ambient sphere version
if (hasAmbientMap) { if (hasAmbientMap) {
program = deferredLightingEffect->_directionalSkyboxLightShadow; program = deferredLightingEffect->_directionalSkyboxLightShadow;
locations = deferredLightingEffect->_directionalSkyboxLightShadowLocations;
} else { } else {
program = deferredLightingEffect->_directionalAmbientSphereLightShadow; program = deferredLightingEffect->_directionalAmbientSphereLightShadow;
locations = deferredLightingEffect->_directionalAmbientSphereLightShadowLocations;
} }
} else { } else {
// If the keylight has an ambient Map then use the Skybox version of the pass // If the keylight has an ambient Map then use the Skybox version of the pass
// otherwise use the ambient sphere version // otherwise use the ambient sphere version
if (hasAmbientMap) { if (hasAmbientMap) {
program = deferredLightingEffect->_directionalSkyboxLight; program = deferredLightingEffect->_directionalSkyboxLight;
locations = deferredLightingEffect->_directionalSkyboxLightLocations;
} else { } else {
program = deferredLightingEffect->_directionalAmbientSphereLight; program = deferredLightingEffect->_directionalAmbientSphereLight;
locations = deferredLightingEffect->_directionalAmbientSphereLightLocations;
} }
} }

View file

@ -37,10 +37,6 @@
#include "SubsurfaceScattering.h" #include "SubsurfaceScattering.h"
#include "AmbientOcclusionEffect.h" #include "AmbientOcclusionEffect.h"
struct LightLocations;
using LightLocationsPtr = std::shared_ptr<LightLocations>;
// THis is where we currently accumulate the local lights, let s change that sooner than later // THis is where we currently accumulate the local lights, let s change that sooner than later
class DeferredLightingEffect : public Dependency { class DeferredLightingEffect : public Dependency {
SINGLETON_DEPENDENCY SINGLETON_DEPENDENCY
@ -72,15 +68,6 @@ private:
gpu::PipelinePointer _localLight; gpu::PipelinePointer _localLight;
gpu::PipelinePointer _localLightOutline; gpu::PipelinePointer _localLightOutline;
LightLocationsPtr _directionalSkyboxLightLocations;
LightLocationsPtr _directionalAmbientSphereLightLocations;
LightLocationsPtr _directionalSkyboxLightShadowLocations;
LightLocationsPtr _directionalAmbientSphereLightShadowLocations;
LightLocationsPtr _localLightLocations;
LightLocationsPtr _localLightOutlineLocations;
friend class LightClusteringPass; friend class LightClusteringPass;
friend class RenderDeferredSetup; friend class RenderDeferredSetup;
friend class RenderDeferredLocals; friend class RenderDeferredLocals;

View file

@ -18,7 +18,7 @@ layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01;
void main(void) { void main(void) {
const float depth = 1.0; const float depth = 1.0;
const vec4 UNIT_QUAD[4] = vec4[4]( const mat4 UNIT_QUAD = mat4(
vec4(-1.0, -1.0, depth, 1.0), vec4(-1.0, -1.0, depth, 1.0),
vec4(1.0, -1.0, depth, 1.0), vec4(1.0, -1.0, depth, 1.0),
vec4(-1.0, 1.0, depth, 1.0), vec4(-1.0, 1.0, depth, 1.0),
@ -26,7 +26,7 @@ void main(void) {
); );
vec4 pos = UNIT_QUAD[gl_VertexID]; vec4 pos = UNIT_QUAD[gl_VertexID];
_texCoord01.xy = (pos.xy + 1.0) * 0.5; _texCoord01 = vec4((pos.xy + 1.0) * 0.5, 0.0, 0.0);
gl_Position = pos; gl_Position = pos;
} }

View file

@ -115,48 +115,39 @@ protected:
const Lambda _triggerHandler; const Lambda _triggerHandler;
}; };
class BoolPreference : public Preference {
Q_OBJECT
Q_PROPERTY(bool value READ getValue WRITE setValue NOTIFY valueChanged)
template <typename T>
class TypedPreference : public Preference {
public: public:
using Getter = std::function<T()>; using Getter = std::function<bool()>;
using Setter = std::function<void(const T&)>; using Setter = std::function<void(const bool&)>;
TypedPreference(const QString& category, const QString& name, Getter getter, Setter setter) BoolPreference(const QString& category, const QString& name, Getter getter, Setter setter)
: Preference(category, name), _getter(getter), _setter(setter) { } : Preference(category, name), _getter(getter), _setter(setter) { }
T getValue() const { return _value; } bool getValue() const { return _value; }
void setValue(const T& value) { if (_value != value) { _value = value; emitValueChanged(); } } void setValue(const bool& value) { if (_value != value) { _value = value; emitValueChanged(); } }
void load() override { _value = _getter(); } void load() override { _value = _getter(); }
void save() const override { void save() const override {
T oldValue = _getter(); bool oldValue = _getter();
if (_value != oldValue) { if (_value != oldValue) {
_setter(_value); _setter(_value);
} }
} }
protected:
T _value;
const Getter _getter;
const Setter _setter;
};
class BoolPreference : public TypedPreference<bool> {
Q_OBJECT
Q_PROPERTY(bool value READ getValue WRITE setValue NOTIFY valueChanged)
public:
BoolPreference(const QString& category, const QString& name, Getter getter, Setter setter)
: TypedPreference(category, name, getter, setter) { }
signals: signals:
void valueChanged(); void valueChanged();
protected: protected:
bool _value;
const Getter _getter;
const Setter _setter;
void emitValueChanged() override { emit valueChanged(); } void emitValueChanged() override { emit valueChanged(); }
}; };
class FloatPreference : public TypedPreference<float> { class FloatPreference : public Preference {
Q_OBJECT Q_OBJECT
Q_PROPERTY(float value READ getValue WRITE setValue NOTIFY valueChanged) Q_PROPERTY(float value READ getValue WRITE setValue NOTIFY valueChanged)
Q_PROPERTY(float min READ getMin CONSTANT) Q_PROPERTY(float min READ getMin CONSTANT)
@ -165,8 +156,21 @@ class FloatPreference : public TypedPreference<float> {
Q_PROPERTY(float decimals READ getDecimals CONSTANT) Q_PROPERTY(float decimals READ getDecimals CONSTANT)
public: public:
using Getter = std::function<float()>;
using Setter = std::function<void(const float&)>;
FloatPreference(const QString& category, const QString& name, Getter getter, Setter setter) FloatPreference(const QString& category, const QString& name, Getter getter, Setter setter)
: TypedPreference(category, name, getter, setter) { } : Preference(category, name), _getter(getter), _setter(setter) { }
float getValue() const { return _value; }
void setValue(const float& value) { if (_value != value) { _value = value; emitValueChanged(); } }
void load() override { _value = _getter(); }
void save() const override {
float oldValue = _getter();
if (_value != oldValue) {
_setter(_value);
}
}
float getMin() const { return _min; } float getMin() const { return _min; }
void setMin(float min) { _min = min; }; void setMin(float min) { _min = min; };
@ -186,14 +190,17 @@ signals:
protected: protected:
void emitValueChanged() override { emit valueChanged(); } void emitValueChanged() override { emit valueChanged(); }
float _value;
const Getter _getter;
const Setter _setter;
float _decimals { 0 }; float _decimals { 0 };
float _min { 0 }; float _min { 0 };
float _max { 1 }; float _max { 1 };
float _step { 0.1f }; float _step { 0.1f };
}; };
class IntPreference : public Preference {
class IntPreference : public TypedPreference<int> {
Q_OBJECT Q_OBJECT
Q_PROPERTY(float value READ getValue WRITE setValue NOTIFY valueChanged) Q_PROPERTY(float value READ getValue WRITE setValue NOTIFY valueChanged)
Q_PROPERTY(float min READ getMin CONSTANT) Q_PROPERTY(float min READ getMin CONSTANT)
@ -202,8 +209,21 @@ class IntPreference : public TypedPreference<int> {
Q_PROPERTY(int decimals READ getDecimals CONSTANT) Q_PROPERTY(int decimals READ getDecimals CONSTANT)
public: public:
using Getter = std::function<int()>;
using Setter = std::function<void(const int&)>;
IntPreference(const QString& category, const QString& name, Getter getter, Setter setter) IntPreference(const QString& category, const QString& name, Getter getter, Setter setter)
: TypedPreference(category, name, getter, setter) { } : Preference(category, name), _getter(getter), _setter(setter) { }
int getValue() const { return _value; }
void setValue(const int& value) { if (_value != value) { _value = value; emitValueChanged(); } }
void load() override { _value = _getter(); }
void save() const override {
int oldValue = _getter();
if (_value != oldValue) {
_setter(_value);
}
}
float getMin() const { return _min; } float getMin() const { return _min; }
void setMin(float min) { _min = min; }; void setMin(float min) { _min = min; };
@ -221,6 +241,10 @@ signals:
void valueChanged(); void valueChanged();
protected: protected:
int _value;
const Getter _getter;
const Setter _setter;
void emitValueChanged() override { emit valueChanged(); } void emitValueChanged() override { emit valueChanged(); }
int _min { std::numeric_limits<int>::min() }; int _min { std::numeric_limits<int>::min() };
@ -229,19 +253,37 @@ protected:
int _decimals { 0 }; int _decimals { 0 };
}; };
class StringPreference : public TypedPreference<QString> { class StringPreference : public Preference {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QString value READ getValue WRITE setValue NOTIFY valueChanged) Q_PROPERTY(QString value READ getValue WRITE setValue NOTIFY valueChanged)
public: public:
using Getter = std::function<QString()>;
using Setter = std::function<void(const QString&)>;
StringPreference(const QString& category, const QString& name, Getter getter, Setter setter) StringPreference(const QString& category, const QString& name, Getter getter, Setter setter)
: TypedPreference(category, name, getter, setter) { } : Preference(category, name), _getter(getter), _setter(setter) { }
QString getValue() const { return _value; }
void setValue(const QString& value) { if (_value != value) { _value = value; emitValueChanged(); } }
void load() override { _value = _getter(); }
void save() const override {
QString oldValue = _getter();
if (_value != oldValue) {
_setter(_value);
}
}
signals: signals:
void valueChanged(); void valueChanged();
protected: protected:
void emitValueChanged() override { emit valueChanged(); } void emitValueChanged() override { emit valueChanged(); }
QString _value;
const Getter _getter;
const Setter _setter;
}; };
class SliderPreference : public FloatPreference { class SliderPreference : public FloatPreference {
@ -342,6 +384,9 @@ class CheckPreference : public BoolPreference {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool indented READ getIndented CONSTANT) Q_PROPERTY(bool indented READ getIndented CONSTANT)
public: public:
using Getter = std::function<bool()>;
using Setter = std::function<void(const bool&)>;
CheckPreference(const QString& category, const QString& name, Getter getter, Setter setter) CheckPreference(const QString& category, const QString& name, Getter getter, Setter setter)
: BoolPreference(category, name, getter, setter) { } : BoolPreference(category, name, getter, setter) { }
Type getType() override { return Checkbox; } Type getType() override { return Checkbox; }