mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 07:37:20 +02:00
Merge branch 'master' of github.com:highfidelity/hifi into nut
This commit is contained in:
commit
32399997b1
35 changed files with 493 additions and 221 deletions
|
@ -25,7 +25,6 @@ OriginalDesktop.Desktop {
|
||||||
|
|
||||||
Action {
|
Action {
|
||||||
text: "Open Browser"
|
text: "Open Browser"
|
||||||
shortcut: "Ctrl+B"
|
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
console.log("Open browser");
|
console.log("Open browser");
|
||||||
browserBuilder.createObject(desktop);
|
browserBuilder.createObject(desktop);
|
||||||
|
|
|
@ -49,7 +49,10 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
function pushSource(path) {
|
function pushSource(path) {
|
||||||
d.push(Qt.resolvedUrl("../../" + path));
|
// Workaround issue https://bugreports.qt.io/browse/QTBUG-75516 in Qt 5.12.3
|
||||||
|
// by creating the manually, instead of letting StackView do it for us.
|
||||||
|
var item = Qt.createComponent(Qt.resolvedUrl("../../" + path));
|
||||||
|
d.push(item);
|
||||||
if (d.currentItem.sendToScript !== undefined) {
|
if (d.currentItem.sendToScript !== undefined) {
|
||||||
d.currentItem.sendToScript.connect(tabletMenu.sendToScript);
|
d.currentItem.sendToScript.connect(tabletMenu.sendToScript);
|
||||||
}
|
}
|
||||||
|
|
|
@ -867,7 +867,11 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) {
|
||||||
DependencyManager::set<ScriptCache>();
|
DependencyManager::set<ScriptCache>();
|
||||||
DependencyManager::set<SoundCache>();
|
DependencyManager::set<SoundCache>();
|
||||||
DependencyManager::set<SoundCacheScriptingInterface>();
|
DependencyManager::set<SoundCacheScriptingInterface>();
|
||||||
|
|
||||||
|
#ifdef HAVE_DDE
|
||||||
DependencyManager::set<DdeFaceTracker>();
|
DependencyManager::set<DdeFaceTracker>();
|
||||||
|
#endif
|
||||||
|
|
||||||
DependencyManager::set<EyeTracker>();
|
DependencyManager::set<EyeTracker>();
|
||||||
DependencyManager::set<AudioClient>();
|
DependencyManager::set<AudioClient>();
|
||||||
DependencyManager::set<AudioScope>();
|
DependencyManager::set<AudioScope>();
|
||||||
|
@ -2759,7 +2763,6 @@ void Application::cleanupBeforeQuit() {
|
||||||
// this must happen after QML, as there are unexplained audio crashes originating in qtwebengine
|
// this must happen after QML, as there are unexplained audio crashes originating in qtwebengine
|
||||||
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "stop");
|
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "stop");
|
||||||
DependencyManager::destroy<AudioClient>();
|
DependencyManager::destroy<AudioClient>();
|
||||||
DependencyManager::destroy<AudioInjectorManager>();
|
|
||||||
DependencyManager::destroy<AudioScriptingInterface>();
|
DependencyManager::destroy<AudioScriptingInterface>();
|
||||||
|
|
||||||
// The PointerManager must be destroyed before the PickManager because when a Pointer is deleted,
|
// The PointerManager must be destroyed before the PickManager because when a Pointer is deleted,
|
||||||
|
@ -2819,6 +2822,7 @@ Application::~Application() {
|
||||||
|
|
||||||
DependencyManager::destroy<SoundCacheScriptingInterface>();
|
DependencyManager::destroy<SoundCacheScriptingInterface>();
|
||||||
|
|
||||||
|
DependencyManager::destroy<AudioInjectorManager>();
|
||||||
DependencyManager::destroy<AvatarManager>();
|
DependencyManager::destroy<AvatarManager>();
|
||||||
DependencyManager::destroy<AnimationCacheScriptingInterface>();
|
DependencyManager::destroy<AnimationCacheScriptingInterface>();
|
||||||
DependencyManager::destroy<AnimationCache>();
|
DependencyManager::destroy<AnimationCache>();
|
||||||
|
@ -3324,7 +3328,9 @@ void Application::onDesktopRootContextCreated(QQmlContext* surfaceContext) {
|
||||||
surfaceContext->setContextProperty("AccountServices", AccountServicesScriptingInterface::getInstance());
|
surfaceContext->setContextProperty("AccountServices", AccountServicesScriptingInterface::getInstance());
|
||||||
|
|
||||||
surfaceContext->setContextProperty("DialogsManager", _dialogsManagerScriptingInterface);
|
surfaceContext->setContextProperty("DialogsManager", _dialogsManagerScriptingInterface);
|
||||||
|
#ifdef HAVE_DDE
|
||||||
surfaceContext->setContextProperty("FaceTracker", DependencyManager::get<DdeFaceTracker>().data());
|
surfaceContext->setContextProperty("FaceTracker", DependencyManager::get<DdeFaceTracker>().data());
|
||||||
|
#endif
|
||||||
surfaceContext->setContextProperty("AvatarManager", DependencyManager::get<AvatarManager>().data());
|
surfaceContext->setContextProperty("AvatarManager", DependencyManager::get<AvatarManager>().data());
|
||||||
surfaceContext->setContextProperty("LODManager", DependencyManager::get<LODManager>().data());
|
surfaceContext->setContextProperty("LODManager", DependencyManager::get<LODManager>().data());
|
||||||
surfaceContext->setContextProperty("HMD", DependencyManager::get<HMDScriptingInterface>().data());
|
surfaceContext->setContextProperty("HMD", DependencyManager::get<HMDScriptingInterface>().data());
|
||||||
|
@ -4303,10 +4309,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::Key_B:
|
case Qt::Key_B:
|
||||||
if (isMeta) {
|
if (isOption) {
|
||||||
auto offscreenUi = getOffscreenUI();
|
|
||||||
offscreenUi->load("Browser.qml");
|
|
||||||
} else if (isOption) {
|
|
||||||
controller::InputRecorder* inputRecorder = controller::InputRecorder::getInstance();
|
controller::InputRecorder* inputRecorder = controller::InputRecorder::getInstance();
|
||||||
inputRecorder->stopPlayback();
|
inputRecorder->stopPlayback();
|
||||||
}
|
}
|
||||||
|
@ -4345,12 +4348,6 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::Key_N:
|
|
||||||
if (!isOption && !isShifted && isMeta) {
|
|
||||||
DependencyManager::get<NodeList>()->toggleIgnoreRadius();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Qt::Key_S:
|
case Qt::Key_S:
|
||||||
if (isShifted && isMeta && !isOption) {
|
if (isShifted && isMeta && !isOption) {
|
||||||
Menu::getInstance()->triggerOption(MenuOption::SuppressShortTimings);
|
Menu::getInstance()->triggerOption(MenuOption::SuppressShortTimings);
|
||||||
|
@ -5174,9 +5171,15 @@ ivec2 Application::getMouse() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
FaceTracker* Application::getActiveFaceTracker() {
|
FaceTracker* Application::getActiveFaceTracker() {
|
||||||
|
#ifdef HAVE_DDE
|
||||||
auto dde = DependencyManager::get<DdeFaceTracker>();
|
auto dde = DependencyManager::get<DdeFaceTracker>();
|
||||||
|
|
||||||
return dde->isActive() ? static_cast<FaceTracker*>(dde.data()) : nullptr;
|
if (dde && dde->isActive()) {
|
||||||
|
return static_cast<FaceTracker*>(dde.data());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
FaceTracker* Application::getSelectedFaceTracker() {
|
FaceTracker* Application::getSelectedFaceTracker() {
|
||||||
|
@ -7010,7 +7013,10 @@ void Application::copyDisplayViewFrustum(ViewFrustum& viewOut) const {
|
||||||
// feature. However, we still use this to reset face trackers, eye trackers, audio and to optionally re-load the avatar
|
// feature. However, we still use this to reset face trackers, eye trackers, audio and to optionally re-load the avatar
|
||||||
// rig and animations from scratch.
|
// rig and animations from scratch.
|
||||||
void Application::resetSensors(bool andReload) {
|
void Application::resetSensors(bool andReload) {
|
||||||
|
#ifdef HAVE_DDE
|
||||||
DependencyManager::get<DdeFaceTracker>()->reset();
|
DependencyManager::get<DdeFaceTracker>()->reset();
|
||||||
|
#endif
|
||||||
|
|
||||||
DependencyManager::get<EyeTracker>()->reset();
|
DependencyManager::get<EyeTracker>()->reset();
|
||||||
_overlayConductor.centerUI();
|
_overlayConductor.centerUI();
|
||||||
getActiveDisplayPlugin()->resetSensors();
|
getActiveDisplayPlugin()->resetSensors();
|
||||||
|
@ -7214,7 +7220,7 @@ void Application::nodeKilled(SharedNodePointer node) {
|
||||||
_octreeProcessor.nodeKilled(node);
|
_octreeProcessor.nodeKilled(node);
|
||||||
|
|
||||||
_entityEditSender.nodeKilled(node);
|
_entityEditSender.nodeKilled(node);
|
||||||
|
|
||||||
if (node->getType() == NodeType::AudioMixer) {
|
if (node->getType() == NodeType::AudioMixer) {
|
||||||
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "audioMixerKilled");
|
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "audioMixerKilled");
|
||||||
} else if (node->getType() == NodeType::EntityServer) {
|
} else if (node->getType() == NodeType::EntityServer) {
|
||||||
|
@ -7402,8 +7408,10 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe
|
||||||
scriptEngine->registerGlobalObject("AccountServices", AccountServicesScriptingInterface::getInstance());
|
scriptEngine->registerGlobalObject("AccountServices", AccountServicesScriptingInterface::getInstance());
|
||||||
qScriptRegisterMetaType(scriptEngine.data(), DownloadInfoResultToScriptValue, DownloadInfoResultFromScriptValue);
|
qScriptRegisterMetaType(scriptEngine.data(), DownloadInfoResultToScriptValue, DownloadInfoResultFromScriptValue);
|
||||||
|
|
||||||
|
#ifdef HAVE_DDE
|
||||||
scriptEngine->registerGlobalObject("FaceTracker", DependencyManager::get<DdeFaceTracker>().data());
|
scriptEngine->registerGlobalObject("FaceTracker", DependencyManager::get<DdeFaceTracker>().data());
|
||||||
|
#endif
|
||||||
|
|
||||||
scriptEngine->registerGlobalObject("AvatarManager", DependencyManager::get<AvatarManager>().data());
|
scriptEngine->registerGlobalObject("AvatarManager", DependencyManager::get<AvatarManager>().data());
|
||||||
|
|
||||||
scriptEngine->registerGlobalObject("LODManager", DependencyManager::get<LODManager>().data());
|
scriptEngine->registerGlobalObject("LODManager", DependencyManager::get<LODManager>().data());
|
||||||
|
|
|
@ -4947,35 +4947,55 @@ void MyAvatar::setWalkSpeed(float value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::setWalkBackwardSpeed(float value) {
|
void MyAvatar::setWalkBackwardSpeed(float value) {
|
||||||
|
bool changed = true;
|
||||||
|
float prevVal;
|
||||||
switch (_controlSchemeIndex) {
|
switch (_controlSchemeIndex) {
|
||||||
case LocomotionControlsMode::CONTROLS_DEFAULT:
|
case LocomotionControlsMode::CONTROLS_DEFAULT:
|
||||||
|
prevVal = _defaultWalkBackwardSpeed.get();
|
||||||
_defaultWalkBackwardSpeed.set(value);
|
_defaultWalkBackwardSpeed.set(value);
|
||||||
break;
|
break;
|
||||||
case LocomotionControlsMode::CONTROLS_ANALOG:
|
case LocomotionControlsMode::CONTROLS_ANALOG:
|
||||||
|
prevVal = _analogWalkBackwardSpeed.get();
|
||||||
_analogWalkBackwardSpeed.set(value);
|
_analogWalkBackwardSpeed.set(value);
|
||||||
break;
|
break;
|
||||||
case LocomotionControlsMode::CONTROLS_ANALOG_PLUS:
|
case LocomotionControlsMode::CONTROLS_ANALOG_PLUS:
|
||||||
|
prevVal = _analogPlusWalkBackwardSpeed.get();
|
||||||
_analogPlusWalkBackwardSpeed.set(value);
|
_analogPlusWalkBackwardSpeed.set(value);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
changed = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (changed && prevVal != value) {
|
||||||
|
emit walkBackwardSpeedChanged(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::setSprintSpeed(float value) {
|
void MyAvatar::setSprintSpeed(float value) {
|
||||||
|
bool changed = true;
|
||||||
|
float prevVal;
|
||||||
switch (_controlSchemeIndex) {
|
switch (_controlSchemeIndex) {
|
||||||
case LocomotionControlsMode::CONTROLS_DEFAULT:
|
case LocomotionControlsMode::CONTROLS_DEFAULT:
|
||||||
|
prevVal = _defaultSprintSpeed.get();
|
||||||
_defaultSprintSpeed.set(value);
|
_defaultSprintSpeed.set(value);
|
||||||
break;
|
break;
|
||||||
case LocomotionControlsMode::CONTROLS_ANALOG:
|
case LocomotionControlsMode::CONTROLS_ANALOG:
|
||||||
|
prevVal = _analogSprintSpeed.get();
|
||||||
_analogSprintSpeed.set(value);
|
_analogSprintSpeed.set(value);
|
||||||
break;
|
break;
|
||||||
case LocomotionControlsMode::CONTROLS_ANALOG_PLUS:
|
case LocomotionControlsMode::CONTROLS_ANALOG_PLUS:
|
||||||
|
prevVal = _analogPlusSprintSpeed.get();
|
||||||
_analogPlusSprintSpeed.set(value);
|
_analogPlusSprintSpeed.set(value);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
changed = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (changed && prevVal != value) {
|
||||||
|
emit analogPlusSprintSpeedChanged(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float MyAvatar::getSprintSpeed() const {
|
float MyAvatar::getSprintSpeed() const {
|
||||||
|
@ -5013,9 +5033,12 @@ float MyAvatar::getAnalogSprintSpeed() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::setAnalogPlusWalkSpeed(float value) {
|
void MyAvatar::setAnalogPlusWalkSpeed(float value) {
|
||||||
_analogPlusWalkSpeed.set(value);
|
if (_analogPlusWalkSpeed.get() != value) {
|
||||||
// Sprint speed for Analog Plus should be double walk speed.
|
_analogPlusWalkSpeed.set(value);
|
||||||
_analogPlusSprintSpeed.set(value * 2.0f);
|
emit analogPlusWalkSpeedChanged(value);
|
||||||
|
// Sprint speed for Analog Plus should be double walk speed.
|
||||||
|
_analogPlusSprintSpeed.set(value * 2.0f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float MyAvatar::getAnalogPlusWalkSpeed() const {
|
float MyAvatar::getAnalogPlusWalkSpeed() const {
|
||||||
|
@ -5023,7 +5046,10 @@ float MyAvatar::getAnalogPlusWalkSpeed() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::setAnalogPlusSprintSpeed(float value) {
|
void MyAvatar::setAnalogPlusSprintSpeed(float value) {
|
||||||
_analogPlusSprintSpeed.set(value);
|
if (_analogPlusSprintSpeed.get() != value) {
|
||||||
|
_analogPlusSprintSpeed.set(value);
|
||||||
|
emit analogPlusSprintSpeedChanged(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float MyAvatar::getAnalogPlusSprintSpeed() const {
|
float MyAvatar::getAnalogPlusSprintSpeed() const {
|
||||||
|
|
|
@ -370,10 +370,10 @@ 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);
|
Q_PROPERTY(float walkSpeed READ getWalkSpeed WRITE setWalkSpeed);
|
||||||
Q_PROPERTY(float analogPlusWalkSpeed READ getAnalogPlusWalkSpeed WRITE setAnalogPlusWalkSpeed);
|
Q_PROPERTY(float analogPlusWalkSpeed READ getAnalogPlusWalkSpeed WRITE setAnalogPlusWalkSpeed NOTIFY analogPlusWalkSpeedChanged);
|
||||||
Q_PROPERTY(float analogPlusSprintSpeed READ getAnalogPlusSprintSpeed WRITE setAnalogPlusSprintSpeed);
|
Q_PROPERTY(float analogPlusSprintSpeed READ getAnalogPlusSprintSpeed WRITE setAnalogPlusSprintSpeed NOTIFY analogPlusSprintSpeedChanged);
|
||||||
Q_PROPERTY(float walkBackwardSpeed READ getWalkBackwardSpeed WRITE setWalkBackwardSpeed);
|
Q_PROPERTY(float walkBackwardSpeed READ getWalkBackwardSpeed WRITE setWalkBackwardSpeed NOTIFY walkBackwardSpeedChanged);
|
||||||
Q_PROPERTY(float sprintSpeed READ getSprintSpeed WRITE setSprintSpeed);
|
Q_PROPERTY(float sprintSpeed READ getSprintSpeed WRITE setSprintSpeed NOTIFY sprintSpeedChanged);
|
||||||
Q_PROPERTY(bool isInSittingState READ getIsInSittingState WRITE setIsInSittingState);
|
Q_PROPERTY(bool isInSittingState READ getIsInSittingState WRITE setIsInSittingState);
|
||||||
Q_PROPERTY(MyAvatar::SitStandModelType userRecenterModel READ getUserRecenterModel WRITE setUserRecenterModel);
|
Q_PROPERTY(MyAvatar::SitStandModelType userRecenterModel READ getUserRecenterModel WRITE setUserRecenterModel);
|
||||||
Q_PROPERTY(bool isSitStandStateLocked READ getIsSitStandStateLocked WRITE setIsSitStandStateLocked);
|
Q_PROPERTY(bool isSitStandStateLocked READ getIsSitStandStateLocked WRITE setIsSitStandStateLocked);
|
||||||
|
@ -2161,6 +2161,38 @@ signals:
|
||||||
*/
|
*/
|
||||||
void audioListenerModeChanged();
|
void audioListenerModeChanged();
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Notifies when the analogPlusWalkSpeed value is changed.
|
||||||
|
* @function MyAvatar.analogPlusWalkSpeedChanged
|
||||||
|
* @param {float} value - the new avatar walk speed
|
||||||
|
* @returns {Signal}
|
||||||
|
*/
|
||||||
|
void analogPlusWalkSpeedChanged(float value);
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Notifies when the analogPlusSprintSpeed value is changed.
|
||||||
|
* @function MyAvatar.analogPlusSprintSpeedChanged
|
||||||
|
* @param {float} value - the new avatar sprint speed
|
||||||
|
* @returns {Signal}
|
||||||
|
*/
|
||||||
|
void analogPlusSprintSpeedChanged(float value);
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Notifies when the sprintSpeed value is changed.
|
||||||
|
* @function MyAvatar.sprintSpeedChanged
|
||||||
|
* @param {float} value - the new avatar sprint speed
|
||||||
|
* @returns {Signal}
|
||||||
|
*/
|
||||||
|
void sprintSpeedChanged(float value);
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Notifies when the walkBackwardSpeed value is changed.
|
||||||
|
* @function MyAvatar.walkBackwardSpeedChanged
|
||||||
|
* @param {float} value - the new avatar walk backward speed
|
||||||
|
* @returns {Signal}
|
||||||
|
*/
|
||||||
|
void walkBackwardSpeedChanged(float value);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* @function MyAvatar.transformChanged
|
* @function MyAvatar.transformChanged
|
||||||
* @returns {Signal}
|
* @returns {Signal}
|
||||||
|
|
|
@ -219,7 +219,7 @@ bool OtherAvatar::isInPhysicsSimulation() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OtherAvatar::shouldBeInPhysicsSimulation() const {
|
bool OtherAvatar::shouldBeInPhysicsSimulation() const {
|
||||||
return !isDead() && _workloadRegion < workload::Region::R3;
|
return !isDead() && _workloadRegion <= workload::Region::R3;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OtherAvatar::needsPhysicsUpdate() const {
|
bool OtherAvatar::needsPhysicsUpdate() const {
|
||||||
|
|
|
@ -14,8 +14,9 @@
|
||||||
|
|
||||||
#include <QtCore/QtGlobal>
|
#include <QtCore/QtGlobal>
|
||||||
|
|
||||||
|
//Disabling dde due to random crashes with closing the socket on macos. all the accompanying code is wrapped with the ifdef HAVE_DDE. uncomment the define below to enable
|
||||||
#if defined(Q_OS_WIN) || defined(Q_OS_OSX)
|
#if defined(Q_OS_WIN) || defined(Q_OS_OSX)
|
||||||
#define HAVE_DDE
|
//#define HAVE_DDE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
|
|
@ -80,7 +80,7 @@ public:
|
||||||
|
|
||||||
class AudioInputDeviceList : public AudioDeviceList {
|
class AudioInputDeviceList : public AudioDeviceList {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(bool peakValuesAvailable READ peakValuesAvailable)
|
Q_PROPERTY(bool peakValuesAvailable READ peakValuesAvailable CONSTANT)
|
||||||
Q_PROPERTY(bool peakValuesEnabled READ peakValuesEnabled WRITE setPeakValuesEnabled NOTIFY peakValuesEnabledChanged)
|
Q_PROPERTY(bool peakValuesEnabled READ peakValuesEnabled WRITE setPeakValuesEnabled NOTIFY peakValuesEnabledChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -111,7 +111,7 @@ void setupPreferences() {
|
||||||
auto setter = [](bool value) { qApp->setSettingConstrainToolbarPosition(value); };
|
auto setter = [](bool value) { qApp->setSettingConstrainToolbarPosition(value); };
|
||||||
preferences->addPreference(new CheckPreference(UI_CATEGORY, "Constrain Toolbar Position to Horizontal Center", getter, setter));
|
preferences->addPreference(new CheckPreference(UI_CATEGORY, "Constrain Toolbar Position to Horizontal Center", getter, setter));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto getter = []()->bool { return qApp->getAwayStateWhenFocusLostInVREnabled(); };
|
auto getter = []()->bool { return qApp->getAwayStateWhenFocusLostInVREnabled(); };
|
||||||
auto setter = [](bool value) { qApp->setAwayStateWhenFocusLostInVREnabled(value); };
|
auto setter = [](bool value) { qApp->setAwayStateWhenFocusLostInVREnabled(value); };
|
||||||
|
@ -231,7 +231,7 @@ void setupPreferences() {
|
||||||
"installation and system details, and crash events. By allowing High Fidelity to collect "
|
"installation and system details, and crash events. By allowing High Fidelity to collect "
|
||||||
"this information you are helping to improve the product. ", getter, setter));
|
"this information you are helping to improve the product. ", getter, setter));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const QString AVATAR_TUNING { "Avatar Tuning" };
|
static const QString AVATAR_TUNING { "Avatar Tuning" };
|
||||||
{
|
{
|
||||||
auto getter = [myAvatar]()->QString { return myAvatar->getDominantHand(); };
|
auto getter = [myAvatar]()->QString { return myAvatar->getDominantHand(); };
|
||||||
|
@ -247,8 +247,8 @@ void setupPreferences() {
|
||||||
preference->setStep(0.05f);
|
preference->setStep(0.05f);
|
||||||
preference->setDecimals(2);
|
preference->setDecimals(2);
|
||||||
preferences->addPreference(preference);
|
preferences->addPreference(preference);
|
||||||
|
|
||||||
// When the Interface is first loaded, this section setupPreferences(); is loaded -
|
// When the Interface is first loaded, this section setupPreferences(); is loaded -
|
||||||
// causing the myAvatar->getDomainMinScale() and myAvatar->getDomainMaxScale() to get set to incorrect values
|
// causing the myAvatar->getDomainMinScale() and myAvatar->getDomainMaxScale() to get set to incorrect values
|
||||||
// which can't be changed across domain switches. Having these values loaded up when you load the Dialog each time
|
// which can't be changed across domain switches. Having these values loaded up when you load the Dialog each time
|
||||||
// is a way around this, therefore they're not specified here but in the QML.
|
// is a way around this, therefore they're not specified here but in the QML.
|
||||||
|
@ -271,10 +271,14 @@ void setupPreferences() {
|
||||||
|
|
||||||
static const QString FACE_TRACKING{ "Face Tracking" };
|
static const QString FACE_TRACKING{ "Face Tracking" };
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_DDE
|
||||||
auto getter = []()->float { return DependencyManager::get<DdeFaceTracker>()->getEyeClosingThreshold(); };
|
auto getter = []()->float { return DependencyManager::get<DdeFaceTracker>()->getEyeClosingThreshold(); };
|
||||||
auto setter = [](float value) { DependencyManager::get<DdeFaceTracker>()->setEyeClosingThreshold(value); };
|
auto setter = [](float value) { DependencyManager::get<DdeFaceTracker>()->setEyeClosingThreshold(value); };
|
||||||
preferences->addPreference(new SliderPreference(FACE_TRACKING, "Eye Closing Threshold", getter, setter));
|
preferences->addPreference(new SliderPreference(FACE_TRACKING, "Eye Closing Threshold", getter, setter));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
auto getter = []()->float { return FaceTracker::getEyeDeflection(); };
|
auto getter = []()->float { return FaceTracker::getEyeDeflection(); };
|
||||||
auto setter = [](float value) { FaceTracker::setEyeDeflection(value); };
|
auto setter = [](float value) { FaceTracker::setEyeDeflection(value); };
|
||||||
|
@ -307,14 +311,14 @@ void setupPreferences() {
|
||||||
preferences->addPreference(preference);
|
preferences->addPreference(preference);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto getter = [myAvatar]() -> bool { return myAvatar->hoverWhenUnsupported(); };
|
auto getter = [myAvatar]()->bool { return myAvatar->hoverWhenUnsupported(); };
|
||||||
auto setter = [myAvatar](bool value) { myAvatar->setHoverWhenUnsupported(value); };
|
auto setter = [myAvatar](bool value) { myAvatar->setHoverWhenUnsupported(value); };
|
||||||
auto preference = new CheckPreference(VR_MOVEMENT, "Hover When Unsupported", getter, setter);
|
auto preference = new CheckPreference(VR_MOVEMENT, "Hover When Unsupported", getter, setter);
|
||||||
preferences->addPreference(preference);
|
preferences->addPreference(preference);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
auto getter = [myAvatar]()->int { return myAvatar->getMovementReference(); };
|
auto getter = [myAvatar]()->int { return myAvatar->getMovementReference(); };
|
||||||
auto setter = [myAvatar](int value) { myAvatar->setMovementReference(value); };
|
auto setter = [myAvatar](int value) { myAvatar->setMovementReference(value); };
|
||||||
//auto preference = new CheckPreference(VR_MOVEMENT, "Hand-Relative Movement", getter, setter);
|
//auto preference = new CheckPreference(VR_MOVEMENT, "Hand-Relative Movement", getter, setter);
|
||||||
auto preference = new RadioButtonsPreference(VR_MOVEMENT, "Movement Direction", getter, setter);
|
auto preference = new RadioButtonsPreference(VR_MOVEMENT, "Movement Direction", getter, setter);
|
||||||
QStringList items;
|
QStringList items;
|
||||||
|
@ -520,6 +524,5 @@ void setupPreferences() {
|
||||||
preference->setStep(10);
|
preference->setStep(10);
|
||||||
preferences->addPreference(preference);
|
preferences->addPreference(preference);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,7 @@ typedef enum LoginErrorTypes
|
||||||
- (BOOL) loginShouldSetErrorState;
|
- (BOOL) loginShouldSetErrorState;
|
||||||
- (void) displayErrorPage;
|
- (void) displayErrorPage;
|
||||||
- (void) showLoginScreen;
|
- (void) showLoginScreen;
|
||||||
|
- (NSString*) getLauncherPath;
|
||||||
- (ProcessState) currentProccessState;
|
- (ProcessState) currentProccessState;
|
||||||
- (void) setCurrentProcessState:(ProcessState) aProcessState;
|
- (void) setCurrentProcessState:(ProcessState) aProcessState;
|
||||||
- (void) setLoginErrorState:(LoginError) aLoginError;
|
- (void) setLoginErrorState:(LoginError) aLoginError;
|
||||||
|
|
|
@ -73,6 +73,11 @@ static BOOL const DELETE_ZIP_FILES = TRUE;
|
||||||
return filePath;
|
return filePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSString*) getLauncherPath
|
||||||
|
{
|
||||||
|
return [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/Contents/MacOS/"];
|
||||||
|
}
|
||||||
|
|
||||||
- (void) extractZipFileAtDestination:(NSString *)destination :(NSString*)file
|
- (void) extractZipFileAtDestination:(NSString *)destination :(NSString*)file
|
||||||
{
|
{
|
||||||
NSTask* task = [[NSTask alloc] init];
|
NSTask* task = [[NSTask alloc] init];
|
||||||
|
@ -174,7 +179,7 @@ static BOOL const DELETE_ZIP_FILES = TRUE;
|
||||||
|
|
||||||
- (NSString*) getAppPath
|
- (NSString*) getAppPath
|
||||||
{
|
{
|
||||||
return [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/Contents/MacOS/"];
|
return [self getDownloadPathForContentAndScripts];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) loginShouldSetErrorState
|
- (BOOL) loginShouldSetErrorState
|
||||||
|
@ -317,7 +322,7 @@ static BOOL const DELETE_ZIP_FILES = TRUE;
|
||||||
|
|
||||||
- (void) launchInterface
|
- (void) launchInterface
|
||||||
{
|
{
|
||||||
NSString* launcherPath = [[self getAppPath] stringByAppendingString:@"HQ Launcher"];
|
NSString* launcherPath = [[self getLauncherPath] stringByAppendingString:@"HQ Launcher"];
|
||||||
|
|
||||||
[[Settings sharedSettings] setLauncherPath:launcherPath];
|
[[Settings sharedSettings] setLauncherPath:launcherPath];
|
||||||
[[Settings sharedSettings] save];
|
[[Settings sharedSettings] save];
|
||||||
|
@ -351,8 +356,6 @@ static BOOL const DELETE_ZIP_FILES = TRUE;
|
||||||
}
|
}
|
||||||
[workspace launchApplicationAtURL:url options:NSWorkspaceLaunchNewInstance configuration:[NSDictionary dictionaryWithObject:arguments forKey:NSWorkspaceLaunchConfigurationArguments] error:&error];
|
[workspace launchApplicationAtURL:url options:NSWorkspaceLaunchNewInstance configuration:[NSDictionary dictionaryWithObject:arguments forKey:NSWorkspaceLaunchConfigurationArguments] error:&error];
|
||||||
|
|
||||||
//NSLog(@"arguments %@", [NSDictionary dictionaryWithObject:arguments forKey:NSWorkspaceLaunchConfigurationArguments]);
|
|
||||||
|
|
||||||
[NSApp terminate:self];
|
[NSApp terminate:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,10 @@ CLauncherDlg::CLauncherDlg(CWnd* pParent)
|
||||||
EnableD2DSupport();
|
EnableD2DSupport();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CLauncherDlg::~CLauncherDlg() {
|
||||||
|
theApp._manager.closeLog();
|
||||||
|
}
|
||||||
|
|
||||||
void CLauncherDlg::DoDataExchange(CDataExchange* pDX)
|
void CLauncherDlg::DoDataExchange(CDataExchange* pDX)
|
||||||
{
|
{
|
||||||
DDX_Control(pDX, IDC_BUTTON_NEXT, m_btnNext);
|
DDX_Control(pDX, IDC_BUTTON_NEXT, m_btnNext);
|
||||||
|
@ -154,25 +158,54 @@ HCURSOR CLauncherDlg::OnQueryDragIcon()
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLauncherDlg::startProcess() {
|
void CLauncherDlg::startProcess() {
|
||||||
if (theApp._manager.needsUpdate()) {
|
if (theApp._manager.needsUpdate()) {
|
||||||
setDrawDialog(DrawStep::DrawProcessUpdate);
|
theApp._manager.addToLog(_T("Starting Process Update"));
|
||||||
} else {
|
setDrawDialog(DrawStep::DrawProcessUpdate);
|
||||||
setDrawDialog(DrawStep::DrawProcessSetup);
|
} else {
|
||||||
}
|
theApp._manager.addToLog(_T("Starting Process Setup"));
|
||||||
|
setDrawDialog(DrawStep::DrawProcessSetup);
|
||||||
CString installDir;
|
}
|
||||||
theApp._manager.getAndCreatePaths(LauncherManager::PathType::Interface_Directory, installDir);
|
theApp._manager.addToLog(_T("Deleting directories before install"));
|
||||||
CString interfaceExe = installDir += "\\interface.exe";
|
|
||||||
if (!theApp._manager.isLoggedIn()) {
|
CString installDir;
|
||||||
theApp._manager.downloadContent();
|
theApp._manager.getAndCreatePaths(LauncherManager::PathType::Interface_Directory, installDir);
|
||||||
} else {
|
CString downloadDir;
|
||||||
theApp._manager.downloadApplication();
|
theApp._manager.getAndCreatePaths(LauncherManager::PathType::Download_Directory, downloadDir);
|
||||||
}
|
|
||||||
|
LauncherUtils::deleteDirectoriesOnThread(installDir, downloadDir, [&](int error) {
|
||||||
|
LauncherUtils::DeleteDirError deleteError = (LauncherUtils::DeleteDirError)error;
|
||||||
|
switch(error) {
|
||||||
|
case LauncherUtils::DeleteDirError::NoErrorDeleting:
|
||||||
|
theApp._manager.addToLog(_T("Install directory deleted."));
|
||||||
|
theApp._manager.addToLog(_T("Downloads directory deleted."));
|
||||||
|
if (!theApp._manager.isLoggedIn()) {
|
||||||
|
theApp._manager.addToLog(_T("Downloading Content"));
|
||||||
|
theApp._manager.downloadContent();
|
||||||
|
} else {
|
||||||
|
theApp._manager.addToLog(_T("Downloading App"));
|
||||||
|
theApp._manager.downloadApplication();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LauncherUtils::DeleteDirError::ErrorDeletingBothDirs:
|
||||||
|
theApp._manager.addToLog(_T("Error deleting directories."));
|
||||||
|
break;
|
||||||
|
case LauncherUtils::DeleteDirError::ErrorDeletingApplicationDir:
|
||||||
|
theApp._manager.addToLog(_T("Error deleting application directory."));
|
||||||
|
break;
|
||||||
|
case LauncherUtils::DeleteDirError::ErrorDeletingDownloadsDir:
|
||||||
|
theApp._manager.addToLog(_T("Error deleting downloads directory."));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL CLauncherDlg::getHQInfo(const CString& orgname) {
|
BOOL CLauncherDlg::getHQInfo(const CString& orgname) {
|
||||||
CString hash;
|
CString hash;
|
||||||
LauncherUtils::hMac256(orgname, LAUNCHER_HMAC_SECRET, hash);
|
CString lowerOrgName = orgname;
|
||||||
|
lowerOrgName.MakeLower();
|
||||||
|
LauncherUtils::hMac256(lowerOrgName, LAUNCHER_HMAC_SECRET, hash);
|
||||||
return theApp._manager.readOrganizationJSON(hash) == LauncherUtils::ResponseError::NoError;
|
return theApp._manager.readOrganizationJSON(hash) == LauncherUtils::ResponseError::NoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,33 +214,44 @@ afx_msg void CLauncherDlg::OnTroubleClicked() {
|
||||||
}
|
}
|
||||||
|
|
||||||
afx_msg void CLauncherDlg::OnNextClicked() {
|
afx_msg void CLauncherDlg::OnNextClicked() {
|
||||||
if (_drawStep != DrawStep::DrawChoose) {
|
if (_drawStep != DrawStep::DrawChoose) {
|
||||||
CString token;
|
CString token;
|
||||||
CString username, password, orgname;
|
CString username, password, orgname;
|
||||||
m_orgname.GetWindowTextW(orgname);
|
m_orgname.GetWindowTextW(orgname);
|
||||||
m_username.GetWindowTextW(username);
|
m_username.GetWindowTextW(username);
|
||||||
m_password.GetWindowTextW(password);
|
m_password.GetWindowTextW(password);
|
||||||
LauncherUtils::ResponseError error;
|
|
||||||
if (orgname.GetLength() > 0 && username.GetLength() > 0 && password.GetLength() > 0) {
|
username = LauncherUtils::urlEncodeString(username);
|
||||||
if (getHQInfo(orgname)) {
|
password = LauncherUtils::urlEncodeString(password);
|
||||||
error = theApp._manager.getAccessTokenForCredentials(username, password);
|
LauncherUtils::ResponseError error;
|
||||||
if (error == LauncherUtils::ResponseError::NoError) {
|
if (orgname.GetLength() > 0 && username.GetLength() > 0 && password.GetLength() > 0) {
|
||||||
setDrawDialog(DrawStep::DrawChoose);
|
theApp._manager.addToLog(_T("Trying to get organization data"));
|
||||||
} else if (error == LauncherUtils::ResponseError::BadCredentials) {
|
if (getHQInfo(orgname)) {
|
||||||
setDrawDialog(DrawStep::DrawLoginErrorCred);
|
theApp._manager.addToLog(_T("Organization data received."));
|
||||||
} else {
|
theApp._manager.addToLog(_T("Trying to log in with credentials"));
|
||||||
MessageBox(L"Error Reading or retreaving response.", L"Network Error", MB_OK | MB_ICONERROR);
|
error = theApp._manager.getAccessTokenForCredentials(username, password);
|
||||||
}
|
if (error == LauncherUtils::ResponseError::NoError) {
|
||||||
} else {
|
theApp._manager.addToLog(_T("Logged in correctly."));
|
||||||
setDrawDialog(DrawStep::DrawLoginErrorOrg);
|
setDrawDialog(DrawStep::DrawChoose);
|
||||||
}
|
} else if (error == LauncherUtils::ResponseError::BadCredentials) {
|
||||||
}
|
theApp._manager.addToLog(_T("Bad credentials. Try again"));
|
||||||
} else {
|
setDrawDialog(DrawStep::DrawLoginErrorCred);
|
||||||
CString displayName;
|
} else {
|
||||||
m_username.GetWindowTextW(displayName);
|
theApp._manager.addToLog(_T("Error Reading or retrieving response."));
|
||||||
theApp._manager.setDisplayName(displayName);
|
MessageBox(L"Error Reading or retrieving response.", L"Network Error", MB_OK | MB_ICONERROR);
|
||||||
startProcess();
|
}
|
||||||
}
|
} else {
|
||||||
|
theApp._manager.addToLog(_T("Organization name does not exist."));
|
||||||
|
setDrawDialog(DrawStep::DrawLoginErrorOrg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CString displayName;
|
||||||
|
m_username.GetWindowTextW(displayName);
|
||||||
|
theApp._manager.setDisplayName(displayName);
|
||||||
|
theApp._manager.addToLog(_T("Setting display name: " + displayName));
|
||||||
|
startProcess();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CLauncherDlg::drawBackground(CHwndRenderTarget* pRenderTarget) {
|
void CLauncherDlg::drawBackground(CHwndRenderTarget* pRenderTarget) {
|
||||||
|
@ -534,11 +578,13 @@ void CLauncherDlg::OnTimer(UINT_PTR nIDEvent) {
|
||||||
}
|
}
|
||||||
if (_showSplash) {
|
if (_showSplash) {
|
||||||
if (_splashStep == 0){
|
if (_splashStep == 0){
|
||||||
if (theApp._manager.needsUninstall()) {
|
if (theApp._manager.needsUninstall()) {
|
||||||
setDrawDialog(DrawStep::DrawProcessUninstall);
|
theApp._manager.addToLog(_T("Waiting to uninstall"));
|
||||||
} else {
|
setDrawDialog(DrawStep::DrawProcessUninstall);
|
||||||
setDrawDialog(DrawStep::DrawLogo);
|
} else {
|
||||||
}
|
theApp._manager.addToLog(_T("Start splash screen"));
|
||||||
|
setDrawDialog(DrawStep::DrawLogo);
|
||||||
|
}
|
||||||
} else if (_splashStep > 100) {
|
} else if (_splashStep > 100) {
|
||||||
_showSplash = false;
|
_showSplash = false;
|
||||||
if (theApp._manager.shouldShutDown()) {
|
if (theApp._manager.shouldShutDown()) {
|
||||||
|
@ -551,6 +597,7 @@ void CLauncherDlg::OnTimer(UINT_PTR nIDEvent) {
|
||||||
theApp._manager.uninstallApplication();
|
theApp._manager.uninstallApplication();
|
||||||
exit(0);
|
exit(0);
|
||||||
} else {
|
} else {
|
||||||
|
theApp._manager.addToLog(_T("Starting login"));
|
||||||
setDrawDialog(DrawStep::DrawLoginLogin);
|
setDrawDialog(DrawStep::DrawLoginLogin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
CLauncherDlg(CWnd* pParent = nullptr);
|
CLauncherDlg(CWnd* pParent = nullptr);
|
||||||
|
~CLauncherDlg();
|
||||||
virtual BOOL PreTranslateMessage(MSG* pMsg);
|
virtual BOOL PreTranslateMessage(MSG* pMsg);
|
||||||
|
|
||||||
void setDrawDialog(DrawStep step, BOOL isUpdate = FALSE);
|
void setDrawDialog(DrawStep step, BOOL isUpdate = FALSE);
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
#include <time.h>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
#include "LauncherManager.h"
|
#include "LauncherManager.h"
|
||||||
|
@ -24,19 +25,57 @@ LauncherManager::~LauncherManager()
|
||||||
}
|
}
|
||||||
|
|
||||||
void LauncherManager::init() {
|
void LauncherManager::init() {
|
||||||
getMostRecentBuild(_latestApplicationURL, _latestVersion);
|
initLog();
|
||||||
CString currentVersion;
|
addToLog(_T("Getting most recent build"));
|
||||||
if (isApplicationInstalled(currentVersion, _domainURL, _contentURL, _loggedIn) && _loggedIn) {
|
getMostRecentBuild(_latestApplicationURL, _latestVersion);
|
||||||
if (_latestVersion.Compare(currentVersion) == 0) {
|
addToLog(_T("Latest version: ") + _latestVersion);
|
||||||
launchApplication();
|
CString currentVersion;
|
||||||
_shouldShutdown = TRUE;
|
if (isApplicationInstalled(currentVersion, _domainURL, _contentURL, _loggedIn) && _loggedIn) {
|
||||||
} else {
|
addToLog(_T("Installed version: ") + currentVersion);
|
||||||
_shouldUpdate = TRUE;
|
if (_latestVersion.Compare(currentVersion) == 0) {
|
||||||
}
|
addToLog(_T("Already running most recent build. Launching interface.exe"));
|
||||||
}
|
launchApplication();
|
||||||
|
_shouldShutdown = TRUE;
|
||||||
|
} else {
|
||||||
|
addToLog(_T("New build found. Updating"));
|
||||||
|
_shouldUpdate = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL LauncherManager::initLog() {
|
||||||
|
CString logPath;
|
||||||
|
auto result = getAndCreatePaths(PathType::Launcher_Directory, logPath);
|
||||||
|
if (result) {
|
||||||
|
logPath += _T("log.txt");
|
||||||
|
return result = _logFile.Open(logPath, CFile::modeCreate | CFile::modeReadWrite);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL LauncherManager::addToLog(const CString& line) {
|
||||||
|
if (_logFile.m_hFile != CStdioFile::hFileNull) {
|
||||||
|
char buff[100];
|
||||||
|
time_t now = time(0);
|
||||||
|
tm ltm;
|
||||||
|
localtime_s(<m, &now);
|
||||||
|
|
||||||
|
strftime(buff, 100, "%Y-%m-%d %H:%M:%S", <m);
|
||||||
|
CString timeStr = CString(buff);
|
||||||
|
_logFile.WriteString(timeStr + _T(" ") + line + _T("\n"));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LauncherManager::closeLog() {
|
||||||
|
if (_logFile.m_hFile != CStdioFile::hFileNull) {
|
||||||
|
_logFile.Close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL LauncherManager::installLauncher() {
|
BOOL LauncherManager::installLauncher() {
|
||||||
|
addToLog(_T("Installing Launcher."));
|
||||||
CString appPath;
|
CString appPath;
|
||||||
BOOL result = getAndCreatePaths(PathType::Running_Path, appPath);
|
BOOL result = getAndCreatePaths(PathType::Running_Path, appPath);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
|
@ -60,6 +99,7 @@ BOOL LauncherManager::installLauncher() {
|
||||||
CopyFile(appPath, instalationPath, FALSE);
|
CopyFile(appPath, instalationPath, FALSE);
|
||||||
}
|
}
|
||||||
} else if (_shouldUninstall) {
|
} else if (_shouldUninstall) {
|
||||||
|
addToLog(_T("Launching uninstall mode."));
|
||||||
CString tempPath;
|
CString tempPath;
|
||||||
if (getAndCreatePaths(PathType::Temp_Directory, tempPath)) {
|
if (getAndCreatePaths(PathType::Temp_Directory, tempPath)) {
|
||||||
tempPath += _T("\\HQ_uninstaller_tmp.exe");
|
tempPath += _T("\\HQ_uninstaller_tmp.exe");
|
||||||
|
@ -73,6 +113,7 @@ BOOL LauncherManager::installLauncher() {
|
||||||
|
|
||||||
BOOL LauncherManager::createShortcuts() {
|
BOOL LauncherManager::createShortcuts() {
|
||||||
CString desktopLnkPath;
|
CString desktopLnkPath;
|
||||||
|
addToLog(_T("Creating shortcuts."));
|
||||||
getAndCreatePaths(PathType::Desktop_Directory, desktopLnkPath);
|
getAndCreatePaths(PathType::Desktop_Directory, desktopLnkPath);
|
||||||
desktopLnkPath += _T("\\HQ Launcher.lnk");
|
desktopLnkPath += _T("\\HQ Launcher.lnk");
|
||||||
CString installDir;
|
CString installDir;
|
||||||
|
@ -100,6 +141,7 @@ BOOL LauncherManager::createShortcuts() {
|
||||||
|
|
||||||
BOOL LauncherManager::deleteShortcuts() {
|
BOOL LauncherManager::deleteShortcuts() {
|
||||||
CString desktopLnkPath;
|
CString desktopLnkPath;
|
||||||
|
addToLog(_T("Deleting shortcuts."));
|
||||||
getAndCreatePaths(PathType::Desktop_Directory, desktopLnkPath);
|
getAndCreatePaths(PathType::Desktop_Directory, desktopLnkPath);
|
||||||
desktopLnkPath += _T("\\HQ Launcher.lnk");
|
desktopLnkPath += _T("\\HQ Launcher.lnk");
|
||||||
BOOL success = LauncherUtils::deleteFileOrDirectory(desktopLnkPath);
|
BOOL success = LauncherUtils::deleteFileOrDirectory(desktopLnkPath);
|
||||||
|
@ -353,13 +395,17 @@ BOOL LauncherManager::uninstallApplication() {
|
||||||
|
|
||||||
void LauncherManager::onZipExtracted(ZipType type, int size) {
|
void LauncherManager::onZipExtracted(ZipType type, int size) {
|
||||||
if (type == ZipType::ZipContent) {
|
if (type == ZipType::ZipContent) {
|
||||||
|
addToLog(_T("Downloading application."));
|
||||||
downloadApplication();
|
downloadApplication();
|
||||||
} else if (type == ZipType::ZipApplication) {
|
} else if (type == ZipType::ZipApplication) {
|
||||||
createShortcuts();
|
createShortcuts();
|
||||||
CString versionPath;
|
CString versionPath;
|
||||||
getAndCreatePaths(LauncherManager::PathType::Launcher_Directory, versionPath);
|
getAndCreatePaths(LauncherManager::PathType::Launcher_Directory, versionPath);
|
||||||
createConfigJSON();
|
addToLog(_T("Creating config.json"));
|
||||||
|
createConfigJSON();
|
||||||
|
addToLog(_T("Launching application."));
|
||||||
launchApplication(_tokensJSON);
|
launchApplication(_tokensJSON);
|
||||||
|
addToLog(_T("Creating registry keys."));
|
||||||
createApplicationRegistryKeys(size);
|
createApplicationRegistryKeys(size);
|
||||||
_shouldShutdown = TRUE;
|
_shouldShutdown = TRUE;
|
||||||
}
|
}
|
||||||
|
@ -377,8 +423,10 @@ BOOL LauncherManager::extractApplication() {
|
||||||
|
|
||||||
void LauncherManager::onFileDownloaded(DownloadType type) {
|
void LauncherManager::onFileDownloaded(DownloadType type) {
|
||||||
if (type == DownloadType::DownloadContent) {
|
if (type == DownloadType::DownloadContent) {
|
||||||
|
addToLog(_T("Installing content."));
|
||||||
installContent();
|
installContent();
|
||||||
} else if (type == DownloadType::DownloadApplication) {
|
} else if (type == DownloadType::DownloadApplication) {
|
||||||
|
addToLog(_T("Installing application."));
|
||||||
extractApplication();
|
extractApplication();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -412,6 +460,7 @@ BOOL LauncherManager::downloadFile(DownloadType type, const CString& url, CStrin
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL LauncherManager::downloadContent() {
|
BOOL LauncherManager::downloadContent() {
|
||||||
|
addToLog(_T("Downloading content."));
|
||||||
CString contentURL = getContentURL();
|
CString contentURL = getContentURL();
|
||||||
return downloadFile(DownloadType::DownloadContent, contentURL, _contentZipPath);
|
return downloadFile(DownloadType::DownloadContent, contentURL, _contentZipPath);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,9 @@ public:
|
||||||
LauncherManager();
|
LauncherManager();
|
||||||
~LauncherManager();
|
~LauncherManager();
|
||||||
void init();
|
void init();
|
||||||
|
BOOL initLog();
|
||||||
|
BOOL addToLog(const CString& line);
|
||||||
|
void closeLog();
|
||||||
BOOL getAndCreatePaths(PathType type, CString& outPath);
|
BOOL getAndCreatePaths(PathType type, CString& outPath);
|
||||||
BOOL getInstalledVersion(const CString& path, CString& version);
|
BOOL getInstalledVersion(const CString& path, CString& version);
|
||||||
BOOL isApplicationInstalled(CString& version, CString& domain,
|
BOOL isApplicationInstalled(CString& version, CString& domain,
|
||||||
|
@ -105,5 +108,6 @@ private:
|
||||||
BOOL _shouldUpdate{ FALSE };
|
BOOL _shouldUpdate{ FALSE };
|
||||||
BOOL _shouldUninstall{ FALSE };
|
BOOL _shouldUninstall{ FALSE };
|
||||||
BOOL _shouldShutdown{ FALSE };
|
BOOL _shouldShutdown{ FALSE };
|
||||||
|
CStdioFile _logFile;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,24 @@
|
||||||
|
|
||||||
#include "LauncherUtils.h"
|
#include "LauncherUtils.h"
|
||||||
|
|
||||||
|
CString LauncherUtils::urlEncodeString(const CString& url) {
|
||||||
|
std::map<CString, CString> specialCharsMap = { { _T("$"), _T("%24") }, { _T(" "), _T("%20") }, { _T("#"), _T("%23") },
|
||||||
|
{ _T("@"), _T("%40") }, { _T("`"), _T("%60") }, { _T("&"), _T("%26") },
|
||||||
|
{ _T("/"), _T("%2F") }, { _T(":"), _T("%3A") }, { _T(";"), _T("%3B") },
|
||||||
|
{ _T("<"), _T("%3C") }, { _T(">"), _T("%3E") }, { _T("="), _T("%3D") },
|
||||||
|
{ _T("?"), _T("%3F") }, { _T("["), _T("%5B") }, { _T("\\"), _T("%5C") },
|
||||||
|
{ _T("]"), _T("%5D") }, { _T("^"), _T("%5E") }, { _T("{"), _T("%7B") },
|
||||||
|
{ _T("|"), _T("%7C") }, { _T("}"), _T("%7D") }, { _T("~"), _T("%7E") },
|
||||||
|
{ _T("“"), _T("%22") }, { _T("‘"), _T("%27") }, { _T("+"), _T("%2B") },
|
||||||
|
{ _T(","), _T("%2C") } };
|
||||||
|
CString stringOut = url;
|
||||||
|
stringOut.Replace(_T("%"), _T("%25"));
|
||||||
|
for (auto& itr = specialCharsMap.begin(); itr != specialCharsMap.end(); itr++) {
|
||||||
|
stringOut.Replace(itr->first, itr->second);
|
||||||
|
}
|
||||||
|
return stringOut;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL LauncherUtils::IsProcessRunning(const wchar_t *processName) {
|
BOOL LauncherUtils::IsProcessRunning(const wchar_t *processName) {
|
||||||
bool exists = false;
|
bool exists = false;
|
||||||
PROCESSENTRY32 entry;
|
PROCESSENTRY32 entry;
|
||||||
|
@ -374,6 +392,19 @@ DWORD WINAPI LauncherUtils::downloadThread(LPVOID lpParameter)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD WINAPI LauncherUtils::deleteDirectoriesThread(LPVOID lpParameter) {
|
||||||
|
DeleteThreadData& data = *((DeleteThreadData*)lpParameter);
|
||||||
|
DeleteDirError error = DeleteDirError::NoErrorDeleting;
|
||||||
|
if (!LauncherUtils::deleteFileOrDirectory(data._applicationDir)) {
|
||||||
|
error = DeleteDirError::ErrorDeletingApplicationDir;
|
||||||
|
}
|
||||||
|
if (!LauncherUtils::deleteFileOrDirectory(data._downloadsDir)) {
|
||||||
|
error = error == NoError ? DeleteDirError::ErrorDeletingDownloadsDir : DeleteDirError::ErrorDeletingBothDirs;
|
||||||
|
}
|
||||||
|
data.callback(error);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
BOOL LauncherUtils::unzipFileOnThread(int type, const std::string& zipFile, const std::string& path, std::function<void(int, int)> callback) {
|
BOOL LauncherUtils::unzipFileOnThread(int type, const std::string& zipFile, const std::string& path, std::function<void(int, int)> callback) {
|
||||||
DWORD myThreadID;
|
DWORD myThreadID;
|
||||||
UnzipThreadData* unzipThreadData = new UnzipThreadData();
|
UnzipThreadData* unzipThreadData = new UnzipThreadData();
|
||||||
|
@ -402,4 +433,20 @@ BOOL LauncherUtils::downloadFileOnThread(int type, const CString& url, const CSt
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL LauncherUtils::deleteDirectoriesOnThread(const CString& applicationDir,
|
||||||
|
const CString& downloadsDir,
|
||||||
|
std::function<void(int)> callback) {
|
||||||
|
DWORD myThreadID;
|
||||||
|
DeleteThreadData* deleteThreadData = new DeleteThreadData();
|
||||||
|
deleteThreadData->_applicationDir = applicationDir;
|
||||||
|
deleteThreadData->_downloadsDir = downloadsDir;
|
||||||
|
deleteThreadData->setCallback(callback);
|
||||||
|
HANDLE myHandle = CreateThread(0, 0, deleteDirectoriesThread, deleteThreadData, 0, &myThreadID);
|
||||||
|
if (myHandle) {
|
||||||
|
CloseHandle(myHandle);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
|
@ -30,6 +30,13 @@ public:
|
||||||
NoError
|
NoError
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum DeleteDirError {
|
||||||
|
NoErrorDeleting = 0,
|
||||||
|
ErrorDeletingApplicationDir,
|
||||||
|
ErrorDeletingDownloadsDir,
|
||||||
|
ErrorDeletingBothDirs
|
||||||
|
};
|
||||||
|
|
||||||
struct DownloadThreadData {
|
struct DownloadThreadData {
|
||||||
int _type;
|
int _type;
|
||||||
CString _url;
|
CString _url;
|
||||||
|
@ -52,6 +59,13 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DeleteThreadData {
|
||||||
|
CString _applicationDir;
|
||||||
|
CString _downloadsDir;
|
||||||
|
std::function<void(int)> callback;
|
||||||
|
void setCallback(std::function<void(int)> fn) { callback = std::bind(fn, std::placeholders::_1); }
|
||||||
|
};
|
||||||
|
|
||||||
static BOOL parseJSON(const CString& jsonTxt, Json::Value& jsonObject);
|
static BOOL parseJSON(const CString& jsonTxt, Json::Value& jsonObject);
|
||||||
static ResponseError makeHTTPCall(const CString& callerName, const CString& mainUrl,
|
static ResponseError makeHTTPCall(const CString& callerName, const CString& mainUrl,
|
||||||
const CString& dirUrl, const CString& contentType,
|
const CString& dirUrl, const CString& contentType,
|
||||||
|
@ -69,9 +83,14 @@ public:
|
||||||
static BOOL deleteRegistryKey(const CString& registryPath);
|
static BOOL deleteRegistryKey(const CString& registryPath);
|
||||||
static BOOL unzipFileOnThread(int type, const std::string& zipFile, const std::string& path, std::function<void(int, int)> callback);
|
static BOOL unzipFileOnThread(int type, const std::string& zipFile, const std::string& path, std::function<void(int, int)> callback);
|
||||||
static BOOL downloadFileOnThread(int type, const CString& url, const CString& file, std::function<void(int)> callback);
|
static BOOL downloadFileOnThread(int type, const CString& url, const CString& file, std::function<void(int)> callback);
|
||||||
|
static BOOL deleteDirectoriesOnThread(const CString& applicationDir,
|
||||||
|
const CString& downloadsDir,
|
||||||
|
std::function<void(int)> callback);
|
||||||
|
static CString urlEncodeString(const CString& url);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Threads
|
// Threads
|
||||||
static DWORD WINAPI unzipThread(LPVOID lpParameter);
|
static DWORD WINAPI unzipThread(LPVOID lpParameter);
|
||||||
static DWORD WINAPI downloadThread(LPVOID lpParameter);
|
static DWORD WINAPI downloadThread(LPVOID lpParameter);
|
||||||
|
static DWORD WINAPI deleteDirectoriesThread(LPVOID lpParameter);
|
||||||
};
|
};
|
|
@ -170,9 +170,9 @@ public:
|
||||||
glFinish();
|
glFinish();
|
||||||
}
|
}
|
||||||
currentPlugin = newPlugin;
|
currentPlugin = newPlugin;
|
||||||
_newPluginQueue.pop();
|
|
||||||
_condition.notify_one();
|
|
||||||
}
|
}
|
||||||
|
_newPluginQueue.pop();
|
||||||
|
_condition.notify_one();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -257,7 +257,7 @@ ShapeKey MaterialEntityRenderer::getShapeKey() {
|
||||||
|
|
||||||
bool isTranslucent = drawMaterialKey.isTranslucent();
|
bool isTranslucent = drawMaterialKey.isTranslucent();
|
||||||
bool hasTangents = drawMaterialKey.isNormalMap();
|
bool hasTangents = drawMaterialKey.isNormalMap();
|
||||||
bool hasLightmap = drawMaterialKey.isLightmapMap();
|
bool hasLightmap = drawMaterialKey.isLightMap();
|
||||||
bool isUnlit = drawMaterialKey.isUnlit();
|
bool isUnlit = drawMaterialKey.isUnlit();
|
||||||
|
|
||||||
ShapeKey::Builder builder;
|
ShapeKey::Builder builder;
|
||||||
|
@ -270,7 +270,7 @@ ShapeKey MaterialEntityRenderer::getShapeKey() {
|
||||||
builder.withTangents();
|
builder.withTangents();
|
||||||
}
|
}
|
||||||
if (hasLightmap) {
|
if (hasLightmap) {
|
||||||
builder.withLightmap();
|
builder.withLightMap();
|
||||||
}
|
}
|
||||||
if (isUnlit) {
|
if (isUnlit) {
|
||||||
builder.withUnlit();
|
builder.withUnlit();
|
||||||
|
|
|
@ -197,7 +197,7 @@ ShapeKey ShapeEntityRenderer::getShapeKey() {
|
||||||
|
|
||||||
bool isTranslucent = drawMaterialKey.isTranslucent();
|
bool isTranslucent = drawMaterialKey.isTranslucent();
|
||||||
bool hasTangents = drawMaterialKey.isNormalMap();
|
bool hasTangents = drawMaterialKey.isNormalMap();
|
||||||
bool hasLightmap = drawMaterialKey.isLightmapMap();
|
bool hasLightmap = drawMaterialKey.isLightMap();
|
||||||
bool isUnlit = drawMaterialKey.isUnlit();
|
bool isUnlit = drawMaterialKey.isUnlit();
|
||||||
|
|
||||||
ShapeKey::Builder builder;
|
ShapeKey::Builder builder;
|
||||||
|
@ -210,7 +210,7 @@ ShapeKey ShapeEntityRenderer::getShapeKey() {
|
||||||
builder.withTangents();
|
builder.withTangents();
|
||||||
}
|
}
|
||||||
if (hasLightmap) {
|
if (hasLightmap) {
|
||||||
builder.withLightmap();
|
builder.withLightMap();
|
||||||
}
|
}
|
||||||
if (isUnlit) {
|
if (isUnlit) {
|
||||||
builder.withUnlit();
|
builder.withUnlit();
|
||||||
|
|
|
@ -88,7 +88,7 @@ private:
|
||||||
// emissive, albedo
|
// emissive, albedo
|
||||||
// urls to textures:
|
// urls to textures:
|
||||||
// emissiveMap, albedoMap (set opacityMap = albedoMap for transparency), metallicMap or specularMap, roughnessMap or glossMap,
|
// emissiveMap, albedoMap (set opacityMap = albedoMap for transparency), metallicMap or specularMap, roughnessMap or glossMap,
|
||||||
// normalMap or bumpMap, occlusionMap, lightmapMap (broken, FIXME), scatteringMap (only works if normal mapped)
|
// normalMap or bumpMap, occlusionMap, lightMap (broken, FIXME), scatteringMap (only works if normal mapped)
|
||||||
QString _materialURL;
|
QString _materialURL;
|
||||||
// Type of material. "uv" or "projected".
|
// Type of material. "uv" or "projected".
|
||||||
MaterialMappingMode _materialMappingMode { UV };
|
MaterialMappingMode _materialMappingMode { UV };
|
||||||
|
|
|
@ -841,7 +841,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
parents[child] = nodecount;
|
parents[child] = nodecount;
|
||||||
}
|
}
|
||||||
sortedNodes.push_back(nodecount);
|
sortedNodes.push_back(nodecount);
|
||||||
nodecount++;
|
++nodecount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -857,7 +857,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
_file.nodes[nodecount].transforms.push_back(getModelTransform(parentNode));
|
_file.nodes[nodecount].transforms.push_back(getModelTransform(parentNode));
|
||||||
parentIndex = parents[parentIndex];
|
parentIndex = parents[parentIndex];
|
||||||
}
|
}
|
||||||
nodecount++;
|
++nodecount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -871,7 +871,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
int parentIndex = parents[currentNode];
|
int parentIndex = parents[currentNode];
|
||||||
if (parentIndex == -1 || hasBeenSorted[parentIndex]) {
|
if (parentIndex == -1 || hasBeenSorted[parentIndex]) {
|
||||||
hasBeenSorted[currentNode] = true;
|
hasBeenSorted[currentNode] = true;
|
||||||
i++;
|
++i;
|
||||||
} else {
|
} else {
|
||||||
int j = i + 1; // index of node to be sorted
|
int j = i + 1; // index of node to be sorted
|
||||||
while (j < numNodes) {
|
while (j < numNodes) {
|
||||||
|
@ -882,10 +882,10 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
hasBeenSorted[nextNode] = true;
|
hasBeenSorted[nextNode] = true;
|
||||||
sortedNodes[i] = nextNode;
|
sortedNodes[i] = nextNode;
|
||||||
sortedNodes[j] = currentNode;
|
sortedNodes[j] = currentNode;
|
||||||
i++;
|
++i;
|
||||||
currentNode = sortedNodes[i];
|
currentNode = sortedNodes[i];
|
||||||
}
|
}
|
||||||
j++;
|
++j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -894,7 +894,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
// Build map from original to new indices
|
// Build map from original to new indices
|
||||||
QVector<int> originalToNewNodeIndexMap;
|
QVector<int> originalToNewNodeIndexMap;
|
||||||
originalToNewNodeIndexMap.fill(-1, numNodes);
|
originalToNewNodeIndexMap.fill(-1, numNodes);
|
||||||
for (int i = 0; i < numNodes; i++) {
|
for (int i = 0; i < numNodes; ++i) {
|
||||||
originalToNewNodeIndexMap[sortedNodes[i]] = i;
|
originalToNewNodeIndexMap[sortedNodes[i]] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -903,6 +903,8 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
HFMJoint joint;
|
HFMJoint joint;
|
||||||
joint.distanceToParent = 0;
|
joint.distanceToParent = 0;
|
||||||
hfmModel.jointIndices["x"] = numNodes;
|
hfmModel.jointIndices["x"] = numNodes;
|
||||||
|
QVector<glm::mat4> globalTransforms;
|
||||||
|
globalTransforms.resize(numNodes);
|
||||||
|
|
||||||
for (int nodeIndex : sortedNodes) {
|
for (int nodeIndex : sortedNodes) {
|
||||||
auto& node = _file.nodes[nodeIndex];
|
auto& node = _file.nodes[nodeIndex];
|
||||||
|
@ -917,6 +919,13 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
glm::vec3 scale = extractScale(joint.transform);
|
glm::vec3 scale = extractScale(joint.transform);
|
||||||
joint.postTransform = glm::scale(glm::mat4(), scale);
|
joint.postTransform = glm::scale(glm::mat4(), scale);
|
||||||
|
|
||||||
|
joint.parentIndex = parents[nodeIndex];
|
||||||
|
globalTransforms[nodeIndex] = joint.transform;
|
||||||
|
if (joint.parentIndex != -1) {
|
||||||
|
globalTransforms[nodeIndex] = globalTransforms[joint.parentIndex] * globalTransforms[nodeIndex];
|
||||||
|
joint.parentIndex = originalToNewNodeIndexMap[joint.parentIndex];
|
||||||
|
}
|
||||||
|
|
||||||
joint.name = node.name;
|
joint.name = node.name;
|
||||||
joint.isSkeletonJoint = false;
|
joint.isSkeletonJoint = false;
|
||||||
hfmModel.joints.push_back(joint);
|
hfmModel.joints.push_back(joint);
|
||||||
|
@ -924,20 +933,30 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
hfmModel.shapeVertices.resize(hfmModel.joints.size());
|
hfmModel.shapeVertices.resize(hfmModel.joints.size());
|
||||||
|
|
||||||
|
|
||||||
|
// get offset transform from mapping
|
||||||
|
float unitScaleFactor = 1.0f;
|
||||||
|
float offsetScale = mapping.value("scale", 1.0f).toFloat() * unitScaleFactor;
|
||||||
|
glm::quat offsetRotation = glm::quat(glm::radians(glm::vec3(mapping.value("rx").toFloat(), mapping.value("ry").toFloat(), mapping.value("rz").toFloat())));
|
||||||
|
hfmModel.offset = glm::translate(glm::mat4(), glm::vec3(mapping.value("tx").toFloat(), mapping.value("ty").toFloat(), mapping.value("tz").toFloat())) *
|
||||||
|
glm::mat4_cast(offsetRotation) * glm::scale(glm::mat4(), glm::vec3(offsetScale, offsetScale, offsetScale));
|
||||||
|
|
||||||
|
|
||||||
// Build skeleton
|
// Build skeleton
|
||||||
std::vector<glm::mat4> jointInverseBindTransforms;
|
std::vector<glm::mat4> jointInverseBindTransforms;
|
||||||
|
std::vector<glm::mat4> globalBindTransforms;
|
||||||
jointInverseBindTransforms.resize(numNodes);
|
jointInverseBindTransforms.resize(numNodes);
|
||||||
|
globalBindTransforms.resize(numNodes);
|
||||||
|
|
||||||
hfmModel.hasSkeletonJoints = !_file.skins.isEmpty();
|
hfmModel.hasSkeletonJoints = !_file.skins.isEmpty();
|
||||||
if (hfmModel.hasSkeletonJoints) {
|
if (hfmModel.hasSkeletonJoints) {
|
||||||
hfmModel.hasSkeletonJoints = true;
|
|
||||||
std::vector<std::vector<float>> inverseBindValues;
|
std::vector<std::vector<float>> inverseBindValues;
|
||||||
getSkinInverseBindMatrices(inverseBindValues);
|
getSkinInverseBindMatrices(inverseBindValues);
|
||||||
|
|
||||||
for (int jointIndex = 0; jointIndex < numNodes; jointIndex++) {
|
for (int jointIndex = 0; jointIndex < numNodes; ++jointIndex) {
|
||||||
int nodeIndex = sortedNodes[jointIndex];
|
int nodeIndex = sortedNodes[jointIndex];
|
||||||
auto joint = hfmModel.joints[jointIndex];
|
auto joint = hfmModel.joints[jointIndex];
|
||||||
|
|
||||||
for (int s = 0; s < _file.skins.size(); s++) {
|
for (int s = 0; s < _file.skins.size(); ++s) {
|
||||||
const auto& skin = _file.skins[s];
|
const auto& skin = _file.skins[s];
|
||||||
int matrixIndex = skin.joints.indexOf(nodeIndex);
|
int matrixIndex = skin.joints.indexOf(nodeIndex);
|
||||||
joint.isSkeletonJoint = skin.joints.contains(nodeIndex);
|
joint.isSkeletonJoint = skin.joints.contains(nodeIndex);
|
||||||
|
@ -954,6 +973,10 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
} else {
|
} else {
|
||||||
jointInverseBindTransforms[jointIndex] = glm::mat4();
|
jointInverseBindTransforms[jointIndex] = glm::mat4();
|
||||||
}
|
}
|
||||||
|
globalBindTransforms[jointIndex] = jointInverseBindTransforms[jointIndex];
|
||||||
|
if (joint.parentIndex != -1) {
|
||||||
|
globalBindTransforms[jointIndex] = globalBindTransforms[joint.parentIndex] * globalBindTransforms[jointIndex];
|
||||||
|
}
|
||||||
glm::vec3 bindTranslation = extractTranslation(hfmModel.offset * glm::inverse(jointInverseBindTransforms[jointIndex]));
|
glm::vec3 bindTranslation = extractTranslation(hfmModel.offset * glm::inverse(jointInverseBindTransforms[jointIndex]));
|
||||||
hfmModel.bindExtents.addPoint(bindTranslation);
|
hfmModel.bindExtents.addPoint(bindTranslation);
|
||||||
}
|
}
|
||||||
|
@ -962,13 +985,13 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Build materials
|
// Build materials
|
||||||
QVector<QString> materialIDs;
|
QVector<QString> materialIDs;
|
||||||
QString unknown = "Default";
|
QString unknown = "Default";
|
||||||
int ukcount = 0;
|
int ukcount = 0;
|
||||||
foreach(auto material, _file.materials) {
|
foreach(auto material, _file.materials) {
|
||||||
if (!material.defined["name"]) {
|
if (!material.defined["name"]) {
|
||||||
QString name = unknown + QString::number(ukcount++);
|
QString name = unknown + QString::number(++ukcount);
|
||||||
material.name = name;
|
material.name = name;
|
||||||
material.defined.insert("name", true);
|
material.defined.insert("name", true);
|
||||||
}
|
}
|
||||||
|
@ -977,7 +1000,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
materialIDs.push_back(mid);
|
materialIDs.push_back(mid);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < materialIDs.size(); i++) {
|
for (int i = 0; i < materialIDs.size(); ++i) {
|
||||||
QString& matid = materialIDs[i];
|
QString& matid = materialIDs[i];
|
||||||
hfmModel.materials[matid] = HFMMaterial();
|
hfmModel.materials[matid] = HFMMaterial();
|
||||||
HFMMaterial& hfmMaterial = hfmModel.materials[matid];
|
HFMMaterial& hfmMaterial = hfmModel.materials[matid];
|
||||||
|
@ -989,6 +1012,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
|
|
||||||
// Build meshes
|
// Build meshes
|
||||||
nodecount = 0;
|
nodecount = 0;
|
||||||
|
hfmModel.meshExtents.reset();
|
||||||
for (int nodeIndex : sortedNodes) {
|
for (int nodeIndex : sortedNodes) {
|
||||||
auto& node = _file.nodes[nodeIndex];
|
auto& node = _file.nodes[nodeIndex];
|
||||||
|
|
||||||
|
@ -1003,7 +1027,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
cluster.inverseBindTransform = Transform(cluster.inverseBindMatrix);
|
cluster.inverseBindTransform = Transform(cluster.inverseBindMatrix);
|
||||||
mesh.clusters.append(cluster);
|
mesh.clusters.append(cluster);
|
||||||
} else { // skinned model
|
} else { // skinned model
|
||||||
for (int j = 0; j < numNodes; j++) {
|
for (int j = 0; j < numNodes; ++j) {
|
||||||
HFMCluster cluster;
|
HFMCluster cluster;
|
||||||
cluster.jointIndex = j;
|
cluster.jointIndex = j;
|
||||||
cluster.inverseBindMatrix = jointInverseBindTransforms[j];
|
cluster.inverseBindMatrix = jointInverseBindTransforms[j];
|
||||||
|
@ -1300,7 +1324,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<int> validatedIndices;
|
QVector<int> validatedIndices;
|
||||||
for (int n = 0; n < indices.count(); n++) {
|
for (int n = 0; n < indices.count(); ++n) {
|
||||||
if (indices[n] < partVerticesCount) {
|
if (indices[n] < partVerticesCount) {
|
||||||
validatedIndices.push_back(indices[n] + prevMeshVerticesCount);
|
validatedIndices.push_back(indices[n] + prevMeshVerticesCount);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1332,7 +1356,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (meshAttributes.contains("TANGENT")) {
|
if (meshAttributes.contains("TANGENT")) {
|
||||||
for (int i = 0; i < partVerticesCount; i++) {
|
for (int i = 0; i < partVerticesCount; ++i) {
|
||||||
mesh.tangents.push_back(glm::vec3(0.0f, 0.0f, 0.0f));
|
mesh.tangents.push_back(glm::vec3(0.0f, 0.0f, 0.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1344,7 +1368,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (meshAttributes.contains("TEXCOORD_0")) {
|
if (meshAttributes.contains("TEXCOORD_0")) {
|
||||||
for (int i = 0; i < partVerticesCount; i++) {
|
for (int i = 0; i < partVerticesCount; ++i) {
|
||||||
mesh.texCoords.push_back(glm::vec2(0.0f, 0.0f));
|
mesh.texCoords.push_back(glm::vec2(0.0f, 0.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1356,7 +1380,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (meshAttributes.contains("TEXCOORD_1")) {
|
if (meshAttributes.contains("TEXCOORD_1")) {
|
||||||
for (int i = 0; i < partVerticesCount; i++) {
|
for (int i = 0; i < partVerticesCount; ++i) {
|
||||||
mesh.texCoords1.push_back(glm::vec2(0.0f, 0.0f));
|
mesh.texCoords1.push_back(glm::vec2(0.0f, 0.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1368,7 +1392,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (meshAttributes.contains("COLOR_0")) {
|
if (meshAttributes.contains("COLOR_0")) {
|
||||||
for (int i = 0; i < partVerticesCount; i++) {
|
for (int i = 0; i < partVerticesCount; ++i) {
|
||||||
mesh.colors.push_back(glm::vec3(1.0f, 1.0f, 1.0f));
|
mesh.colors.push_back(glm::vec3(1.0f, 1.0f, 1.0f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1398,8 +1422,8 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (meshAttributes.contains("JOINTS_0")) {
|
if (meshAttributes.contains("JOINTS_0")) {
|
||||||
for (int i = 0; i < partVerticesCount; i++) {
|
for (int i = 0; i < partVerticesCount; ++i) {
|
||||||
for (int j = 0; j < 4; j++) {
|
for (int j = 0; j < 4; ++j) {
|
||||||
clusterJoints.push_back(0);
|
clusterJoints.push_back(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1430,9 +1454,9 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (meshAttributes.contains("WEIGHTS_0")) {
|
if (meshAttributes.contains("WEIGHTS_0")) {
|
||||||
for (int i = 0; i < partVerticesCount; i++) {
|
for (int i = 0; i < partVerticesCount; ++i) {
|
||||||
clusterWeights.push_back(1.0f);
|
clusterWeights.push_back(1.0f);
|
||||||
for (int j = 1; j < 4; j++) {
|
for (int j = 1; j < 4; ++j) {
|
||||||
clusterWeights.push_back(0.0f);
|
clusterWeights.push_back(0.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1448,12 +1472,12 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
int numVertices = mesh.vertices.size() - prevMeshVerticesCount;
|
int numVertices = mesh.vertices.size() - prevMeshVerticesCount;
|
||||||
|
|
||||||
// Append new cluster indices and weights for this mesh part
|
// Append new cluster indices and weights for this mesh part
|
||||||
for (int i = 0; i < numVertices * WEIGHTS_PER_VERTEX; i++) {
|
for (int i = 0; i < numVertices * WEIGHTS_PER_VERTEX; ++i) {
|
||||||
mesh.clusterIndices.push_back(mesh.clusters.size() - 1);
|
mesh.clusterIndices.push_back(mesh.clusters.size() - 1);
|
||||||
mesh.clusterWeights.push_back(0);
|
mesh.clusterWeights.push_back(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int c = 0; c < clusterJoints.size(); c++) {
|
for (int c = 0; c < clusterJoints.size(); ++c) {
|
||||||
mesh.clusterIndices[prevMeshClusterIndexCount + c] =
|
mesh.clusterIndices[prevMeshClusterIndexCount + c] =
|
||||||
originalToNewNodeIndexMap[_file.skins[node.skin].joints[clusterJoints[c]]];
|
originalToNewNodeIndexMap[_file.skins[node.skin].joints[clusterJoints[c]]];
|
||||||
}
|
}
|
||||||
|
@ -1474,6 +1498,20 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
} else {
|
} else {
|
||||||
mesh.clusterWeights[prevMeshClusterWeightCount + j] = (uint16_t)((float)(UINT16_MAX) + ALMOST_HALF);
|
mesh.clusterWeights[prevMeshClusterWeightCount + j] = (uint16_t)((float)(UINT16_MAX) + ALMOST_HALF);
|
||||||
}
|
}
|
||||||
|
for (int clusterIndex = 0; clusterIndex < mesh.clusters.size() - 1; ++clusterIndex) {
|
||||||
|
ShapeVertices& points = hfmModel.shapeVertices.at(clusterIndex);
|
||||||
|
glm::vec3 globalMeshScale = extractScale(globalTransforms[nodeIndex]);
|
||||||
|
const glm::mat4 meshToJoint = glm::scale(glm::mat4(), globalMeshScale) * jointInverseBindTransforms[clusterIndex];
|
||||||
|
|
||||||
|
const float EXPANSION_WEIGHT_THRESHOLD = 0.25f;
|
||||||
|
if (mesh.clusterWeights[j] >= EXPANSION_WEIGHT_THRESHOLD) {
|
||||||
|
// TODO: fix transformed vertices being pushed back
|
||||||
|
auto& vertex = mesh.vertices[i];
|
||||||
|
const glm::mat4 vertexTransform = meshToJoint * (glm::translate(glm::mat4(), vertex));
|
||||||
|
glm::vec3 transformedVertex = hfmModel.joints[clusterIndex].translation * (extractTranslation(vertexTransform));
|
||||||
|
points.push_back(transformedVertex);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1484,7 +1522,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
|
|
||||||
// populate the texture coordinates if they don't exist
|
// populate the texture coordinates if they don't exist
|
||||||
if (mesh.texCoords.size() == 0 && !hfmModel.hasSkeletonJoints) {
|
if (mesh.texCoords.size() == 0 && !hfmModel.hasSkeletonJoints) {
|
||||||
for (int i = 0; i < part.triangleIndices.size(); i++) { mesh.texCoords.push_back(glm::vec2(0.0, 1.0)); }
|
for (int i = 0; i < part.triangleIndices.size(); ++i) { mesh.texCoords.push_back(glm::vec2(0.0, 1.0)); }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build morph targets (blend shapes)
|
// Build morph targets (blend shapes)
|
||||||
|
@ -1495,7 +1533,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
hifi::VariantHash blendshapeMappings = mapping.value("bs").toHash();
|
hifi::VariantHash blendshapeMappings = mapping.value("bs").toHash();
|
||||||
QMultiHash<QString, WeightedIndex> blendshapeIndices;
|
QMultiHash<QString, WeightedIndex> blendshapeIndices;
|
||||||
|
|
||||||
for (int i = 0;; i++) {
|
for (int i = 0;; ++i) {
|
||||||
hifi::ByteArray blendshapeName = FACESHIFT_BLENDSHAPES[i];
|
hifi::ByteArray blendshapeName = FACESHIFT_BLENDSHAPES[i];
|
||||||
if (blendshapeName.isEmpty()) {
|
if (blendshapeName.isEmpty()) {
|
||||||
break;
|
break;
|
||||||
|
@ -1515,7 +1553,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
auto names = _file.meshes[node.mesh].extras.targetNames;
|
auto names = _file.meshes[node.mesh].extras.targetNames;
|
||||||
QVector<double> weights = _file.meshes[node.mesh].weights;
|
QVector<double> weights = _file.meshes[node.mesh].weights;
|
||||||
|
|
||||||
for (int weightedIndex = 0; weightedIndex < values.size(); weightedIndex++) {
|
for (int weightedIndex = 0; weightedIndex < values.size(); ++weightedIndex) {
|
||||||
float weight = 0.1f;
|
float weight = 0.1f;
|
||||||
int indexFromMapping = weightedIndex;
|
int indexFromMapping = weightedIndex;
|
||||||
int targetIndex = weightedIndex;
|
int targetIndex = weightedIndex;
|
||||||
|
@ -1556,32 +1594,17 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
} else {
|
} else {
|
||||||
blendshape.vertices[count] = blendshape.vertices[count] + vertices[i];
|
blendshape.vertices[count] = blendshape.vertices[count] + vertices[i];
|
||||||
blendshape.normals[count] = blendshape.normals[count] + normals[i];
|
blendshape.normals[count] = blendshape.normals[count] + normals[i];
|
||||||
count++;
|
++count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int clusterIndex = 0; clusterIndex < mesh.clusters.size() - 1; clusterIndex++) {
|
|
||||||
ShapeVertices& points = hfmModel.shapeVertices.at(clusterIndex);
|
|
||||||
for (glm::vec3 vertex : mesh.vertices) {
|
|
||||||
points.push_back(vertex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mesh.meshExtents.reset();
|
|
||||||
foreach(const glm::vec3& vertex, mesh.vertices) {
|
foreach(const glm::vec3& vertex, mesh.vertices) {
|
||||||
mesh.meshExtents.addPoint(vertex);
|
glm::vec3 transformedVertex = glm::vec3(globalTransforms[nodeIndex] * glm::vec4(vertex, 1.0f));
|
||||||
hfmModel.meshExtents.addPoint(vertex);
|
mesh.meshExtents.addPoint(transformedVertex);
|
||||||
}
|
hfmModel.meshExtents.addPoint(transformedVertex);
|
||||||
|
}
|
||||||
mesh.meshIndex = hfmModel.meshes.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
mesh.meshExtents.reset();
|
|
||||||
foreach(const glm::vec3& vertex, mesh.vertices) {
|
|
||||||
mesh.meshExtents.addPoint(vertex);
|
|
||||||
hfmModel.meshExtents.addPoint(vertex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add epsilon to mesh extents to compensate for planar meshes
|
// Add epsilon to mesh extents to compensate for planar meshes
|
||||||
|
@ -1592,7 +1615,7 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
|
||||||
|
|
||||||
mesh.meshIndex = hfmModel.meshes.size();
|
mesh.meshIndex = hfmModel.meshes.size();
|
||||||
}
|
}
|
||||||
nodecount++;
|
++nodecount;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1839,8 +1862,8 @@ bool GLTFSerializer::readArray(const hifi::ByteArray& bin, int byteOffset, int c
|
||||||
blobstream.unsetDevice();
|
blobstream.unsetDevice();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; ++i) {
|
||||||
for (int j = 0; j < bufferCount; j++) {
|
for (int j = 0; j < bufferCount; ++j) {
|
||||||
if (!blobstream.atEnd()) {
|
if (!blobstream.atEnd()) {
|
||||||
T value;
|
T value;
|
||||||
blobstream >> value;
|
blobstream >> value;
|
||||||
|
@ -1893,7 +1916,7 @@ bool GLTFSerializer::addArrayFromAccessor(GLTFAccessor& accessor, QVector<T>& ou
|
||||||
success = addArrayOfType(buffer.blob, bufferview.byteOffset + accBoffset, accessor.count, outarray, accessor.type,
|
success = addArrayOfType(buffer.blob, bufferview.byteOffset + accBoffset, accessor.count, outarray, accessor.type,
|
||||||
accessor.componentType);
|
accessor.componentType);
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < accessor.count; i++) {
|
for (int i = 0; i < accessor.count; ++i) {
|
||||||
T value;
|
T value;
|
||||||
memset(&value, 0, sizeof(T)); // Make sure the dummy array is initalised to zero.
|
memset(&value, 0, sizeof(T)); // Make sure the dummy array is initalised to zero.
|
||||||
outarray.push_back(value);
|
outarray.push_back(value);
|
||||||
|
@ -1924,10 +1947,10 @@ bool GLTFSerializer::addArrayFromAccessor(GLTFAccessor& accessor, QVector<T>& ou
|
||||||
accessor.sparse.count, out_sparse_values_array, accessor.type, accessor.componentType);
|
accessor.sparse.count, out_sparse_values_array, accessor.type, accessor.componentType);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
for (int i = 0; i < accessor.sparse.count; i++) {
|
for (int i = 0; i < accessor.sparse.count; ++i) {
|
||||||
if ((i * 3) + 2 < out_sparse_values_array.size()) {
|
if ((i * 3) + 2 < out_sparse_values_array.size()) {
|
||||||
if ((out_sparse_indices_array[i] * 3) + 2 < outarray.length()) {
|
if ((out_sparse_indices_array[i] * 3) + 2 < outarray.length()) {
|
||||||
for (int j = 0; j < 3; j++) {
|
for (int j = 0; j < 3; ++j) {
|
||||||
outarray[(out_sparse_indices_array[i] * 3) + j] = out_sparse_values_array[(i * 3) + j];
|
outarray[(out_sparse_indices_array[i] * 3) + j] = out_sparse_values_array[(i * 3) + j];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace scriptable {
|
||||||
* @property {string} normalMap
|
* @property {string} normalMap
|
||||||
* @property {string} bumpMap
|
* @property {string} bumpMap
|
||||||
* @property {string} occlusionMap
|
* @property {string} occlusionMap
|
||||||
* @property {string} lightmapMap
|
* @property {string} lightMap
|
||||||
* @property {string} scatteringMap
|
* @property {string} scatteringMap
|
||||||
* @property {Mat4|string} texCoordTransform0
|
* @property {Mat4|string} texCoordTransform0
|
||||||
* @property {Mat4|string} texCoordTransform1
|
* @property {Mat4|string} texCoordTransform1
|
||||||
|
@ -91,7 +91,7 @@ namespace scriptable {
|
||||||
QString normalMap;
|
QString normalMap;
|
||||||
QString bumpMap;
|
QString bumpMap;
|
||||||
QString occlusionMap;
|
QString occlusionMap;
|
||||||
QString lightmapMap;
|
QString lightMap;
|
||||||
QString scatteringMap;
|
QString scatteringMap;
|
||||||
std::array<glm::mat4, graphics::Material::NUM_TEXCOORD_TRANSFORMS> texCoordTransforms;
|
std::array<glm::mat4, graphics::Material::NUM_TEXCOORD_TRANSFORMS> texCoordTransforms;
|
||||||
|
|
||||||
|
|
|
@ -430,10 +430,10 @@ namespace scriptable {
|
||||||
obj.setProperty("occlusionMap", material.occlusionMap);
|
obj.setProperty("occlusionMap", material.occlusionMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::LIGHTMAP_MAP_BIT)) {
|
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::LIGHT_MAP_BIT)) {
|
||||||
obj.setProperty("lightmapMap", FALLTHROUGH);
|
obj.setProperty("lightMap", FALLTHROUGH);
|
||||||
} else if (!material.lightmapMap.isEmpty()) {
|
} else if (!material.lightMap.isEmpty()) {
|
||||||
obj.setProperty("lightmapMap", material.lightmapMap);
|
obj.setProperty("lightMap", material.lightMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::SCATTERING_MAP_BIT)) {
|
if (hasPropertyFallthroughs && material.propertyFallthroughs.at(graphics::MaterialKey::SCATTERING_MAP_BIT)) {
|
||||||
|
|
|
@ -39,7 +39,7 @@ scriptable::ScriptableMaterial& scriptable::ScriptableMaterial::operator=(const
|
||||||
normalMap = material.normalMap;
|
normalMap = material.normalMap;
|
||||||
bumpMap = material.bumpMap;
|
bumpMap = material.bumpMap;
|
||||||
occlusionMap = material.occlusionMap;
|
occlusionMap = material.occlusionMap;
|
||||||
lightmapMap = material.lightmapMap;
|
lightMap = material.lightMap;
|
||||||
scatteringMap = material.scatteringMap;
|
scatteringMap = material.scatteringMap;
|
||||||
|
|
||||||
defaultFallthrough = material.defaultFallthrough;
|
defaultFallthrough = material.defaultFallthrough;
|
||||||
|
@ -110,9 +110,9 @@ scriptable::ScriptableMaterial::ScriptableMaterial(const graphics::MaterialPoint
|
||||||
occlusionMap = map->getTextureSource()->getUrl().toString();
|
occlusionMap = map->getTextureSource()->getUrl().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
map = material->getTextureMap(graphics::Material::MapChannel::LIGHTMAP_MAP);
|
map = material->getTextureMap(graphics::Material::MapChannel::LIGHT_MAP);
|
||||||
if (map && map->getTextureSource()) {
|
if (map && map->getTextureSource()) {
|
||||||
lightmapMap = map->getTextureSource()->getUrl().toString();
|
lightMap = map->getTextureSource()->getUrl().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
map = material->getTextureMap(graphics::Material::MapChannel::SCATTERING_MAP);
|
map = material->getTextureMap(graphics::Material::MapChannel::SCATTERING_MAP);
|
||||||
|
|
|
@ -129,7 +129,7 @@ void Material::setTextureMap(MapChannel channel, const TextureMapPointer& textur
|
||||||
_texcoordTransforms[1] = (textureMap ? textureMap->getTextureTransform().getMatrix() : glm::mat4());
|
_texcoordTransforms[1] = (textureMap ? textureMap->getTextureTransform().getMatrix() : glm::mat4());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel == MaterialKey::LIGHTMAP_MAP) {
|
if (channel == MaterialKey::LIGHT_MAP) {
|
||||||
// update the texcoord1 with lightmap
|
// update the texcoord1 with lightmap
|
||||||
_texcoordTransforms[1] = (textureMap ? textureMap->getTextureTransform().getMatrix() : glm::mat4());
|
_texcoordTransforms[1] = (textureMap ? textureMap->getTextureTransform().getMatrix() : glm::mat4());
|
||||||
_lightmapParams = (textureMap ? glm::vec2(textureMap->getLightmapOffsetScale()) : glm::vec2(0.0, 1.0));
|
_lightmapParams = (textureMap ? glm::vec2(textureMap->getLightmapOffsetScale()) : glm::vec2(0.0, 1.0));
|
||||||
|
|
|
@ -53,7 +53,7 @@ public:
|
||||||
ROUGHNESS_MAP_BIT,
|
ROUGHNESS_MAP_BIT,
|
||||||
NORMAL_MAP_BIT,
|
NORMAL_MAP_BIT,
|
||||||
OCCLUSION_MAP_BIT,
|
OCCLUSION_MAP_BIT,
|
||||||
LIGHTMAP_MAP_BIT,
|
LIGHT_MAP_BIT,
|
||||||
SCATTERING_MAP_BIT,
|
SCATTERING_MAP_BIT,
|
||||||
|
|
||||||
NUM_FLAGS,
|
NUM_FLAGS,
|
||||||
|
@ -67,7 +67,7 @@ public:
|
||||||
ROUGHNESS_MAP,
|
ROUGHNESS_MAP,
|
||||||
NORMAL_MAP,
|
NORMAL_MAP,
|
||||||
OCCLUSION_MAP,
|
OCCLUSION_MAP,
|
||||||
LIGHTMAP_MAP,
|
LIGHT_MAP,
|
||||||
SCATTERING_MAP,
|
SCATTERING_MAP,
|
||||||
|
|
||||||
NUM_MAP_CHANNELS,
|
NUM_MAP_CHANNELS,
|
||||||
|
@ -107,7 +107,7 @@ public:
|
||||||
|
|
||||||
Builder& withNormalMap() { _flags.set(NORMAL_MAP_BIT); return (*this); }
|
Builder& withNormalMap() { _flags.set(NORMAL_MAP_BIT); return (*this); }
|
||||||
Builder& withOcclusionMap() { _flags.set(OCCLUSION_MAP_BIT); return (*this); }
|
Builder& withOcclusionMap() { _flags.set(OCCLUSION_MAP_BIT); return (*this); }
|
||||||
Builder& withLightmapMap() { _flags.set(LIGHTMAP_MAP_BIT); return (*this); }
|
Builder& withLightMap() { _flags.set(LIGHT_MAP_BIT); return (*this); }
|
||||||
Builder& withScatteringMap() { _flags.set(SCATTERING_MAP_BIT); return (*this); }
|
Builder& withScatteringMap() { _flags.set(SCATTERING_MAP_BIT); return (*this); }
|
||||||
|
|
||||||
// Convenient standard keys that we will keep on using all over the place
|
// Convenient standard keys that we will keep on using all over the place
|
||||||
|
@ -157,8 +157,8 @@ public:
|
||||||
void setOcclusionMap(bool value) { _flags.set(OCCLUSION_MAP_BIT, value); }
|
void setOcclusionMap(bool value) { _flags.set(OCCLUSION_MAP_BIT, value); }
|
||||||
bool isOcclusionMap() const { return _flags[OCCLUSION_MAP_BIT]; }
|
bool isOcclusionMap() const { return _flags[OCCLUSION_MAP_BIT]; }
|
||||||
|
|
||||||
void setLightmapMap(bool value) { _flags.set(LIGHTMAP_MAP_BIT, value); }
|
void setLightMap(bool value) { _flags.set(LIGHT_MAP_BIT, value); }
|
||||||
bool isLightmapMap() const { return _flags[LIGHTMAP_MAP_BIT]; }
|
bool isLightMap() const { return _flags[LIGHT_MAP_BIT]; }
|
||||||
|
|
||||||
void setScattering(bool value) { _flags.set(SCATTERING_VAL_BIT, value); }
|
void setScattering(bool value) { _flags.set(SCATTERING_VAL_BIT, value); }
|
||||||
bool isScattering() const { return _flags[SCATTERING_VAL_BIT]; }
|
bool isScattering() const { return _flags[SCATTERING_VAL_BIT]; }
|
||||||
|
@ -235,8 +235,8 @@ public:
|
||||||
Builder& withoutOcclusionMap() { _value.reset(MaterialKey::OCCLUSION_MAP_BIT); _mask.set(MaterialKey::OCCLUSION_MAP_BIT); return (*this); }
|
Builder& withoutOcclusionMap() { _value.reset(MaterialKey::OCCLUSION_MAP_BIT); _mask.set(MaterialKey::OCCLUSION_MAP_BIT); return (*this); }
|
||||||
Builder& withOcclusionMap() { _value.set(MaterialKey::OCCLUSION_MAP_BIT); _mask.set(MaterialKey::OCCLUSION_MAP_BIT); return (*this); }
|
Builder& withOcclusionMap() { _value.set(MaterialKey::OCCLUSION_MAP_BIT); _mask.set(MaterialKey::OCCLUSION_MAP_BIT); return (*this); }
|
||||||
|
|
||||||
Builder& withoutLightmapMap() { _value.reset(MaterialKey::LIGHTMAP_MAP_BIT); _mask.set(MaterialKey::LIGHTMAP_MAP_BIT); return (*this); }
|
Builder& withoutLightMap() { _value.reset(MaterialKey::LIGHT_MAP_BIT); _mask.set(MaterialKey::LIGHT_MAP_BIT); return (*this); }
|
||||||
Builder& withLightmapMap() { _value.set(MaterialKey::LIGHTMAP_MAP_BIT); _mask.set(MaterialKey::LIGHTMAP_MAP_BIT); return (*this); }
|
Builder& withLightMap() { _value.set(MaterialKey::LIGHT_MAP_BIT); _mask.set(MaterialKey::LIGHT_MAP_BIT); return (*this); }
|
||||||
|
|
||||||
Builder& withoutScattering() { _value.reset(MaterialKey::SCATTERING_VAL_BIT); _mask.set(MaterialKey::SCATTERING_VAL_BIT); return (*this); }
|
Builder& withoutScattering() { _value.reset(MaterialKey::SCATTERING_VAL_BIT); _mask.set(MaterialKey::SCATTERING_VAL_BIT); return (*this); }
|
||||||
Builder& withScattering() { _value.set(MaterialKey::SCATTERING_VAL_BIT); _mask.set(MaterialKey::SCATTERING_VAL_BIT); return (*this); }
|
Builder& withScattering() { _value.set(MaterialKey::SCATTERING_VAL_BIT); _mask.set(MaterialKey::SCATTERING_VAL_BIT); return (*this); }
|
||||||
|
|
|
@ -178,7 +178,7 @@ float fetchScatteringMap(vec2 uv) {
|
||||||
float <$occlusion$> = mix(1.0, fetchOcclusionMap(<$texcoord1$>), float((<$matKey$> & OCCLUSION_MAP_BIT) != 0));
|
float <$occlusion$> = mix(1.0, fetchOcclusionMap(<$texcoord1$>), float((<$matKey$> & OCCLUSION_MAP_BIT) != 0));
|
||||||
<@endif@>
|
<@endif@>
|
||||||
<@if lightmap@>
|
<@if lightmap@>
|
||||||
vec3 <$lightmap$> = fetchLightmapMap(<$texcoord1$>);
|
vec3 <$lightmap$> = fetchLightMap(<$texcoord1$>);
|
||||||
<@endif@>
|
<@endif@>
|
||||||
<@endfunc@>
|
<@endfunc@>
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ float fetchScatteringMap(vec2 uv) {
|
||||||
<$declareMaterialTexMapArrayBuffer()$>
|
<$declareMaterialTexMapArrayBuffer()$>
|
||||||
|
|
||||||
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP) uniform sampler2D emissiveMap;
|
LAYOUT(binding=GRAPHICS_TEXTURE_MATERIAL_EMISSIVE_LIGHTMAP) uniform sampler2D emissiveMap;
|
||||||
vec3 fetchLightmapMap(vec2 uv) {
|
vec3 fetchLightMap(vec2 uv) {
|
||||||
vec2 lightmapParams = getTexMapArray()._lightmapParams;
|
vec2 lightmapParams = getTexMapArray()._lightmapParams;
|
||||||
return (vec3(lightmapParams.x) + lightmapParams.y * texture(emissiveMap, uv).rgb);
|
return (vec3(lightmapParams.x) + lightmapParams.y * texture(emissiveMap, uv).rgb);
|
||||||
}
|
}
|
||||||
|
|
|
@ -362,9 +362,9 @@ std::pair<std::string, std::shared_ptr<NetworkMaterial>> NetworkMaterialResource
|
||||||
if (value.isString()) {
|
if (value.isString()) {
|
||||||
auto valueString = value.toString();
|
auto valueString = value.toString();
|
||||||
if (valueString == FALLTHROUGH) {
|
if (valueString == FALLTHROUGH) {
|
||||||
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::LIGHTMAP_MAP_BIT);
|
material->setPropertyDoesFallthrough(graphics::MaterialKey::FlagBit::LIGHT_MAP_BIT);
|
||||||
} else {
|
} else {
|
||||||
material->setLightmapMap(baseUrl.resolved(valueString));
|
material->setLightMap(baseUrl.resolved(valueString));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (key == "texCoordTransform0") {
|
} else if (key == "texCoordTransform0") {
|
||||||
|
@ -567,12 +567,12 @@ void NetworkMaterial::setScatteringMap(const QUrl& url) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkMaterial::setLightmapMap(const QUrl& url) {
|
void NetworkMaterial::setLightMap(const QUrl& url) {
|
||||||
auto map = fetchTextureMap(url, image::TextureUsage::LIGHTMAP_TEXTURE, MapChannel::LIGHTMAP_MAP);
|
auto map = fetchTextureMap(url, image::TextureUsage::LIGHTMAP_TEXTURE, MapChannel::LIGHT_MAP);
|
||||||
if (map) {
|
if (map) {
|
||||||
//map->setTextureTransform(_lightmapTransform);
|
//map->setTextureTransform(_lightmapTransform);
|
||||||
//map->setLightmapOffsetScale(_lightmapParams.x, _lightmapParams.y);
|
//map->setLightmapOffsetScale(_lightmapParams.x, _lightmapParams.y);
|
||||||
setTextureMap(MapChannel::LIGHTMAP_MAP, map);
|
setTextureMap(MapChannel::LIGHT_MAP, map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -640,14 +640,14 @@ NetworkMaterial::NetworkMaterial(const HFMMaterial& material, const QUrl& textur
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!material.lightmapTexture.filename.isEmpty()) {
|
if (!material.lightmapTexture.filename.isEmpty()) {
|
||||||
auto map = fetchTextureMap(textureBaseUrl, material.lightmapTexture, image::TextureUsage::LIGHTMAP_TEXTURE, MapChannel::LIGHTMAP_MAP);
|
auto map = fetchTextureMap(textureBaseUrl, material.lightmapTexture, image::TextureUsage::LIGHTMAP_TEXTURE, MapChannel::LIGHT_MAP);
|
||||||
if (map) {
|
if (map) {
|
||||||
_lightmapTransform = material.lightmapTexture.transform;
|
_lightmapTransform = material.lightmapTexture.transform;
|
||||||
_lightmapParams = material.lightmapParams;
|
_lightmapParams = material.lightmapParams;
|
||||||
map->setTextureTransform(_lightmapTransform);
|
map->setTextureTransform(_lightmapTransform);
|
||||||
map->setLightmapOffsetScale(_lightmapParams.x, _lightmapParams.y);
|
map->setLightmapOffsetScale(_lightmapParams.x, _lightmapParams.y);
|
||||||
}
|
}
|
||||||
setTextureMap(MapChannel::LIGHTMAP_MAP, map);
|
setTextureMap(MapChannel::LIGHT_MAP, map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -660,7 +660,7 @@ void NetworkMaterial::setTextures(const QVariantMap& textureMap) {
|
||||||
const auto& metallicName = getTextureName(MapChannel::METALLIC_MAP);
|
const auto& metallicName = getTextureName(MapChannel::METALLIC_MAP);
|
||||||
const auto& occlusionName = getTextureName(MapChannel::OCCLUSION_MAP);
|
const auto& occlusionName = getTextureName(MapChannel::OCCLUSION_MAP);
|
||||||
const auto& emissiveName = getTextureName(MapChannel::EMISSIVE_MAP);
|
const auto& emissiveName = getTextureName(MapChannel::EMISSIVE_MAP);
|
||||||
const auto& lightmapName = getTextureName(MapChannel::LIGHTMAP_MAP);
|
const auto& lightmapName = getTextureName(MapChannel::LIGHT_MAP);
|
||||||
const auto& scatteringName = getTextureName(MapChannel::SCATTERING_MAP);
|
const auto& scatteringName = getTextureName(MapChannel::SCATTERING_MAP);
|
||||||
|
|
||||||
if (!albedoName.isEmpty()) {
|
if (!albedoName.isEmpty()) {
|
||||||
|
@ -715,12 +715,12 @@ void NetworkMaterial::setTextures(const QVariantMap& textureMap) {
|
||||||
|
|
||||||
if (!lightmapName.isEmpty()) {
|
if (!lightmapName.isEmpty()) {
|
||||||
auto url = textureMap.contains(lightmapName) ? textureMap[lightmapName].toUrl() : QUrl();
|
auto url = textureMap.contains(lightmapName) ? textureMap[lightmapName].toUrl() : QUrl();
|
||||||
auto map = fetchTextureMap(url, image::TextureUsage::LIGHTMAP_TEXTURE, MapChannel::LIGHTMAP_MAP);
|
auto map = fetchTextureMap(url, image::TextureUsage::LIGHTMAP_TEXTURE, MapChannel::LIGHT_MAP);
|
||||||
if (map) {
|
if (map) {
|
||||||
map->setTextureTransform(_lightmapTransform);
|
map->setTextureTransform(_lightmapTransform);
|
||||||
map->setLightmapOffsetScale(_lightmapParams.x, _lightmapParams.y);
|
map->setLightmapOffsetScale(_lightmapParams.x, _lightmapParams.y);
|
||||||
}
|
}
|
||||||
setTextureMap(MapChannel::LIGHTMAP_MAP, map);
|
setTextureMap(MapChannel::LIGHT_MAP, map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ public:
|
||||||
void setOcclusionMap(const QUrl& url);
|
void setOcclusionMap(const QUrl& url);
|
||||||
void setEmissiveMap(const QUrl& url);
|
void setEmissiveMap(const QUrl& url);
|
||||||
void setScatteringMap(const QUrl& url);
|
void setScatteringMap(const QUrl& url);
|
||||||
void setLightmapMap(const QUrl& url);
|
void setLightMap(const QUrl& url);
|
||||||
|
|
||||||
bool isMissingTexture();
|
bool isMissingTexture();
|
||||||
void checkResetOpacityMap();
|
void checkResetOpacityMap();
|
||||||
|
|
|
@ -115,8 +115,8 @@ ShapeKey MeshPartPayload::getShapeKey() const {
|
||||||
if (drawMaterialKey.isNormalMap()) {
|
if (drawMaterialKey.isNormalMap()) {
|
||||||
builder.withTangents();
|
builder.withTangents();
|
||||||
}
|
}
|
||||||
if (drawMaterialKey.isLightmapMap()) {
|
if (drawMaterialKey.isLightMap()) {
|
||||||
builder.withLightmap();
|
builder.withLightMap();
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
@ -354,7 +354,7 @@ void ModelMeshPartPayload::setShapeKey(bool invalidateShapeKey, PrimitiveMode pr
|
||||||
|
|
||||||
bool isTranslucent = drawMaterialKey.isTranslucent();
|
bool isTranslucent = drawMaterialKey.isTranslucent();
|
||||||
bool hasTangents = drawMaterialKey.isNormalMap() && _hasTangents;
|
bool hasTangents = drawMaterialKey.isNormalMap() && _hasTangents;
|
||||||
bool hasLightmap = drawMaterialKey.isLightmapMap();
|
bool hasLightmap = drawMaterialKey.isLightMap();
|
||||||
bool isUnlit = drawMaterialKey.isUnlit();
|
bool isUnlit = drawMaterialKey.isUnlit();
|
||||||
|
|
||||||
bool isDeformed = _isBlendShaped || _isSkinned;
|
bool isDeformed = _isBlendShaped || _isSkinned;
|
||||||
|
@ -374,7 +374,7 @@ void ModelMeshPartPayload::setShapeKey(bool invalidateShapeKey, PrimitiveMode pr
|
||||||
builder.withTangents();
|
builder.withTangents();
|
||||||
}
|
}
|
||||||
if (hasLightmap) {
|
if (hasLightmap) {
|
||||||
builder.withLightmap();
|
builder.withLightMap();
|
||||||
}
|
}
|
||||||
if (isUnlit) {
|
if (isUnlit) {
|
||||||
builder.withUnlit();
|
builder.withUnlit();
|
||||||
|
|
|
@ -107,7 +107,7 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip
|
||||||
model_translucent_normal_map, nullptr, nullptr);
|
model_translucent_normal_map, nullptr, nullptr);
|
||||||
addPipeline(
|
addPipeline(
|
||||||
// FIXME: Ignore lightmap for translucents meshpart
|
// FIXME: Ignore lightmap for translucents meshpart
|
||||||
Key::Builder().withMaterial().withTranslucent().withLightmap(),
|
Key::Builder().withMaterial().withTranslucent().withLightMap(),
|
||||||
model_translucent, nullptr, nullptr);
|
model_translucent, nullptr, nullptr);
|
||||||
// Same thing but with Fade on
|
// Same thing but with Fade on
|
||||||
addPipeline(
|
addPipeline(
|
||||||
|
@ -127,21 +127,21 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip
|
||||||
model_translucent_normal_map_fade, batchSetter, itemSetter);
|
model_translucent_normal_map_fade, batchSetter, itemSetter);
|
||||||
addPipeline(
|
addPipeline(
|
||||||
// FIXME: Ignore lightmap for translucents meshpart
|
// FIXME: Ignore lightmap for translucents meshpart
|
||||||
Key::Builder().withMaterial().withTranslucent().withLightmap().withFade(),
|
Key::Builder().withMaterial().withTranslucent().withLightMap().withFade(),
|
||||||
model_translucent_fade, batchSetter, itemSetter);
|
model_translucent_fade, batchSetter, itemSetter);
|
||||||
// Lightmapped
|
// Lightmapped
|
||||||
addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withMaterial().withLightmap(),
|
Key::Builder().withMaterial().withLightMap(),
|
||||||
model_lightmap, nullptr, nullptr);
|
model_lightmap, nullptr, nullptr);
|
||||||
addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withMaterial().withLightmap().withTangents(),
|
Key::Builder().withMaterial().withLightMap().withTangents(),
|
||||||
model_lightmap_normal_map, nullptr, nullptr);
|
model_lightmap_normal_map, nullptr, nullptr);
|
||||||
// Same thing but with Fade on
|
// Same thing but with Fade on
|
||||||
addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withMaterial().withLightmap().withFade(),
|
Key::Builder().withMaterial().withLightMap().withFade(),
|
||||||
model_lightmap_fade, batchSetter, itemSetter);
|
model_lightmap_fade, batchSetter, itemSetter);
|
||||||
addPipeline(
|
addPipeline(
|
||||||
Key::Builder().withMaterial().withLightmap().withTangents().withFade(),
|
Key::Builder().withMaterial().withLightMap().withTangents().withFade(),
|
||||||
model_lightmap_normal_map_fade, batchSetter, itemSetter);
|
model_lightmap_normal_map_fade, batchSetter, itemSetter);
|
||||||
|
|
||||||
// matrix palette skinned
|
// matrix palette skinned
|
||||||
|
@ -228,10 +228,10 @@ void initForwardPipelines(ShapePlumber& plumber) {
|
||||||
|
|
||||||
// Opaques
|
// Opaques
|
||||||
addPipeline(Key::Builder().withMaterial(), program::forward_model);
|
addPipeline(Key::Builder().withMaterial(), program::forward_model);
|
||||||
addPipeline(Key::Builder().withMaterial().withLightmap(), program::forward_model_lightmap);
|
addPipeline(Key::Builder().withMaterial().withLightMap(), program::forward_model_lightmap);
|
||||||
addPipeline(Key::Builder().withMaterial().withUnlit(), program::forward_model_unlit);
|
addPipeline(Key::Builder().withMaterial().withUnlit(), program::forward_model_unlit);
|
||||||
addPipeline(Key::Builder().withMaterial().withTangents(), program::forward_model_normal_map);
|
addPipeline(Key::Builder().withMaterial().withTangents(), program::forward_model_normal_map);
|
||||||
addPipeline(Key::Builder().withMaterial().withTangents().withLightmap(), program::forward_model_normal_map_lightmap);
|
addPipeline(Key::Builder().withMaterial().withTangents().withLightMap(), program::forward_model_normal_map_lightmap);
|
||||||
|
|
||||||
// Deformed Opaques
|
// Deformed Opaques
|
||||||
addPipeline(Key::Builder().withMaterial().withDeformed(), program::forward_deformed_model);
|
addPipeline(Key::Builder().withMaterial().withDeformed(), program::forward_deformed_model);
|
||||||
|
@ -581,7 +581,7 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
|
||||||
break;
|
break;
|
||||||
case graphics::MaterialKey::EMISSIVE_MAP_BIT:
|
case graphics::MaterialKey::EMISSIVE_MAP_BIT:
|
||||||
// Lightmap takes precendence over emissive map for legacy reasons
|
// Lightmap takes precendence over emissive map for legacy reasons
|
||||||
if (materialKey.isEmissiveMap() && !materialKey.isLightmapMap()) {
|
if (materialKey.isEmissiveMap() && !materialKey.isLightMap()) {
|
||||||
auto itr = textureMaps.find(graphics::MaterialKey::EMISSIVE_MAP);
|
auto itr = textureMaps.find(graphics::MaterialKey::EMISSIVE_MAP);
|
||||||
if (itr != textureMaps.end()) {
|
if (itr != textureMaps.end()) {
|
||||||
if (itr->second->isDefined()) {
|
if (itr->second->isDefined()) {
|
||||||
|
@ -595,14 +595,14 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
|
||||||
forceDefault = true;
|
forceDefault = true;
|
||||||
}
|
}
|
||||||
schemaKey.setEmissiveMap(true);
|
schemaKey.setEmissiveMap(true);
|
||||||
} else if (materialKey.isLightmapMap()) {
|
} else if (materialKey.isLightMap()) {
|
||||||
// We'll set this later when we check the lightmap
|
// We'll set this later when we check the lightmap
|
||||||
wasSet = true;
|
wasSet = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case graphics::MaterialKey::LIGHTMAP_MAP_BIT:
|
case graphics::MaterialKey::LIGHT_MAP_BIT:
|
||||||
if (materialKey.isLightmapMap()) {
|
if (materialKey.isLightMap()) {
|
||||||
auto itr = textureMaps.find(graphics::MaterialKey::LIGHTMAP_MAP);
|
auto itr = textureMaps.find(graphics::MaterialKey::LIGHT_MAP);
|
||||||
if (itr != textureMaps.end()) {
|
if (itr != textureMaps.end()) {
|
||||||
if (itr->second->isDefined()) {
|
if (itr->second->isDefined()) {
|
||||||
drawMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, itr->second->getTextureView());
|
drawMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, itr->second->getTextureView());
|
||||||
|
@ -614,7 +614,7 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
|
||||||
} else {
|
} else {
|
||||||
forceDefault = true;
|
forceDefault = true;
|
||||||
}
|
}
|
||||||
schemaKey.setLightmapMap(true);
|
schemaKey.setLightMap(true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case graphics::Material::TEXCOORDTRANSFORM0:
|
case graphics::Material::TEXCOORDTRANSFORM0:
|
||||||
|
@ -712,12 +712,12 @@ void RenderPipelines::updateMultiMaterial(graphics::MultiMaterial& multiMaterial
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case graphics::MaterialKey::EMISSIVE_MAP_BIT:
|
case graphics::MaterialKey::EMISSIVE_MAP_BIT:
|
||||||
if (schemaKey.isEmissiveMap() && !schemaKey.isLightmapMap()) {
|
if (schemaKey.isEmissiveMap() && !schemaKey.isLightMap()) {
|
||||||
drawMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getGrayTexture());
|
drawMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getGrayTexture());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case graphics::MaterialKey::LIGHTMAP_MAP_BIT:
|
case graphics::MaterialKey::LIGHT_MAP_BIT:
|
||||||
if (schemaKey.isLightmapMap()) {
|
if (schemaKey.isLightMap()) {
|
||||||
drawMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getBlackTexture());
|
drawMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getBlackTexture());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -765,7 +765,7 @@ bool RenderPipelines::bindMaterials(graphics::MultiMaterial& multiMaterial, gpu:
|
||||||
batch.setResourceTextureTable(multiMaterial.getTextureTable());
|
batch.setResourceTextureTable(multiMaterial.getTextureTable());
|
||||||
} else {
|
} else {
|
||||||
if (renderMode != render::Args::RenderMode::SHADOW_RENDER_MODE) {
|
if (renderMode != render::Args::RenderMode::SHADOW_RENDER_MODE) {
|
||||||
if (key.isLightmapMap()) {
|
if (key.isLightMap()) {
|
||||||
defaultMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getBlackTexture());
|
defaultMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getBlackTexture());
|
||||||
} else if (key.isEmissiveMap()) {
|
} else if (key.isEmissiveMap()) {
|
||||||
defaultMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getGrayTexture());
|
defaultMaterialTextures->setTexture(gr::Texture::MaterialEmissiveLightmap, textureCache->getGrayTexture());
|
||||||
|
|
|
@ -558,14 +558,20 @@ void Scene::removeItemTransition(ItemID itemId) {
|
||||||
auto& item = _items[itemId];
|
auto& item = _items[itemId];
|
||||||
TransitionStage::Index transitionId = item.getTransitionId();
|
TransitionStage::Index transitionId = item.getTransitionId();
|
||||||
if (!render::TransitionStage::isIndexInvalid(transitionId)) {
|
if (!render::TransitionStage::isIndexInvalid(transitionId)) {
|
||||||
auto finishedOperators = _transitionFinishedOperatorMap[transitionId];
|
const auto& transition = transitionStage->getTransition(transitionId);
|
||||||
for (auto finishedOperator : finishedOperators) {
|
const auto transitionOwner = transition.itemId;
|
||||||
if (finishedOperator) {
|
if (transitionOwner == itemId) {
|
||||||
finishedOperator();
|
// No more items will be using this transition. Clean it up.
|
||||||
|
auto finishedOperators = _transitionFinishedOperatorMap[transitionId];
|
||||||
|
for (auto finishedOperator : finishedOperators) {
|
||||||
|
if (finishedOperator) {
|
||||||
|
finishedOperator();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
_transitionFinishedOperatorMap.erase(transitionId);
|
||||||
|
transitionStage->removeTransition(transitionId);
|
||||||
}
|
}
|
||||||
_transitionFinishedOperatorMap.erase(transitionId);
|
|
||||||
transitionStage->removeTransition(transitionId);
|
|
||||||
setItemTransition(itemId, render::TransitionStage::INVALID_INDEX);
|
setItemTransition(itemId, render::TransitionStage::INVALID_INDEX);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ public:
|
||||||
|
|
||||||
Builder& withMaterial() { _flags.set(MATERIAL); return (*this); }
|
Builder& withMaterial() { _flags.set(MATERIAL); return (*this); }
|
||||||
Builder& withTranslucent() { _flags.set(TRANSLUCENT); return (*this); }
|
Builder& withTranslucent() { _flags.set(TRANSLUCENT); return (*this); }
|
||||||
Builder& withLightmap() { _flags.set(LIGHTMAP); return (*this); }
|
Builder& withLightMap() { _flags.set(LIGHTMAP); return (*this); }
|
||||||
Builder& withTangents() { _flags.set(TANGENTS); return (*this); }
|
Builder& withTangents() { _flags.set(TANGENTS); return (*this); }
|
||||||
Builder& withUnlit() { _flags.set(UNLIT); return (*this); }
|
Builder& withUnlit() { _flags.set(UNLIT); return (*this); }
|
||||||
Builder& withDeformed() { _flags.set(DEFORMED); return (*this); }
|
Builder& withDeformed() { _flags.set(DEFORMED); return (*this); }
|
||||||
|
@ -116,8 +116,8 @@ public:
|
||||||
Builder& withTranslucent() { _flags.set(TRANSLUCENT); _mask.set(TRANSLUCENT); return (*this); }
|
Builder& withTranslucent() { _flags.set(TRANSLUCENT); _mask.set(TRANSLUCENT); return (*this); }
|
||||||
Builder& withOpaque() { _flags.reset(TRANSLUCENT); _mask.set(TRANSLUCENT); return (*this); }
|
Builder& withOpaque() { _flags.reset(TRANSLUCENT); _mask.set(TRANSLUCENT); return (*this); }
|
||||||
|
|
||||||
Builder& withLightmap() { _flags.set(LIGHTMAP); _mask.set(LIGHTMAP); return (*this); }
|
Builder& withLightMap() { _flags.set(LIGHTMAP); _mask.set(LIGHTMAP); return (*this); }
|
||||||
Builder& withoutLightmap() { _flags.reset(LIGHTMAP); _mask.set(LIGHTMAP); return (*this); }
|
Builder& withoutLightMap() { _flags.reset(LIGHTMAP); _mask.set(LIGHTMAP); return (*this); }
|
||||||
|
|
||||||
Builder& withTangents() { _flags.set(TANGENTS); _mask.set(TANGENTS); return (*this); }
|
Builder& withTangents() { _flags.set(TANGENTS); _mask.set(TANGENTS); return (*this); }
|
||||||
Builder& withoutTangents() { _flags.reset(TANGENTS); _mask.set(TANGENTS); return (*this); }
|
Builder& withoutTangents() { _flags.reset(TANGENTS); _mask.set(TANGENTS); return (*this); }
|
||||||
|
@ -160,7 +160,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
bool useMaterial() const { return _flags[MATERIAL]; }
|
bool useMaterial() const { return _flags[MATERIAL]; }
|
||||||
bool hasLightmap() const { return _flags[LIGHTMAP]; }
|
bool hasLightMap() const { return _flags[LIGHTMAP]; }
|
||||||
bool hasTangents() const { return _flags[TANGENTS]; }
|
bool hasTangents() const { return _flags[TANGENTS]; }
|
||||||
bool isUnlit() const { return _flags[UNLIT]; }
|
bool isUnlit() const { return _flags[UNLIT]; }
|
||||||
bool isTranslucent() const { return _flags[TRANSLUCENT]; }
|
bool isTranslucent() const { return _flags[TRANSLUCENT]; }
|
||||||
|
@ -199,7 +199,7 @@ inline QDebug operator<<(QDebug debug, const ShapeKey& key) {
|
||||||
} else {
|
} else {
|
||||||
debug << "[ShapeKey:"
|
debug << "[ShapeKey:"
|
||||||
<< "useMaterial:" << key.useMaterial()
|
<< "useMaterial:" << key.useMaterial()
|
||||||
<< "hasLightmap:" << key.hasLightmap()
|
<< "hasLightmap:" << key.hasLightMap()
|
||||||
<< "hasTangents:" << key.hasTangents()
|
<< "hasTangents:" << key.hasTangents()
|
||||||
<< "isUnlit:" << key.isUnlit()
|
<< "isUnlit:" << key.isUnlit()
|
||||||
<< "isTranslucent:" << key.isTranslucent()
|
<< "isTranslucent:" << key.isTranslucent()
|
||||||
|
|
|
@ -38,7 +38,7 @@ class Camera : public QObject {
|
||||||
|
|
||||||
Q_PROPERTY(glm::vec3 position READ getPosition WRITE setPosition)
|
Q_PROPERTY(glm::vec3 position READ getPosition WRITE setPosition)
|
||||||
Q_PROPERTY(glm::quat orientation READ getOrientation WRITE setOrientation)
|
Q_PROPERTY(glm::quat orientation READ getOrientation WRITE setOrientation)
|
||||||
Q_PROPERTY(QString mode READ getModeString WRITE setModeString)
|
Q_PROPERTY(QString mode READ getModeString WRITE setModeString NOTIFY modeUpdated)
|
||||||
Q_PROPERTY(QVariantMap frustum READ getViewFrustum CONSTANT)
|
Q_PROPERTY(QVariantMap frustum READ getViewFrustum CONSTANT)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in a new issue