From b8b61e7c62a8ad6dd891111064cdedc9cb432502 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Thu, 11 Jun 2015 15:51:21 -0700 Subject: [PATCH 01/41] integrated joysticks with userinputmapper, enabling plug-in-and-play controllers and input mapping with js --- interface/src/Application.cpp | 6 +- interface/src/devices/Joystick.cpp | 177 ++++++++++++++++-- interface/src/devices/Joystick.h | 51 +++-- .../SDL2Manager.cpp} | 101 +++++----- .../SDL2Manager.h} | 82 +++----- interface/src/ui/UserInputMapper.cpp | 5 + interface/src/ui/UserInputMapper.h | 1 + 7 files changed, 278 insertions(+), 145 deletions(-) rename interface/src/{scripting/JoystickScriptingInterface.cpp => devices/SDL2Manager.cpp} (62%) rename interface/src/{scripting/JoystickScriptingInterface.h => devices/SDL2Manager.h} (53%) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 750955dc6a..e126882004 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -113,6 +113,7 @@ #include "devices/Faceshift.h" #include "devices/Leapmotion.h" #include "devices/RealSense.h" +#include "devices/SDL2Manager.h" #include "devices/MIDIManager.h" #include "devices/OculusManager.h" #include "devices/TV3DManager.h" @@ -127,7 +128,6 @@ #include "scripting/AudioDeviceScriptingInterface.h" #include "scripting/ClipboardScriptingInterface.h" #include "scripting/HMDScriptingInterface.h" -#include "scripting/JoystickScriptingInterface.h" #include "scripting/GlobalServicesScriptingInterface.h" #include "scripting/LocationScriptingInterface.h" #include "scripting/MenuScriptingInterface.h" @@ -1455,6 +1455,7 @@ void Application::keyReleaseEvent(QKeyEvent* event) { void Application::focusOutEvent(QFocusEvent* event) { _keyboardMouseDevice.focusOutEvent(event); + SDL2Manager::getInstance()->focusOutEvent(); // synthesize events for keys currently pressed, since we may not get their release events foreach (int key, _keysPressed) { @@ -2450,7 +2451,7 @@ void Application::update(float deltaTime) { } SixenseManager::getInstance().update(deltaTime); - JoystickScriptingInterface::getInstance().update(); + SDL2Manager::getInstance()->update(); } _userInputMapper.update(deltaTime); @@ -4045,7 +4046,6 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri scriptEngine->registerGlobalObject("AvatarManager", DependencyManager::get().data()); - scriptEngine->registerGlobalObject("Joysticks", &JoystickScriptingInterface::getInstance()); qScriptRegisterMetaType(scriptEngine, joystickToScriptValue, joystickFromScriptValue); scriptEngine->registerGlobalObject("UndoStack", &_undoStackScriptingInterface); diff --git a/interface/src/devices/Joystick.cpp b/interface/src/devices/Joystick.cpp index 8b225437c2..659e5fa175 100644 --- a/interface/src/devices/Joystick.cpp +++ b/interface/src/devices/Joystick.cpp @@ -13,8 +13,11 @@ #include +#include "Application.h" + #include "Joystick.h" +const float CONTROLLER_THRESHOLD = .25f; #ifdef HAVE_SDL2 const float MAX_AXIS = 32768.0f; @@ -22,10 +25,7 @@ const float MAX_AXIS = 32768.0f; Joystick::Joystick(SDL_JoystickID instanceId, const QString& name, SDL_GameController* sdlGameController) : _sdlGameController(sdlGameController), _sdlJoystick(SDL_GameControllerGetJoystick(_sdlGameController)), - _instanceId(instanceId), - _name(name), - _axes(QVector(SDL_JoystickNumAxes(_sdlJoystick))), - _buttons(QVector(SDL_JoystickNumButtons(_sdlJoystick))) + _instanceId(instanceId) { } @@ -42,24 +42,171 @@ void Joystick::closeJoystick() { #endif } +void Joystick::update() { + for (auto axisState : _axisStateMap) { + if (axisState.second < CONTROLLER_THRESHOLD && axisState.second > -CONTROLLER_THRESHOLD) { + _axisStateMap[axisState.first] = 0; + } + } +} + +void Joystick::focusOutEvent() { + _axisStateMap.clear(); + _buttonPressedMap.clear(); +}; #ifdef HAVE_SDL2 void Joystick::handleAxisEvent(const SDL_ControllerAxisEvent& event) { - if (_axes.size() <= event.axis) { - _axes.resize(event.axis + 1); + SDL_GameControllerAxis axis = (SDL_GameControllerAxis) event.axis; + + if (axis == SDL_CONTROLLER_AXIS_LEFTX) { + _axisStateMap[makeInput(LEFT_AXIS_X_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(LEFT_AXIS_X_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + } else if (axis == SDL_CONTROLLER_AXIS_LEFTY) { + _axisStateMap[makeInput(LEFT_AXIS_Y_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(LEFT_AXIS_Y_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + } else if (axis == SDL_CONTROLLER_AXIS_RIGHTX) { + _axisStateMap[makeInput(RIGHT_AXIS_X_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(RIGHT_AXIS_X_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + } else if (axis == SDL_CONTROLLER_AXIS_RIGHTY) { + _axisStateMap[makeInput(RIGHT_AXIS_Y_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(RIGHT_AXIS_Y_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; } - - float oldValue = _axes[event.axis]; - float newValue = event.value / MAX_AXIS; - _axes[event.axis] = newValue; - - emit axisValueChanged(event.axis, newValue, oldValue); + } void Joystick::handleButtonEvent(const SDL_ControllerButtonEvent& event) { - bool oldValue = _buttons[event.button]; + auto input = makeInput((SDL_GameControllerButton) event.button); bool newValue = event.state == SDL_PRESSED; - _buttons[event.button] = newValue; - emit buttonStateChanged(event.button, newValue, oldValue); + if (newValue) { + _buttonPressedMap.insert(input.getChannel()); + } else { + _buttonPressedMap.erase(input.getChannel()); + } } #endif + + +void Joystick::registerToUserInputMapper(UserInputMapper& mapper) { + // Grab the current free device ID + _deviceID = mapper.getFreeDeviceID(); + + auto proxy = UserInputMapper::DeviceProxy::Pointer(new UserInputMapper::DeviceProxy(_name)); + proxy->getButton = [this] (const UserInputMapper::Input& input, int timestamp) -> bool { return this->getButton(input._channel); }; + proxy->getAxis = [this] (const UserInputMapper::Input& input, int timestamp) -> float { return this->getAxis(input._channel); }; + proxy->getAvailabeInputs = [this] () -> QVector { + QVector availableInputs; +#ifdef HAVE_SDL2 + availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_A), "Bottom Button")); + availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_B), "Right Button")); + availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_X), "Left Button")); + availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_Y), "Top Button")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_DPAD_UP), "DPad Up")); + availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_DPAD_DOWN), "DPad Down")); + availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_DPAD_LEFT), "DPad Left")); + availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_DPAD_RIGHT), "DPad Right")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_LEFTSHOULDER), "L1")); + availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), "R1")); +#endif + return availableInputs; + }; + proxy->resetDeviceBindings = [this, &mapper] () -> bool { + mapper.removeAllInputChannelsForDevice(_deviceID); + this->assignDefaultInputMapping(mapper); + return true; + }; + mapper.registerDevice(_deviceID, proxy); +} + +void Joystick::assignDefaultInputMapping(UserInputMapper& mapper) { +#ifdef HAVE_SDL2 + const float JOYSTICK_MOVE_SPEED = 1.0f; + const float DPAD_MOVE_SPEED = .5f; + const float JOYSTICK_YAW_SPEED = 0.5f; + const float JOYSTICK_PITCH_SPEED = 0.25f; + + // Y axes are flipped (up is negative) + // Left Joystick: Movement, strafing + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(LEFT_AXIS_Y_NEG), JOYSTICK_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(LEFT_AXIS_Y_POS), JOYSTICK_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(LEFT_AXIS_X_POS), JOYSTICK_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(LEFT_AXIS_X_NEG), JOYSTICK_MOVE_SPEED); + + // Right Joystick: Camera orientation + mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(RIGHT_AXIS_X_POS), JOYSTICK_YAW_SPEED); + mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(RIGHT_AXIS_X_NEG), JOYSTICK_YAW_SPEED); + mapper.addInputChannel(UserInputMapper::PITCH_UP, makeInput(RIGHT_AXIS_Y_NEG), JOYSTICK_PITCH_SPEED); + mapper.addInputChannel(UserInputMapper::PITCH_DOWN, makeInput(RIGHT_AXIS_Y_POS), JOYSTICK_PITCH_SPEED); + + // Dpad movement + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(SDL_CONTROLLER_BUTTON_DPAD_UP), DPAD_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(SDL_CONTROLLER_BUTTON_DPAD_DOWN), DPAD_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(SDL_CONTROLLER_BUTTON_DPAD_RIGHT), DPAD_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(SDL_CONTROLLER_BUTTON_DPAD_LEFT), DPAD_MOVE_SPEED); + + // Button controls + mapper.addInputChannel(UserInputMapper::VERTICAL_UP, makeInput(SDL_CONTROLLER_BUTTON_Y), DPAD_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(SDL_CONTROLLER_BUTTON_A), DPAD_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(SDL_CONTROLLER_BUTTON_X), JOYSTICK_YAW_SPEED); + mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(SDL_CONTROLLER_BUTTON_B), JOYSTICK_YAW_SPEED); + + + // Hold front right shoulder button for precision controls + // Left Joystick: Movement, strafing + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(LEFT_AXIS_Y_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.); + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(LEFT_AXIS_Y_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.); + mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(LEFT_AXIS_X_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.); + mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(LEFT_AXIS_X_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.); + + // Right Joystick: Camera orientation + mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(RIGHT_AXIS_X_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.); + mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(RIGHT_AXIS_X_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.); + mapper.addInputChannel(UserInputMapper::PITCH_UP, makeInput(RIGHT_AXIS_Y_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_PITCH_SPEED/2.); + mapper.addInputChannel(UserInputMapper::PITCH_DOWN, makeInput(RIGHT_AXIS_Y_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_PITCH_SPEED/2.); + + // Dpad movement + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(SDL_CONTROLLER_BUTTON_DPAD_UP), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(SDL_CONTROLLER_BUTTON_DPAD_DOWN), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); + mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(SDL_CONTROLLER_BUTTON_DPAD_RIGHT), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); + mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(SDL_CONTROLLER_BUTTON_DPAD_LEFT), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); + + // Button controls + mapper.addInputChannel(UserInputMapper::VERTICAL_UP, makeInput(SDL_CONTROLLER_BUTTON_Y), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); + mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(SDL_CONTROLLER_BUTTON_A), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); + mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(SDL_CONTROLLER_BUTTON_X), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.); + mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(SDL_CONTROLLER_BUTTON_B), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.); +#endif +} + +float Joystick::getButton(int channel) const { + if (!_buttonPressedMap.empty()) { + if (_buttonPressedMap.find(channel) != _buttonPressedMap.end()) { + return 1.0f; + } else { + return 0.0f; + } + } + return 0.0f; +} + +float Joystick::getAxis(int channel) const { + auto axis = _axisStateMap.find(channel); + if (axis != _axisStateMap.end()) { + return (*axis).second; + } else { + return 0.0f; + } +} + +#ifdef HAVE_SDL2 +UserInputMapper::Input Joystick::makeInput(SDL_GameControllerButton button) { + return UserInputMapper::Input(_deviceID, button, UserInputMapper::ChannelType::BUTTON); +} +#endif + +UserInputMapper::Input Joystick::makeInput(Joystick::JoystickAxisChannel axis) { + return UserInputMapper::Input(_deviceID, axis, UserInputMapper::ChannelType::AXIS); +} + diff --git a/interface/src/devices/Joystick.h b/interface/src/devices/Joystick.h index eeeeb03759..c5ca7a6f7f 100644 --- a/interface/src/devices/Joystick.h +++ b/interface/src/devices/Joystick.h @@ -20,6 +20,8 @@ #undef main #endif +#include "ui/UserInputMapper.h" + class Joystick : public QObject { Q_OBJECT @@ -29,12 +31,38 @@ class Joystick : public QObject { Q_PROPERTY(int instanceId READ getInstanceId) #endif - Q_PROPERTY(int numAxes READ getNumAxes) - Q_PROPERTY(int numButtons READ getNumButtons) public: + enum JoystickAxisChannel { + LEFT_AXIS_X_POS = 0, + LEFT_AXIS_X_NEG, + LEFT_AXIS_Y_POS, + LEFT_AXIS_Y_NEG, + RIGHT_AXIS_X_POS, + RIGHT_AXIS_X_NEG, + RIGHT_AXIS_Y_POS, + RIGHT_AXIS_Y_NEG, + }; + Joystick(); ~Joystick(); + typedef std::unordered_set ButtonPressedMap; + typedef std::map AxisStateMap; + + float getButton(int channel) const; + float getAxis(int channel) const; + +#ifdef HAVE_SDL2 + UserInputMapper::Input makeInput(SDL_GameControllerButton button); +#endif + UserInputMapper::Input makeInput(Joystick::JoystickAxisChannel axis); + + void registerToUserInputMapper(UserInputMapper& mapper); + void assignDefaultInputMapping(UserInputMapper& mapper); + + void update(); + void focusOutEvent(); + #ifdef HAVE_SDL2 Joystick(SDL_JoystickID instanceId, const QString& name, SDL_GameController* sdlGameController); #endif @@ -51,15 +79,8 @@ public: int getInstanceId() const { return _instanceId; } #endif - const QVector& getAxes() const { return _axes; } - const QVector& getButtons() const { return _buttons; } + int getDeviceID() { return _deviceID; } - int getNumAxes() const { return _axes.size(); } - int getNumButtons() const { return _buttons.size(); } - -signals: - void axisValueChanged(int axis, float newValue, float oldValue); - void buttonStateChanged(int button, float newValue, float oldValue); private: #ifdef HAVE_SDL2 SDL_GameController* _sdlGameController; @@ -68,8 +89,12 @@ private: #endif QString _name; - QVector _axes; - QVector _buttons; + +protected: + int _deviceID = 0; + + ButtonPressedMap _buttonPressedMap; + AxisStateMap _axisStateMap; }; -#endif // hifi_JoystickTracker_h +#endif // hifi_Joystick_h diff --git a/interface/src/scripting/JoystickScriptingInterface.cpp b/interface/src/devices/SDL2Manager.cpp similarity index 62% rename from interface/src/scripting/JoystickScriptingInterface.cpp rename to interface/src/devices/SDL2Manager.cpp index 0490b1f704..32408fce18 100644 --- a/interface/src/scripting/JoystickScriptingInterface.cpp +++ b/interface/src/devices/SDL2Manager.cpp @@ -1,73 +1,66 @@ // -// JoystickScriptingInterface.cpp +// SDL2Manager.cpp // interface/src/devices // -// Created by Andrzej Kapolka on 5/15/14. -// Copyright 2014 High Fidelity, Inc. +// Created by Sam Gondelman on 6/5/15. +// Copyright 2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include -#include -#include - -#ifdef HAVE_SDL2 -#include -#undef main -#endif #include #include #include -#include "Application.h" +#include "Application.h" -#include "JoystickScriptingInterface.h" +#include "SDL2Manager.h" #ifdef HAVE_SDL2 -SDL_JoystickID getInstanceId(SDL_GameController* controller) { +SDL_JoystickID SDL2Manager::getInstanceId(SDL_GameController* controller) { SDL_Joystick* joystick = SDL_GameControllerGetJoystick(controller); return SDL_JoystickInstanceID(joystick); } #endif -JoystickScriptingInterface& JoystickScriptingInterface::getInstance() { - static JoystickScriptingInterface sharedInstance; - return sharedInstance; -} - -JoystickScriptingInterface::JoystickScriptingInterface() : +SDL2Manager::SDL2Manager() : #ifdef HAVE_SDL2 - _openJoysticks(), +_openJoysticks(), #endif - _isInitialized(false) +_isInitialized(false) { #ifdef HAVE_SDL2 bool initSuccess = (SDL_Init(SDL_INIT_GAMECONTROLLER) == 0); if (initSuccess) { int joystickCount = SDL_NumJoysticks(); - + for (int i = 0; i < joystickCount; i++) { SDL_GameController* controller = SDL_GameControllerOpen(i); if (controller) { SDL_JoystickID id = getInstanceId(controller); - Joystick* joystick = new Joystick(id, SDL_GameControllerName(controller), controller); - _openJoysticks[id] = joystick; + if (!_openJoysticks.contains(id)) { + Joystick* joystick = new Joystick(id, SDL_GameControllerName(controller), controller); + _openJoysticks[id] = joystick; + joystick->registerToUserInputMapper(*Application::getUserInputMapper()); + joystick->assignDefaultInputMapping(*Application::getUserInputMapper()); + emit joystickAdded(joystick); + } } } - + _isInitialized = true; } else { - qDebug() << "Error initializing SDL"; + qDebug() << "Error initializing SDL2 Manager"; } #endif } -JoystickScriptingInterface::~JoystickScriptingInterface() { +SDL2Manager::~SDL2Manager() { #ifdef HAVE_SDL2 qDeleteAll(_openJoysticks); @@ -75,34 +68,25 @@ JoystickScriptingInterface::~JoystickScriptingInterface() { #endif } -const QObjectList JoystickScriptingInterface::getAllJoysticks() const { - QObjectList objectList; -#ifdef HAVE_SDL2 - const QList joystickList = _openJoysticks.values(); - for (int i = 0; i < joystickList.length(); i++) { - objectList << joystickList[i]; - } -#endif - return objectList; +SDL2Manager* SDL2Manager::getInstance() { + static SDL2Manager sharedInstance; + return &sharedInstance; } -Joystick* JoystickScriptingInterface::joystickWithName(const QString& name) { -#ifdef HAVE_SDL2 - QMap::iterator iter = _openJoysticks.begin(); - while (iter != _openJoysticks.end()) { - if (iter.value()->getName() == name) { - return iter.value(); - } - iter++; +void SDL2Manager::focusOutEvent() { + for (auto joystick : _openJoysticks) { + joystick->focusOutEvent(); } -#endif - return NULL; } -void JoystickScriptingInterface::update() { +void SDL2Manager::update() { #ifdef HAVE_SDL2 if (_isInitialized) { - PerformanceTimer perfTimer("JoystickScriptingInterface::update"); + for (auto joystick : _openJoysticks) { + joystick->update(); + } + + PerformanceTimer perfTimer("SDL2Manager::update"); SDL_GameControllerUpdate(); SDL_Event event; while (SDL_PollEvent(&event)) { @@ -120,16 +104,16 @@ void JoystickScriptingInterface::update() { if (event.cbutton.button == SDL_CONTROLLER_BUTTON_BACK) { // this will either start or stop a global back event QEvent::Type backType = (event.type == SDL_CONTROLLERBUTTONDOWN) - ? HFBackEvent::startType() - : HFBackEvent::endType(); + ? HFBackEvent::startType() + : HFBackEvent::endType(); HFBackEvent backEvent(backType); qApp->sendEvent(qApp, &backEvent); } else if (event.cbutton.button == SDL_CONTROLLER_BUTTON_A) { // this will either start or stop a global action event QEvent::Type actionType = (event.type == SDL_CONTROLLERBUTTONDOWN) - ? HFActionEvent::startType() - : HFActionEvent::endType(); + ? HFActionEvent::startType() + : HFActionEvent::endType(); // global action events fire in the center of the screen Application* app = Application::getInstance(); @@ -141,14 +125,19 @@ void JoystickScriptingInterface::update() { } else if (event.type == SDL_CONTROLLERDEVICEADDED) { SDL_GameController* controller = SDL_GameControllerOpen(event.cdevice.which); - + SDL_JoystickID id = getInstanceId(controller); - Joystick* joystick = new Joystick(id, SDL_GameControllerName(controller), controller); - _openJoysticks[id] = joystick; - emit joystickAdded(joystick); + if (!_openJoysticks.contains(id)) { + Joystick* joystick = new Joystick(id, SDL_GameControllerName(controller), controller); + _openJoysticks[id] = joystick; + joystick->registerToUserInputMapper(*Application::getUserInputMapper()); + joystick->assignDefaultInputMapping(*Application::getUserInputMapper()); + emit joystickAdded(joystick); + } } else if (event.type == SDL_CONTROLLERDEVICEREMOVED) { Joystick* joystick = _openJoysticks[event.cdevice.which]; _openJoysticks.remove(event.cdevice.which); + Application::getUserInputMapper()->removeDevice(joystick->getDeviceID()); emit joystickRemoved(joystick); } } diff --git a/interface/src/scripting/JoystickScriptingInterface.h b/interface/src/devices/SDL2Manager.h similarity index 53% rename from interface/src/scripting/JoystickScriptingInterface.h rename to interface/src/devices/SDL2Manager.h index c9a68d24b1..0a32570ee2 100644 --- a/interface/src/scripting/JoystickScriptingInterface.h +++ b/interface/src/devices/SDL2Manager.h @@ -1,77 +1,46 @@ // -// JoystickScriptingInterface.h +// SDL2Manager.h // interface/src/devices // -// Created by Andrzej Kapolka on 5/15/14. -// Copyright 2014 High Fidelity, Inc. +// Created by Sam Gondelman on 6/5/15. +// Copyright 2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef hifi_JoystickScriptingInterface_h -#define hifi_JoystickScriptingInterface_h - -#include -#include +#ifndef hifi__SDL2Manager_h +#define hifi__SDL2Manager_h #ifdef HAVE_SDL2 #include #endif +#include "ui/UserInputMapper.h" + #include "devices/Joystick.h" -/// Handles joystick input through SDL. -class JoystickScriptingInterface : public QObject { +class SDL2Manager : public QObject { Q_OBJECT - -#ifdef HAVE_SDL2 - Q_PROPERTY(int AXIS_INVALID READ axisInvalid) - Q_PROPERTY(int AXIS_LEFT_X READ axisLeftX) - Q_PROPERTY(int AXIS_LEFT_Y READ axisLeftY) - Q_PROPERTY(int AXIS_RIGHT_X READ axisRightX) - Q_PROPERTY(int AXIS_RIGHT_Y READ axisRightY) - Q_PROPERTY(int AXIS_TRIGGER_LEFT READ axisTriggerLeft) - Q_PROPERTY(int AXIS_TRIGGER_RIGHT READ axisTriggerRight) - Q_PROPERTY(int AXIS_MAX READ axisMax) - - Q_PROPERTY(int BUTTON_INVALID READ buttonInvalid) - Q_PROPERTY(int BUTTON_FACE_BOTTOM READ buttonFaceBottom) - Q_PROPERTY(int BUTTON_FACE_RIGHT READ buttonFaceRight) - Q_PROPERTY(int BUTTON_FACE_LEFT READ buttonFaceLeft) - Q_PROPERTY(int BUTTON_FACE_TOP READ buttonFaceTop) - Q_PROPERTY(int BUTTON_BACK READ buttonBack) - Q_PROPERTY(int BUTTON_GUIDE READ buttonGuide) - Q_PROPERTY(int BUTTON_START READ buttonStart) - Q_PROPERTY(int BUTTON_LEFT_STICK READ buttonLeftStick) - Q_PROPERTY(int BUTTON_RIGHT_STICK READ buttonRightStick) - Q_PROPERTY(int BUTTON_LEFT_SHOULDER READ buttonLeftShoulder) - Q_PROPERTY(int BUTTON_RIGHT_SHOULDER READ buttonRightShoulder) - Q_PROPERTY(int BUTTON_DPAD_UP READ buttonDpadUp) - Q_PROPERTY(int BUTTON_DPAD_DOWN READ buttonDpadDown) - Q_PROPERTY(int BUTTON_DPAD_LEFT READ buttonDpadLeft) - Q_PROPERTY(int BUTTON_DPAD_RIGHT READ buttonDpadRight) - Q_PROPERTY(int BUTTON_MAX READ buttonMax) - - Q_PROPERTY(int BUTTON_PRESSED READ buttonPressed) - Q_PROPERTY(int BUTTON_RELEASED READ buttonRelease) -#endif - + public: - static JoystickScriptingInterface& getInstance(); - + SDL2Manager(); + ~SDL2Manager(); + + void focusOutEvent(); + void update(); - -public slots: - Joystick* joystickWithName(const QString& name); - const QObjectList getAllJoysticks() const; - + + static SDL2Manager* getInstance(); + signals: void joystickAdded(Joystick* joystick); void joystickRemoved(Joystick* joystick); - + private: #ifdef HAVE_SDL2 + SDL_JoystickID getInstanceId(SDL_GameController* controller); + int axisInvalid() const { return SDL_CONTROLLER_AXIS_INVALID; } int axisLeftX() const { return SDL_CONTROLLER_AXIS_LEFTX; } int axisLeftY() const { return SDL_CONTROLLER_AXIS_LEFTY; } @@ -80,7 +49,7 @@ private: int axisTriggerLeft() const { return SDL_CONTROLLER_AXIS_TRIGGERLEFT; } int axisTriggerRight() const { return SDL_CONTROLLER_AXIS_TRIGGERRIGHT; } int axisMax() const { return SDL_CONTROLLER_AXIS_MAX; } - + int buttonInvalid() const { return SDL_CONTROLLER_BUTTON_INVALID; } int buttonFaceBottom() const { return SDL_CONTROLLER_BUTTON_A; } int buttonFaceRight() const { return SDL_CONTROLLER_BUTTON_B; } @@ -98,18 +67,15 @@ private: int buttonDpadLeft() const { return SDL_CONTROLLER_BUTTON_DPAD_LEFT; } int buttonDpadRight() const { return SDL_CONTROLLER_BUTTON_DPAD_RIGHT; } int buttonMax() const { return SDL_CONTROLLER_BUTTON_MAX; } - + int buttonPressed() const { return SDL_PRESSED; } int buttonRelease() const { return SDL_RELEASED; } #endif - - JoystickScriptingInterface(); - ~JoystickScriptingInterface(); - + #ifdef HAVE_SDL2 QMap _openJoysticks; #endif bool _isInitialized; }; -#endif // hifi_JoystickScriptingInterface_h +#endif // hifi__SDL2Manager_h diff --git a/interface/src/ui/UserInputMapper.cpp b/interface/src/ui/UserInputMapper.cpp index e994b3cf30..2c28b79c75 100755 --- a/interface/src/ui/UserInputMapper.cpp +++ b/interface/src/ui/UserInputMapper.cpp @@ -106,6 +106,11 @@ void UserInputMapper::removeAllInputChannelsForDevice(uint16 device) { } } +void UserInputMapper::removeDevice(int device) { + removeAllInputChannelsForDevice((uint16) device); + _registeredDevices.erase(device); +} + int UserInputMapper::getInputChannels(InputChannels& channels) const { for (auto& channel : _actionToInputsMap) { channels.push_back(channel.second); diff --git a/interface/src/ui/UserInputMapper.h b/interface/src/ui/UserInputMapper.h index 0a08e277db..84ca192e3e 100755 --- a/interface/src/ui/UserInputMapper.h +++ b/interface/src/ui/UserInputMapper.h @@ -189,6 +189,7 @@ public: bool removeInputChannel(InputChannel channel); void removeAllInputChannels(); void removeAllInputChannelsForDevice(uint16 device); + void removeDevice(int device); //Grab all the input channels currently in use, return the number int getInputChannels(InputChannels& channels) const; QVector getAllInputsForDevice(uint16 device); From 2bdef6205e5d99f4b7fad1f9fed3dd51ad4b35dd Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Thu, 11 Jun 2015 16:20:46 -0700 Subject: [PATCH 02/41] added more available inputs to joystick and keyboardmousedevice --- interface/src/devices/Joystick.cpp | 10 +++++++ interface/src/devices/KeyboardMouseDevice.cpp | 26 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/interface/src/devices/Joystick.cpp b/interface/src/devices/Joystick.cpp index 659e5fa175..43dc50b252 100644 --- a/interface/src/devices/Joystick.cpp +++ b/interface/src/devices/Joystick.cpp @@ -109,6 +109,16 @@ void Joystick::registerToUserInputMapper(UserInputMapper& mapper) { availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_LEFTSHOULDER), "L1")); availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), "R1")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(LEFT_AXIS_Y_NEG), "Left Stick Up")); + availableInputs.append(UserInputMapper::InputPair(makeInput(LEFT_AXIS_Y_POS), "Left Stick Down")); + availableInputs.append(UserInputMapper::InputPair(makeInput(LEFT_AXIS_X_POS), "Left Stick Right")); + availableInputs.append(UserInputMapper::InputPair(makeInput(LEFT_AXIS_X_NEG), "Left Stick Left")); + availableInputs.append(UserInputMapper::InputPair(makeInput(RIGHT_AXIS_Y_NEG), "Right Stick Up")); + availableInputs.append(UserInputMapper::InputPair(makeInput(RIGHT_AXIS_Y_POS), "Right Stick Down")); + availableInputs.append(UserInputMapper::InputPair(makeInput(RIGHT_AXIS_X_POS), "Right Stick Right")); + availableInputs.append(UserInputMapper::InputPair(makeInput(RIGHT_AXIS_X_NEG), "Right Stick Left")); + #endif return availableInputs; }; diff --git a/interface/src/devices/KeyboardMouseDevice.cpp b/interface/src/devices/KeyboardMouseDevice.cpp index 8a336064e5..5f18c02c7e 100755 --- a/interface/src/devices/KeyboardMouseDevice.cpp +++ b/interface/src/devices/KeyboardMouseDevice.cpp @@ -170,7 +170,33 @@ void KeyboardMouseDevice::registerToUserInputMapper(UserInputMapper& mapper) { for (int i = (int) Qt::Key_A; i <= (int) Qt::Key_Z; i++) { availableInputs.append(UserInputMapper::InputPair(makeInput(Qt::Key(i)), QKeySequence(Qt::Key(i)).toString())); } + for (int i = (int) Qt::Key_Left; i <= (int) Qt::Key_Down; i++) { + availableInputs.append(UserInputMapper::InputPair(makeInput(Qt::Key(i)), QKeySequence(Qt::Key(i)).toString())); + } availableInputs.append(UserInputMapper::InputPair(makeInput(Qt::Key_Space), QKeySequence(Qt::Key_Space).toString())); + availableInputs.append(UserInputMapper::InputPair(makeInput(Qt::Key_Shift), "Shift")); + availableInputs.append(UserInputMapper::InputPair(makeInput(Qt::Key_PageUp), QKeySequence(Qt::Key_PageUp).toString())); + availableInputs.append(UserInputMapper::InputPair(makeInput(Qt::Key_PageDown), QKeySequence(Qt::Key_PageDown).toString())); + + availableInputs.append(UserInputMapper::InputPair(makeInput(Qt::LeftButton), "Left Mouse Click")); + availableInputs.append(UserInputMapper::InputPair(makeInput(Qt::MiddleButton), "Middle Mouse Click")); + availableInputs.append(UserInputMapper::InputPair(makeInput(Qt::RightButton), "Right Mouse Click")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(MOUSE_AXIS_X_POS), "Mouse Move Right")); + availableInputs.append(UserInputMapper::InputPair(makeInput(MOUSE_AXIS_X_NEG), "Mouse Move Left")); + availableInputs.append(UserInputMapper::InputPair(makeInput(MOUSE_AXIS_Y_POS), "Mouse Move Up")); + availableInputs.append(UserInputMapper::InputPair(makeInput(MOUSE_AXIS_Y_NEG), "Mouse Move Down")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(MOUSE_AXIS_WHEEL_Y_POS), "Mouse Wheel Right")); + availableInputs.append(UserInputMapper::InputPair(makeInput(MOUSE_AXIS_WHEEL_Y_NEG), "Mouse Wheel Left")); + availableInputs.append(UserInputMapper::InputPair(makeInput(MOUSE_AXIS_WHEEL_X_POS), "Mouse Wheel Up")); + availableInputs.append(UserInputMapper::InputPair(makeInput(MOUSE_AXIS_WHEEL_X_NEG), "Mouse Wheel Down")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(TOUCH_AXIS_X_POS), "Touchpad Right")); + availableInputs.append(UserInputMapper::InputPair(makeInput(TOUCH_AXIS_X_NEG), "Touchpad Left")); + availableInputs.append(UserInputMapper::InputPair(makeInput(TOUCH_AXIS_Y_POS), "Touchpad Up")); + availableInputs.append(UserInputMapper::InputPair(makeInput(TOUCH_AXIS_Y_NEG), "Touchpad Down")); + return availableInputs; }; proxy->resetDeviceBindings = [this, &mapper] () -> bool { From 72cc070f0a7df6f1d5d6e5f020dc60fbc482c919 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Thu, 11 Jun 2015 18:24:32 -0700 Subject: [PATCH 03/41] enabled remappable zooming (with keyboard: shift + w, shift + s, and others), switches to first person if you zoom in a lot --- interface/src/Application.cpp | 15 +++++++++++---- interface/src/avatar/Avatar.h | 2 ++ interface/src/avatar/MyAvatar.cpp | 8 ++++++++ interface/src/avatar/MyAvatar.h | 9 +++++++++ interface/src/devices/KeyboardMouseDevice.cpp | 14 +++++++------- 5 files changed, 37 insertions(+), 11 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e126882004..f66980ab71 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -193,7 +193,6 @@ const QString SKIP_FILENAME = QStandardPaths::writableLocation(QStandardPaths::D const QString DEFAULT_SCRIPTS_JS_URL = "http://s3.amazonaws.com/hifi-public/scripts/defaultScripts.js"; Setting::Handle maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTREE_PPS); - #ifdef Q_OS_WIN class MyNativeEventFilter : public QAbstractNativeEventFilter { public: @@ -881,6 +880,10 @@ void Application::paintGL() { } glEnable(GL_LINE_SMOOTH); + + const float CAMERA_PERSON_THRESHOLD = MyAvatar::ZOOM_MIN * _myAvatar->getScale(); + Menu::getInstance()->setIsOptionChecked("First Person", _myAvatar->getBoomLength() * _myAvatar->getScale() <= CAMERA_PERSON_THRESHOLD); + Application::getInstance()->cameraMenuChanged(); if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { // Always use the default eye position, not the actual head eye position. @@ -899,9 +902,8 @@ void Application::paintGL() { } } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { - static const float THIRD_PERSON_CAMERA_DISTANCE = 1.5f; _myCamera.setPosition(_myAvatar->getDefaultEyePosition() + - _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, 1.0f) * THIRD_PERSON_CAMERA_DISTANCE * _myAvatar->getScale()); + _myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, 1.0f) * _myAvatar->getBoomLength() * _myAvatar->getScale()); if (OculusManager::isConnected()) { _myCamera.setRotation(_myAvatar->getWorldAlignedOrientation()); } else { @@ -2370,10 +2372,14 @@ void Application::cameraMenuChanged() { } else if (Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson)) { if (_myCamera.getMode() != CAMERA_MODE_FIRST_PERSON) { _myCamera.setMode(CAMERA_MODE_FIRST_PERSON); + _myAvatar->setBoomLength(MyAvatar::ZOOM_MIN); } } else { if (_myCamera.getMode() != CAMERA_MODE_THIRD_PERSON) { _myCamera.setMode(CAMERA_MODE_THIRD_PERSON); + if (_myAvatar->getBoomLength() == MyAvatar::ZOOM_MIN) { + _myAvatar->setBoomLength(MyAvatar::ZOOM_DEFAULT); + } } } } @@ -2472,7 +2478,8 @@ void Application::update(float deltaTime) { _myAvatar->setDriveKeys(ROT_DOWN, _userInputMapper.getActionState(UserInputMapper::PITCH_DOWN)); _myAvatar->setDriveKeys(ROT_LEFT, _userInputMapper.getActionState(UserInputMapper::YAW_LEFT)); _myAvatar->setDriveKeys(ROT_RIGHT, _userInputMapper.getActionState(UserInputMapper::YAW_RIGHT)); - + _myAvatar->setDriveKeys(BOOM_IN, _userInputMapper.getActionState(UserInputMapper::BOOM_IN)); + _myAvatar->setDriveKeys(BOOM_OUT, _userInputMapper.getActionState(UserInputMapper::BOOM_OUT)); updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process... diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index b198d12a6e..2590808347 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -52,6 +52,8 @@ enum DriveKeys { ROT_RIGHT, ROT_UP, ROT_DOWN, + BOOM_IN, + BOOM_OUT, MAX_DRIVE_KEYS }; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index c4e08b5dba..6fe99b89e4 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -70,6 +70,10 @@ const int SCRIPTED_MOTOR_CAMERA_FRAME = 0; const int SCRIPTED_MOTOR_AVATAR_FRAME = 1; const int SCRIPTED_MOTOR_WORLD_FRAME = 2; +const float MyAvatar::ZOOM_MIN = .5f; +const float MyAvatar::ZOOM_MAX = 10.0f; +const float MyAvatar::ZOOM_DEFAULT = 1.5f; + MyAvatar::MyAvatar() : Avatar(), _turningKeyPressTime(0.0f), @@ -77,6 +81,7 @@ MyAvatar::MyAvatar() : _wasPushing(false), _isPushing(false), _isBraking(false), + _boomLength(ZOOM_DEFAULT), _trapDuration(0.0f), _thrust(0.0f), _keyboardMotorVelocity(0.0f), @@ -1347,6 +1352,9 @@ glm::vec3 MyAvatar::applyKeyboardMotor(float deltaTime, const glm::vec3& localVe } } } + + _boomLength += _driveKeys[BOOM_OUT] - _driveKeys[BOOM_IN]; + _boomLength = glm::clamp(_boomLength, ZOOM_MIN, ZOOM_MAX); return newLocalVelocity; } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index a3dc34e6e0..7adaf908f4 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -162,6 +162,13 @@ public: const RecorderPointer getRecorder() const { return _recorder; } const PlayerPointer getPlayer() const { return _player; } + float getBoomLength() const { return _boomLength; } + void setBoomLength(float boomLength) { _boomLength = boomLength; } + + static const float ZOOM_MIN; + static const float ZOOM_MAX; + static const float ZOOM_DEFAULT; + public slots: void increaseSize(); void decreaseSize(); @@ -210,6 +217,8 @@ private: bool _wasPushing; bool _isPushing; bool _isBraking; + + float _boomLength; float _trapDuration; // seconds that avatar has been trapped by collisions glm::vec3 _thrust; // impulse accumulator for outside sources diff --git a/interface/src/devices/KeyboardMouseDevice.cpp b/interface/src/devices/KeyboardMouseDevice.cpp index 5f18c02c7e..aeeb2480e7 100755 --- a/interface/src/devices/KeyboardMouseDevice.cpp +++ b/interface/src/devices/KeyboardMouseDevice.cpp @@ -215,7 +215,7 @@ void KeyboardMouseDevice::assignDefaultInputMapping(UserInputMapper& mapper) { const float MOUSE_PITCH_SPEED = 0.25f; const float TOUCH_YAW_SPEED = 0.5f; const float TOUCH_PITCH_SPEED = 0.25f; - //const float BUTTON_BOOM_SPEED = 0.1f; + const float BUTTON_BOOM_SPEED = 0.1f; // AWSD keys mapping mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(Qt::Key_S), BUTTON_MOVE_SPEED); @@ -225,8 +225,8 @@ void KeyboardMouseDevice::assignDefaultInputMapping(UserInputMapper& mapper) { mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(Qt::Key_C), BUTTON_MOVE_SPEED); mapper.addInputChannel(UserInputMapper::VERTICAL_UP, makeInput(Qt::Key_E), BUTTON_MOVE_SPEED); - // mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(Qt::Key_W), makeInput(Qt::Key_Shift), BUTTON_BOOM_SPEED); - // mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(Qt::Key_S), makeInput(Qt::Key_Shift), BUTTON_BOOM_SPEED); + mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(Qt::Key_W), makeInput(Qt::Key_Shift), BUTTON_BOOM_SPEED); + mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(Qt::Key_S), makeInput(Qt::Key_Shift), BUTTON_BOOM_SPEED); mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(Qt::Key_A), makeInput(Qt::RightButton), BUTTON_YAW_SPEED); mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(Qt::Key_D), makeInput(Qt::RightButton), BUTTON_YAW_SPEED); mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(Qt::Key_A), makeInput(Qt::Key_Shift), BUTTON_YAW_SPEED); @@ -242,8 +242,8 @@ void KeyboardMouseDevice::assignDefaultInputMapping(UserInputMapper& mapper) { mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(Qt::Key_PageDown), BUTTON_MOVE_SPEED); mapper.addInputChannel(UserInputMapper::VERTICAL_UP, makeInput(Qt::Key_PageUp), BUTTON_MOVE_SPEED); - // mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(Qt::Key_Up), makeInput(Qt::Key_Shift), BUTTON_BOOM_SPEED); - // mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(Qt::Key_Down), makeInput(Qt::Key_Shift), BUTTON_BOOM_SPEED); + mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(Qt::Key_Up), makeInput(Qt::Key_Shift), BUTTON_BOOM_SPEED); + mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(Qt::Key_Down), makeInput(Qt::Key_Shift), BUTTON_BOOM_SPEED); mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(Qt::Key_Left), makeInput(Qt::RightButton), BUTTON_YAW_SPEED); mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(Qt::Key_Right), makeInput(Qt::RightButton), BUTTON_YAW_SPEED); mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(Qt::Key_Left), makeInput(Qt::Key_Shift), BUTTON_YAW_SPEED); @@ -272,8 +272,8 @@ void KeyboardMouseDevice::assignDefaultInputMapping(UserInputMapper& mapper) { mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(TOUCH_AXIS_X_POS), TOUCH_YAW_SPEED); // Wheel move - //mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(MOUSE_AXIS_WHEEL_Y_NEG), BUTTON_BOOM_SPEED); - //mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(MOUSE_AXIS_WHEEL_Y_POS), BUTTON_BOOM_SPEED); + mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(MOUSE_AXIS_WHEEL_Y_NEG), BUTTON_BOOM_SPEED); + mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(MOUSE_AXIS_WHEEL_Y_POS), BUTTON_BOOM_SPEED); mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(MOUSE_AXIS_WHEEL_X_NEG), BUTTON_YAW_SPEED); mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(MOUSE_AXIS_WHEEL_X_POS), BUTTON_YAW_SPEED); From b4e108cd3bcf288f9a09e731dd92639d7c8a1772 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Fri, 12 Jun 2015 10:16:00 -0700 Subject: [PATCH 04/41] added zooming to default joystick controls --- interface/src/Application.cpp | 3 +- interface/src/devices/Joystick.cpp | 47 +++++++++++++++++++++--------- interface/src/devices/Joystick.h | 2 ++ 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f66980ab71..a3b226dafc 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -881,8 +881,7 @@ void Application::paintGL() { glEnable(GL_LINE_SMOOTH); - const float CAMERA_PERSON_THRESHOLD = MyAvatar::ZOOM_MIN * _myAvatar->getScale(); - Menu::getInstance()->setIsOptionChecked("First Person", _myAvatar->getBoomLength() * _myAvatar->getScale() <= CAMERA_PERSON_THRESHOLD); + Menu::getInstance()->setIsOptionChecked("First Person", _myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN); Application::getInstance()->cameraMenuChanged(); if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { diff --git a/interface/src/devices/Joystick.cpp b/interface/src/devices/Joystick.cpp index 43dc50b252..cf1e6bce47 100644 --- a/interface/src/devices/Joystick.cpp +++ b/interface/src/devices/Joystick.cpp @@ -59,20 +59,30 @@ void Joystick::focusOutEvent() { void Joystick::handleAxisEvent(const SDL_ControllerAxisEvent& event) { SDL_GameControllerAxis axis = (SDL_GameControllerAxis) event.axis; - if (axis == SDL_CONTROLLER_AXIS_LEFTX) { - _axisStateMap[makeInput(LEFT_AXIS_X_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; - _axisStateMap[makeInput(LEFT_AXIS_X_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; - } else if (axis == SDL_CONTROLLER_AXIS_LEFTY) { - _axisStateMap[makeInput(LEFT_AXIS_Y_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; - _axisStateMap[makeInput(LEFT_AXIS_Y_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; - } else if (axis == SDL_CONTROLLER_AXIS_RIGHTX) { - _axisStateMap[makeInput(RIGHT_AXIS_X_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; - _axisStateMap[makeInput(RIGHT_AXIS_X_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; - } else if (axis == SDL_CONTROLLER_AXIS_RIGHTY) { - _axisStateMap[makeInput(RIGHT_AXIS_Y_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; - _axisStateMap[makeInput(RIGHT_AXIS_Y_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + switch (axis) { + case SDL_CONTROLLER_AXIS_LEFTX: + _axisStateMap[makeInput(LEFT_AXIS_X_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(LEFT_AXIS_X_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + break; + case SDL_CONTROLLER_AXIS_LEFTY: + _axisStateMap[makeInput(LEFT_AXIS_Y_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(LEFT_AXIS_Y_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + break; + case SDL_CONTROLLER_AXIS_RIGHTX: + _axisStateMap[makeInput(RIGHT_AXIS_X_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(RIGHT_AXIS_X_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + break; + case SDL_CONTROLLER_AXIS_RIGHTY: + _axisStateMap[makeInput(RIGHT_AXIS_Y_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(RIGHT_AXIS_Y_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + break; + case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: + _axisStateMap[makeInput(RIGHT_SHOULDER).getChannel()] = event.value / MAX_AXIS; + break; + case SDL_CONTROLLER_AXIS_TRIGGERLEFT: + _axisStateMap[makeInput(LEFT_SHOULDER).getChannel()] = event.value / MAX_AXIS; + break; } - } void Joystick::handleButtonEvent(const SDL_ControllerButtonEvent& event) { @@ -109,6 +119,8 @@ void Joystick::registerToUserInputMapper(UserInputMapper& mapper) { availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_LEFTSHOULDER), "L1")); availableInputs.append(UserInputMapper::InputPair(makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), "R1")); + availableInputs.append(UserInputMapper::InputPair(makeInput(RIGHT_SHOULDER), "L2")); + availableInputs.append(UserInputMapper::InputPair(makeInput(LEFT_SHOULDER), "R2")); availableInputs.append(UserInputMapper::InputPair(makeInput(LEFT_AXIS_Y_NEG), "Left Stick Up")); availableInputs.append(UserInputMapper::InputPair(makeInput(LEFT_AXIS_Y_POS), "Left Stick Down")); @@ -136,6 +148,7 @@ void Joystick::assignDefaultInputMapping(UserInputMapper& mapper) { const float DPAD_MOVE_SPEED = .5f; const float JOYSTICK_YAW_SPEED = 0.5f; const float JOYSTICK_PITCH_SPEED = 0.25f; + const float BOOM_SPEED = 0.1f; // Y axes are flipped (up is negative) // Left Joystick: Movement, strafing @@ -162,6 +175,10 @@ void Joystick::assignDefaultInputMapping(UserInputMapper& mapper) { mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(SDL_CONTROLLER_BUTTON_X), JOYSTICK_YAW_SPEED); mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(SDL_CONTROLLER_BUTTON_B), JOYSTICK_YAW_SPEED); + // Zoom + mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(RIGHT_SHOULDER), BOOM_SPEED); + mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(LEFT_SHOULDER), BOOM_SPEED); + // Hold front right shoulder button for precision controls // Left Joystick: Movement, strafing @@ -187,6 +204,10 @@ void Joystick::assignDefaultInputMapping(UserInputMapper& mapper) { mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(SDL_CONTROLLER_BUTTON_A), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(SDL_CONTROLLER_BUTTON_X), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.); mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(SDL_CONTROLLER_BUTTON_B), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.); + + // Zoom + mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(RIGHT_SHOULDER), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), BOOM_SPEED/2.); + mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(LEFT_SHOULDER), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), BOOM_SPEED/2.); #endif } diff --git a/interface/src/devices/Joystick.h b/interface/src/devices/Joystick.h index c5ca7a6f7f..c546a82aaa 100644 --- a/interface/src/devices/Joystick.h +++ b/interface/src/devices/Joystick.h @@ -41,6 +41,8 @@ public: RIGHT_AXIS_X_NEG, RIGHT_AXIS_Y_POS, RIGHT_AXIS_Y_NEG, + RIGHT_SHOULDER, + LEFT_SHOULDER, }; Joystick(); From 1a8df6509fcffe9015573d55051871701682cbdd Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Fri, 12 Jun 2015 18:22:56 -0700 Subject: [PATCH 05/41] userinputmapper supports hydra, but some hydra events still register as mouse events --- interface/src/Application.cpp | 1 + interface/src/devices/Joystick.cpp | 6 +- interface/src/devices/KeyboardMouseDevice.cpp | 4 +- interface/src/devices/SixenseManager.cpp | 149 +++++++++++++++++- interface/src/devices/SixenseManager.h | 34 ++++ 5 files changed, 189 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a3b226dafc..a1ab6d35ae 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1456,6 +1456,7 @@ void Application::keyReleaseEvent(QKeyEvent* event) { void Application::focusOutEvent(QFocusEvent* event) { _keyboardMouseDevice.focusOutEvent(event); + SixenseManager::getInstance().focusOutEvent(); SDL2Manager::getInstance()->focusOutEvent(); // synthesize events for keys currently pressed, since we may not get their release events diff --git a/interface/src/devices/Joystick.cpp b/interface/src/devices/Joystick.cpp index cf1e6bce47..5d7e51b103 100644 --- a/interface/src/devices/Joystick.cpp +++ b/interface/src/devices/Joystick.cpp @@ -82,6 +82,8 @@ void Joystick::handleAxisEvent(const SDL_ControllerAxisEvent& event) { case SDL_CONTROLLER_AXIS_TRIGGERLEFT: _axisStateMap[makeInput(LEFT_SHOULDER).getChannel()] = event.value / MAX_AXIS; break; + default: + break; } } @@ -102,8 +104,8 @@ void Joystick::registerToUserInputMapper(UserInputMapper& mapper) { _deviceID = mapper.getFreeDeviceID(); auto proxy = UserInputMapper::DeviceProxy::Pointer(new UserInputMapper::DeviceProxy(_name)); - proxy->getButton = [this] (const UserInputMapper::Input& input, int timestamp) -> bool { return this->getButton(input._channel); }; - proxy->getAxis = [this] (const UserInputMapper::Input& input, int timestamp) -> float { return this->getAxis(input._channel); }; + proxy->getButton = [this] (const UserInputMapper::Input& input, int timestamp) -> bool { return this->getButton(input.getChannel()); }; + proxy->getAxis = [this] (const UserInputMapper::Input& input, int timestamp) -> float { return this->getAxis(input.getChannel()); }; proxy->getAvailabeInputs = [this] () -> QVector { QVector availableInputs; #ifdef HAVE_SDL2 diff --git a/interface/src/devices/KeyboardMouseDevice.cpp b/interface/src/devices/KeyboardMouseDevice.cpp index aeeb2480e7..fcb60cca26 100755 --- a/interface/src/devices/KeyboardMouseDevice.cpp +++ b/interface/src/devices/KeyboardMouseDevice.cpp @@ -160,8 +160,8 @@ void KeyboardMouseDevice::registerToUserInputMapper(UserInputMapper& mapper) { _deviceID = mapper.getFreeDeviceID(); auto proxy = UserInputMapper::DeviceProxy::Pointer(new UserInputMapper::DeviceProxy("Keyboard")); - proxy->getButton = [this] (const UserInputMapper::Input& input, int timestamp) -> bool { return this->getButton(input._channel); }; - proxy->getAxis = [this] (const UserInputMapper::Input& input, int timestamp) -> float { return this->getAxis(input._channel); }; + proxy->getButton = [this] (const UserInputMapper::Input& input, int timestamp) -> bool { return this->getButton(input.getChannel()); }; + proxy->getAxis = [this] (const UserInputMapper::Input& input, int timestamp) -> float { return this->getAxis(input.getChannel()); }; proxy->getAvailabeInputs = [this] () -> QVector { QVector availableInputs; for (int i = (int) Qt::Key_0; i <= (int) Qt::Key_9; i++) { diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index f1a762e64f..54cf202838 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -38,6 +38,10 @@ typedef int (*SixenseTakeIntFunction)(int); typedef int (*SixenseTakeIntAndSixenseControllerData)(int, sixenseControllerData*); #endif +// These bits aren't used for buttons, so they can be used as masks: +const unsigned int LEFT_MASK = 0; +const unsigned int RIGHT_MASK = 1U << 1; + #endif SixenseManager& SixenseManager::getInstance() { @@ -147,6 +151,7 @@ void SixenseManager::update(float deltaTime) { #ifdef HAVE_SIXENSE Hand* hand = DependencyManager::get()->getMyAvatar()->getHand(); if (_isInitialized && _isEnabled) { + _buttonPressedMap.clear(); #ifdef __APPLE__ SixenseBaseFunction sixenseGetNumActiveControllers = (SixenseBaseFunction) _sixenseLibrary->resolve("sixenseGetNumActiveControllers"); @@ -154,12 +159,18 @@ void SixenseManager::update(float deltaTime) { if (sixenseGetNumActiveControllers() == 0) { _hydrasConnected = false; + if (_deviceID) { + Application::getUserInputMapper()->removeDevice(_deviceID); + _deviceID = 0; + } return; } PerformanceTimer perfTimer("sixense"); if (!_hydrasConnected) { _hydrasConnected = true; + registerToUserInputMapper(*Application::getUserInputMapper()); + getInstance().assignDefaultInputMapping(*Application::getUserInputMapper()); UserActivityLogger::getInstance().connectedDevice("spatial_controller", "hydra"); } @@ -216,12 +227,14 @@ void SixenseManager::update(float deltaTime) { palm->setActive(false); // if this isn't a Sixsense ID palm, always make it inactive } - // Read controller buttons and joystick into the hand palm->setControllerButtons(data->buttons); palm->setTrigger(data->trigger); palm->setJoystick(data->joystick_x, data->joystick_y); + handleButtonEvent(data->buttons, numActiveControllers - 1); + handleAxisEvent(data->joystick_x, data->joystick_y, data->trigger, numActiveControllers - 1); + // Emulate the mouse so we can use scripts if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseMouseInput) && !_controllersAtBase) { emulateMouse(palm, numActiveControllers - 1); @@ -590,3 +603,137 @@ void SixenseManager::emulateMouse(PalmData* palm, int index) { #endif // HAVE_SIXENSE +void SixenseManager::focusOutEvent() { + _axisStateMap.clear(); + _buttonPressedMap.clear(); +}; + +void SixenseManager::handleAxisEvent(float stickX, float stickY, float trigger, int index) { + _axisStateMap[makeInput(AXIS_Y_POS, index).getChannel()] = (stickY > 0) ? stickY : 0.0f; + _axisStateMap[makeInput(AXIS_Y_NEG, index).getChannel()] = (stickY < 0) ? -stickY : 0.0f; + _axisStateMap[makeInput(AXIS_X_POS, index).getChannel()] = (stickX > 0) ? stickX : 0.0f; + _axisStateMap[makeInput(AXIS_X_NEG, index).getChannel()] = (stickX < 0) ? -stickX : 0.0f; + _axisStateMap[makeInput(BACK_TRIGGER, index).getChannel()] = trigger; +} + +void SixenseManager::handleButtonEvent(unsigned int buttons, int index) { + if (buttons & BUTTON_0) { + _buttonPressedMap.insert(makeInput(BUTTON_0, index).getChannel()); + } + if (buttons & BUTTON_1) { + _buttonPressedMap.insert(makeInput(BUTTON_1, index).getChannel()); + } + if (buttons & BUTTON_2) { + _buttonPressedMap.insert(makeInput(BUTTON_2, index).getChannel()); + } + if (buttons & BUTTON_3) { + _buttonPressedMap.insert(makeInput(BUTTON_3, index).getChannel()); + } + if (buttons & BUTTON_4) { + _buttonPressedMap.insert(makeInput(BUTTON_4, index).getChannel()); + } + if (buttons & BUTTON_FWD) { + _buttonPressedMap.insert(makeInput(BUTTON_FWD, index).getChannel()); + } +} + +void SixenseManager::registerToUserInputMapper(UserInputMapper& mapper) { + // Grab the current free device ID + _deviceID = mapper.getFreeDeviceID(); + + auto proxy = UserInputMapper::DeviceProxy::Pointer(new UserInputMapper::DeviceProxy("Hydra")); + proxy->getButton = [this] (const UserInputMapper::Input& input, int timestamp) -> bool { return this->getButton(input.getChannel()); }; + proxy->getAxis = [this] (const UserInputMapper::Input& input, int timestamp) -> float { return this->getAxis(input.getChannel()); }; + proxy->getAvailabeInputs = [this] () -> QVector { + QVector availableInputs; + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_0, 0), "Left Start")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_1, 0), "Left Button 1")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_2, 0), "Left Button 2")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_3, 0), "Left Button 3")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_4, 0), "Left Button 4")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_FWD, 0), "L1")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BACK_TRIGGER, 0), "L2")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_POS, 0), "Left Stick Up")); + availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_NEG, 0), "Left Stick Down")); + availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_POS, 0), "Left Stick Right")); + availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_NEG, 0), "Left Stick Left")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_0, 1), "Right Start")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_1, 1), "Right Button 1")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_2, 1), "Right Button 2")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_3, 1), "Right Button 3")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_4, 1), "Right Button 4")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_FWD, 1), "R1")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BACK_TRIGGER, 1), "R2")); + + availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_POS, 1), "Right Stick Up")); + availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_NEG, 1), "Right Stick Down")); + availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_POS, 1), "Right Stick Right")); + availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_NEG, 1), "Right Stick Left")); + return availableInputs; + }; + proxy->resetDeviceBindings = [this, &mapper] () -> bool { + mapper.removeAllInputChannelsForDevice(_deviceID); + this->assignDefaultInputMapping(mapper); + return true; + }; + mapper.registerDevice(_deviceID, proxy); +} + +void SixenseManager::assignDefaultInputMapping(UserInputMapper& mapper) { + const float JOYSTICK_MOVE_SPEED = 1.0f; + const float JOYSTICK_YAW_SPEED = 0.5f; + const float JOYSTICK_PITCH_SPEED = 0.25f; + const float BUTTON_MOVE_SPEED = 1.0f; + const float BOOM_SPEED = .1f; + + // Left Joystick: Movement, strafing + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(AXIS_Y_POS, 0), JOYSTICK_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(AXIS_Y_NEG, 0), JOYSTICK_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(AXIS_X_POS, 0), JOYSTICK_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(AXIS_X_NEG, 0), JOYSTICK_MOVE_SPEED); + + // Right Joystick: Camera orientation + mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(AXIS_X_POS, 1), JOYSTICK_YAW_SPEED); + mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(AXIS_X_NEG, 1), JOYSTICK_YAW_SPEED); + mapper.addInputChannel(UserInputMapper::PITCH_UP, makeInput(AXIS_Y_POS, 1), JOYSTICK_PITCH_SPEED); + mapper.addInputChannel(UserInputMapper::PITCH_DOWN, makeInput(AXIS_Y_NEG, 1), JOYSTICK_PITCH_SPEED); + + // Buttons + mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(BUTTON_3, 0), BOOM_SPEED); + mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(BUTTON_1, 0), BOOM_SPEED); + + mapper.addInputChannel(UserInputMapper::VERTICAL_UP, makeInput(BUTTON_3, 1), BUTTON_MOVE_SPEED); + mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(BUTTON_1, 1), BUTTON_MOVE_SPEED); +} + +float SixenseManager::getButton(int channel) const { + if (!_buttonPressedMap.empty()) { + if (_buttonPressedMap.find(channel) != _buttonPressedMap.end()) { + return 1.0f; + } else { + return 0.0f; + } + } + return 0.0f; +} + +float SixenseManager::getAxis(int channel) const { + auto axis = _axisStateMap.find(channel); + if (axis != _axisStateMap.end()) { + return (*axis).second; + } else { + return 0.0f; + } +} + +UserInputMapper::Input SixenseManager::makeInput(unsigned int button, int index) { + return UserInputMapper::Input(_deviceID, button | (index == 0 ? LEFT_MASK : RIGHT_MASK), UserInputMapper::ChannelType::BUTTON); +} + +UserInputMapper::Input SixenseManager::makeInput(SixenseManager::JoystickAxisChannel axis, int index) { + return UserInputMapper::Input(_deviceID, axis | (index == 0 ? LEFT_MASK : RIGHT_MASK), UserInputMapper::ChannelType::AXIS); +} diff --git a/interface/src/devices/SixenseManager.h b/interface/src/devices/SixenseManager.h index 6f47f2fac9..2ca6b0fb5b 100644 --- a/interface/src/devices/SixenseManager.h +++ b/interface/src/devices/SixenseManager.h @@ -13,6 +13,7 @@ #define hifi_SixenseManager_h #include +#include #ifdef HAVE_SIXENSE #include @@ -25,6 +26,8 @@ #endif +#include "ui/UserInputMapper.h" + class PalmData; const unsigned int BUTTON_0 = 1U << 0; // the skinny button between 1 and 2 @@ -45,6 +48,14 @@ const bool DEFAULT_INVERT_SIXENSE_MOUSE_BUTTONS = false; class SixenseManager : public QObject { Q_OBJECT public: + enum JoystickAxisChannel { + AXIS_Y_POS = 1U << 0, + AXIS_Y_NEG = 1U << 3, + AXIS_X_POS = 1U << 4, + AXIS_X_NEG = 1U << 5, + BACK_TRIGGER = 1U << 6, + }; + static SixenseManager& getInstance(); void initialize(); @@ -60,6 +71,21 @@ public: bool getInvertButtons() const { return _invertButtons; } void setInvertButtons(bool invertSixenseButtons) { _invertButtons = invertSixenseButtons; } + typedef std::unordered_set ButtonPressedMap; + typedef std::map AxisStateMap; + + float getButton(int channel) const; + float getAxis(int channel) const; + + UserInputMapper::Input makeInput(unsigned int button, int index); + UserInputMapper::Input makeInput(JoystickAxisChannel axis, int index); + + void registerToUserInputMapper(UserInputMapper& mapper); + void assignDefaultInputMapping(UserInputMapper& mapper); + + void update(); + void focusOutEvent(); + public slots: void toggleSixense(bool shouldEnable); void setFilter(bool filter); @@ -70,6 +96,8 @@ private: ~SixenseManager(); #ifdef HAVE_SIXENSE + void handleButtonEvent(unsigned int buttons, int index); + void handleAxisEvent(float x, float y, float trigger, int index); void updateCalibration(const sixenseControllerData* controllers); void emulateMouse(PalmData* palm, int index); @@ -110,6 +138,12 @@ private: float _reticleMoveSpeed = DEFAULT_SIXENSE_RETICLE_MOVE_SPEED; bool _invertButtons = DEFAULT_INVERT_SIXENSE_MOUSE_BUTTONS; + +protected: + int _deviceID = 0; + + ButtonPressedMap _buttonPressedMap; + AxisStateMap _axisStateMap; }; #endif // hifi_SixenseManager_h From fe576c6bafe98cdcd0432d0d13ca009f77a6e0bc Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Mon, 15 Jun 2015 10:23:24 -0700 Subject: [PATCH 06/41] hands reset when hydras disconnect --- interface/src/devices/SixenseManager.cpp | 10 ++++++++++ interface/src/devices/SixenseManager.h | 1 + 2 files changed, 11 insertions(+) diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 54cf202838..3927850a44 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -65,6 +65,8 @@ SixenseManager::SixenseManager() : _bumperPressed[1] = false; _oldX[1] = -1; _oldY[1] = -1; + _prevPalms[0] = nullptr; + _prevPalms[1] = nullptr; } SixenseManager::~SixenseManager() { @@ -162,6 +164,12 @@ void SixenseManager::update(float deltaTime) { if (_deviceID) { Application::getUserInputMapper()->removeDevice(_deviceID); _deviceID = 0; + if (_prevPalms[0]) { + _prevPalms[0]->setActive(false); + } + if (_prevPalms[1]) { + _prevPalms[1]->setActive(false); + } } return; } @@ -209,6 +217,7 @@ void SixenseManager::update(float deltaTime) { for (size_t j = 0; j < hand->getNumPalms(); j++) { if (hand->getPalms()[j].getSixenseID() == data->controller_index) { palm = &(hand->getPalms()[j]); + _prevPalms[numActiveControllers - 1] = palm; foundHand = true; } } @@ -217,6 +226,7 @@ void SixenseManager::update(float deltaTime) { hand->getPalms().push_back(newPalm); palm = &(hand->getPalms()[hand->getNumPalms() - 1]); palm->setSixenseID(data->controller_index); + _prevPalms[numActiveControllers - 1] = palm; qCDebug(interfaceapp, "Found new Sixense controller, ID %i", data->controller_index); } diff --git a/interface/src/devices/SixenseManager.h b/interface/src/devices/SixenseManager.h index 2ca6b0fb5b..63aa8846ec 100644 --- a/interface/src/devices/SixenseManager.h +++ b/interface/src/devices/SixenseManager.h @@ -132,6 +132,7 @@ private: bool _bumperPressed[2]; int _oldX[2]; int _oldY[2]; + PalmData* _prevPalms[2]; bool _lowVelocityFilter; bool _controllersAtBase; From 40bd747080979be5c69f32a8636c601918cce010 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Mon, 15 Jun 2015 11:13:07 -0700 Subject: [PATCH 07/41] added trigger buttons to hydra, removed hydraMove.js from default scripts --- examples/defaultScripts.js | 1 - interface/src/devices/SixenseManager.cpp | 6 ++++++ interface/src/devices/SixenseManager.h | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/examples/defaultScripts.js b/examples/defaultScripts.js index 61bed8d9b1..b5e3e3f551 100644 --- a/examples/defaultScripts.js +++ b/examples/defaultScripts.js @@ -11,7 +11,6 @@ Script.load("progress.js"); Script.load("edit.js"); Script.load("selectAudioDevice.js"); -Script.load("controllers/hydra/hydraMove.js"); Script.load("inspect.js"); Script.load("lobby.js"); Script.load("notifications.js"); diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 3927850a44..18c7365ef8 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -645,6 +645,9 @@ void SixenseManager::handleButtonEvent(unsigned int buttons, int index) { if (buttons & BUTTON_FWD) { _buttonPressedMap.insert(makeInput(BUTTON_FWD, index).getChannel()); } + if (buttons & BUTTON_TRIGGER) { + _buttonPressedMap.insert(makeInput(BUTTON_TRIGGER, index).getChannel()); + } } void SixenseManager::registerToUserInputMapper(UserInputMapper& mapper) { @@ -669,6 +672,7 @@ void SixenseManager::registerToUserInputMapper(UserInputMapper& mapper) { availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_NEG, 0), "Left Stick Down")); availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_POS, 0), "Left Stick Right")); availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_NEG, 0), "Left Stick Left")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_TRIGGER, 0), "Left Trigger Press")); availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_0, 1), "Right Start")); availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_1, 1), "Right Button 1")); @@ -683,6 +687,8 @@ void SixenseManager::registerToUserInputMapper(UserInputMapper& mapper) { availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_Y_NEG, 1), "Right Stick Down")); availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_POS, 1), "Right Stick Right")); availableInputs.append(UserInputMapper::InputPair(makeInput(AXIS_X_NEG, 1), "Right Stick Left")); + availableInputs.append(UserInputMapper::InputPair(makeInput(BUTTON_TRIGGER, 1), "Right Trigger Press")); + return availableInputs; }; proxy->resetDeviceBindings = [this, &mapper] () -> bool { diff --git a/interface/src/devices/SixenseManager.h b/interface/src/devices/SixenseManager.h index 63aa8846ec..92cc0742d6 100644 --- a/interface/src/devices/SixenseManager.h +++ b/interface/src/devices/SixenseManager.h @@ -36,6 +36,7 @@ const unsigned int BUTTON_2 = 1U << 6; const unsigned int BUTTON_3 = 1U << 3; const unsigned int BUTTON_4 = 1U << 4; const unsigned int BUTTON_FWD = 1U << 7; +const unsigned int BUTTON_TRIGGER = 1U << 8; // Event type that represents using the controller const unsigned int CONTROLLER_0_EVENT = 1500U; From 4090fd6aa1013fb7043e7054d7e7122c0b243eb4 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Mon, 15 Jun 2015 12:53:14 -0700 Subject: [PATCH 08/41] attempt to fix build errors --- interface/src/devices/SixenseManager.cpp | 8 ++++---- interface/src/devices/SixenseManager.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 18c7365ef8..95a622e7ad 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -19,6 +19,10 @@ #include "UserActivityLogger.h" #include "InterfaceLogging.h" +// These bits aren't used for buttons, so they can be used as masks: +const unsigned int LEFT_MASK = 0; +const unsigned int RIGHT_MASK = 1U << 1; + #ifdef HAVE_SIXENSE const int CALIBRATION_STATE_IDLE = 0; @@ -38,10 +42,6 @@ typedef int (*SixenseTakeIntFunction)(int); typedef int (*SixenseTakeIntAndSixenseControllerData)(int, sixenseControllerData*); #endif -// These bits aren't used for buttons, so they can be used as masks: -const unsigned int LEFT_MASK = 0; -const unsigned int RIGHT_MASK = 1U << 1; - #endif SixenseManager& SixenseManager::getInstance() { diff --git a/interface/src/devices/SixenseManager.h b/interface/src/devices/SixenseManager.h index 92cc0742d6..c27b3ca0e2 100644 --- a/interface/src/devices/SixenseManager.h +++ b/interface/src/devices/SixenseManager.h @@ -96,9 +96,9 @@ private: SixenseManager(); ~SixenseManager(); -#ifdef HAVE_SIXENSE void handleButtonEvent(unsigned int buttons, int index); void handleAxisEvent(float x, float y, float trigger, int index); +#ifdef HAVE_SIXENSE void updateCalibration(const sixenseControllerData* controllers); void emulateMouse(PalmData* palm, int index); From 4a00bd3e7f2e30268c3ed4ee46a7f0bfef59d958 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 15 Jun 2015 16:06:20 -0700 Subject: [PATCH 09/41] quiet compiler --- libraries/entities/src/EntityItem.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index f64dad0ef4..d2881e5f3a 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -67,12 +67,12 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) : _simulatorIDChangedTime(0), _marketplaceID(ENTITY_ITEM_DEFAULT_MARKETPLACE_ID), _name(ENTITY_ITEM_DEFAULT_NAME), + _href(""), + _description(""), _dirtyFlags(0), _element(nullptr), _physicsInfo(nullptr), - _simulated(false), - _href(""), - _description("") + _simulated(false) { quint64 now = usecTimestampNow(); _lastSimulated = now; From 445381bb6bf1dcfc8cf5574b63aa33eea49f49d7 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 15 Jun 2015 16:07:28 -0700 Subject: [PATCH 10/41] fix DEFAULT_VOXEL_DATA, recompress voxel data when a script calls setVoxel. Use provided transform when rendering. --- .../src/RenderablePolyVoxEntityItem.cpp | 30 ++++++++++++------- .../src/RenderablePolyVoxEntityItem.h | 3 +- libraries/entities/src/PolyVoxEntityItem.cpp | 21 ++++++++++++- libraries/entities/src/PolyVoxEntityItem.h | 22 +++++++------- 4 files changed, 54 insertions(+), 22 deletions(-) diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index bb5932d70c..d8e7ca0a18 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -121,7 +121,7 @@ void RenderablePolyVoxEntityItem::setVoxelVolumeSize(glm::vec3 voxelVolumeSize) _volData->setBorderValue(255); #ifdef WANT_DEBUG - qDebug() << " new size is" << _volData->getWidth() << _volData->getHeight() << _volData->getDepth(); + qDebug() << " new voxel-space size is" << _volData->getWidth() << _volData->getHeight() << _volData->getDepth(); #endif // I'm not sure this is needed... the docs say that each element is initialized with its default @@ -220,12 +220,15 @@ uint8_t RenderablePolyVoxEntityItem::getVoxel(int x, int y, int z) { return _volData->getVoxelAt(x, y, z); } -void RenderablePolyVoxEntityItem::setVoxel(int x, int y, int z, uint8_t toValue) { +void RenderablePolyVoxEntityItem::setVoxelInternal(int x, int y, int z, uint8_t toValue) { + // set a voxel without recompressing the voxel data assert(_volData); if (!inUserBounds(_volData, _voxelSurfaceStyle, x, y, z)) { return; } + updateOnCount(x, y, z, toValue); + if (_voxelSurfaceStyle == SURFACE_EDGED_CUBIC) { _volData->setVoxelAt(x + 1, y + 1, z + 1, toValue); } else { @@ -234,6 +237,11 @@ void RenderablePolyVoxEntityItem::setVoxel(int x, int y, int z, uint8_t toValue) } +void RenderablePolyVoxEntityItem::setVoxel(int x, int y, int z, uint8_t toValue) { + setVoxelInternal(x, y, z, toValue); + compressVolumeData(); +} + void RenderablePolyVoxEntityItem::updateOnCount(int x, int y, int z, uint8_t toValue) { // keep _onCount up to date if (!inUserBounds(_volData, _voxelSurfaceStyle, x, y, z)) { @@ -259,7 +267,7 @@ void RenderablePolyVoxEntityItem::setAll(uint8_t toValue) { for (int y = 0; y < _voxelVolumeSize.y; y++) { for (int x = 0; x < _voxelVolumeSize.x; x++) { updateOnCount(x, y, z, toValue); - setVoxel(x, y, z, toValue); + setVoxelInternal(x, y, z, toValue); } } } @@ -267,7 +275,7 @@ void RenderablePolyVoxEntityItem::setAll(uint8_t toValue) { } void RenderablePolyVoxEntityItem::setVoxelInVolume(glm::vec3 position, uint8_t toValue) { - updateOnCount(position.x, position.y, position.z, toValue); + // same as setVoxel but takes a vector rather than 3 floats. setVoxel(position.x, position.y, position.z, toValue); } @@ -283,7 +291,7 @@ void RenderablePolyVoxEntityItem::setSphereInVolume(glm::vec3 center, float radi // If the current voxel is less than 'radius' units from the center then we make it solid. if (fDistToCenter <= radius) { updateOnCount(x, y, z, toValue); - setVoxel(x, y, z, toValue); + setVoxelInternal(x, y, z, toValue); } } } @@ -380,10 +388,7 @@ void RenderablePolyVoxEntityItem::render(RenderArgs* args) { getModel(); } - Transform transform; - transform.setTranslation(getPosition() - getRegistrationPoint() * getDimensions()); - transform.setRotation(getRotation()); - transform.setScale(getDimensions() / _voxelVolumeSize); + Transform transform(voxelToWorldMatrix()); auto mesh = _modelGeometry.getMesh(); Q_ASSERT(args->_batch); @@ -514,6 +519,11 @@ void RenderablePolyVoxEntityItem::compressVolumeData() { QByteArray newVoxelData; QDataStream writer(&newVoxelData, QIODevice::WriteOnly | QIODevice::Truncate); + + #ifdef WANT_DEBUG + qDebug() << "compressing voxel data of size:" << voxelXSize << voxelYSize << voxelZSize; + #endif + writer << voxelXSize << voxelYSize << voxelZSize; QByteArray compressedData = qCompress(uncompressedData, 9); @@ -573,7 +583,7 @@ void RenderablePolyVoxEntityItem::decompressVolumeData() { for (int x = 0; x < voxelXSize; x++) { int uncompressedIndex = (z * voxelYSize * voxelXSize) + (y * voxelZSize) + x; updateOnCount(x, y, z, uncompressedData[uncompressedIndex]); - setVoxel(x, y, z, uncompressedData[uncompressedIndex]); + setVoxelInternal(x, y, z, uncompressedData[uncompressedIndex]); } } } diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h index 77aeb24f2a..814f3deb07 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.h @@ -73,11 +73,12 @@ public: virtual void setVoxelInVolume(glm::vec3 position, uint8_t toValue); SIMPLE_RENDERABLE(); - + private: // The PolyVoxEntityItem class has _voxelData which contains dimensions and compressed voxel data. The dimensions // may not match _voxelVolumeSize. + void setVoxelInternal(int x, int y, int z, uint8_t toValue); void compressVolumeData(); void decompressVolumeData(); diff --git a/libraries/entities/src/PolyVoxEntityItem.cpp b/libraries/entities/src/PolyVoxEntityItem.cpp index 95ab7d1035..84fbf11311 100644 --- a/libraries/entities/src/PolyVoxEntityItem.cpp +++ b/libraries/entities/src/PolyVoxEntityItem.cpp @@ -23,7 +23,7 @@ const glm::vec3 PolyVoxEntityItem::DEFAULT_VOXEL_VOLUME_SIZE = glm::vec3(32, 32, 32); const float PolyVoxEntityItem::MAX_VOXEL_DIMENSION = 32.0f; -const QByteArray PolyVoxEntityItem::DEFAULT_VOXEL_DATA(qCompress(QByteArray(0), 9)); // XXX +const QByteArray PolyVoxEntityItem::DEFAULT_VOXEL_DATA(PolyVoxEntityItem::makeEmptyVoxelData()); const PolyVoxEntityItem::PolyVoxSurfaceStyle PolyVoxEntityItem::DEFAULT_VOXEL_SURFACE_STYLE = PolyVoxEntityItem::SURFACE_MARCHING_CUBES; @@ -31,6 +31,25 @@ EntityItemPointer PolyVoxEntityItem::factory(const EntityItemID& entityID, const return EntityItemPointer(new PolyVoxEntityItem(entityID, properties)); } + + + +QByteArray PolyVoxEntityItem::makeEmptyVoxelData(quint16 voxelXSize, quint16 voxelYSize, quint16 voxelZSize) { + int rawSize = voxelXSize * voxelYSize * voxelZSize; + + QByteArray uncompressedData = QByteArray(rawSize, '\0'); + QByteArray newVoxelData; + QDataStream writer(&newVoxelData, QIODevice::WriteOnly | QIODevice::Truncate); + writer << voxelXSize << voxelYSize << voxelZSize; + + QByteArray compressedData = qCompress(uncompressedData, 9); + writer << compressedData; + + return newVoxelData; +} + + + PolyVoxEntityItem::PolyVoxEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) : EntityItem(entityItemID), _voxelVolumeSize(PolyVoxEntityItem::DEFAULT_VOXEL_VOLUME_SIZE), diff --git a/libraries/entities/src/PolyVoxEntityItem.h b/libraries/entities/src/PolyVoxEntityItem.h index bf8214675b..33e127e9b2 100644 --- a/libraries/entities/src/PolyVoxEntityItem.h +++ b/libraries/entities/src/PolyVoxEntityItem.h @@ -12,14 +12,14 @@ #ifndef hifi_PolyVoxEntityItem_h #define hifi_PolyVoxEntityItem_h -#include "EntityItem.h" +#include "EntityItem.h" class PolyVoxEntityItem : public EntityItem { public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); PolyVoxEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties); - + ALLOW_INSTANTIATION // This class can be instantiated // methods for getting/setting all properties of an entity @@ -29,22 +29,22 @@ class PolyVoxEntityItem : public EntityItem { // TODO: eventually only include properties changed since the params.lastViewFrustumSent time virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const; - virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, + virtual void appendSubclassData(OctreePacketData* packetData, EncodeBitstreamParams& params, EntityTreeElementExtraEncodeData* modelTreeElementExtraEncodeData, EntityPropertyFlags& requestedProperties, EntityPropertyFlags& propertyFlags, EntityPropertyFlags& propertiesDidntFit, - int& propertyCount, + int& propertyCount, OctreeElement::AppendState& appendState) const; - virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, + virtual int readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args, EntityPropertyFlags& propertyFlags, bool overwriteLocalData); - + // never have a ray intersection pick a PolyVoxEntityItem. virtual bool supportsDetailedRayIntersection() const { return true; } virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, - bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face, + bool& keepSearching, OctreeElement*& element, float& distance, BoxFace& face, void** intersectedObject, bool precisionPicking) const { return false; } virtual void debugDump() const; @@ -58,12 +58,12 @@ class PolyVoxEntityItem : public EntityItem { enum PolyVoxSurfaceStyle { SURFACE_MARCHING_CUBES, SURFACE_CUBIC, - SURFACE_EDGED_CUBIC + SURFACE_EDGED_CUBIC }; virtual void setVoxelSurfaceStyle(PolyVoxSurfaceStyle voxelSurfaceStyle) { _voxelSurfaceStyle = voxelSurfaceStyle; } virtual void setVoxelSurfaceStyle(uint16_t voxelSurfaceStyle) { - setVoxelSurfaceStyle((PolyVoxSurfaceStyle) voxelSurfaceStyle); + setVoxelSurfaceStyle((PolyVoxSurfaceStyle) voxelSurfaceStyle); } virtual PolyVoxSurfaceStyle getVoxelSurfaceStyle() const { return _voxelSurfaceStyle; } @@ -82,15 +82,17 @@ class PolyVoxEntityItem : public EntityItem { virtual void setAll(uint8_t toValue) {} virtual void setVoxelInVolume(glm::vec3 position, uint8_t toValue) {} - + virtual uint8_t getVoxel(int x, int y, int z) { return 0; } virtual void setVoxel(int x, int y, int z, uint8_t toValue) {} + static QByteArray makeEmptyVoxelData(quint16 voxelXSize = 16, quint16 voxelYSize = 16, quint16 voxelZSize = 16); protected: glm::vec3 _voxelVolumeSize; // this is always 3 bytes QByteArray _voxelData; PolyVoxSurfaceStyle _voxelSurfaceStyle; + }; #endif // hifi_PolyVoxEntityItem_h From 6def25de92a2409b025f09ba17c2c90a4ea3a607 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 15 Jun 2015 16:22:06 -0700 Subject: [PATCH 11/41] formatting --- libraries/entities/src/PolyVoxEntityItem.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/entities/src/PolyVoxEntityItem.h b/libraries/entities/src/PolyVoxEntityItem.h index 33e127e9b2..e5d511c087 100644 --- a/libraries/entities/src/PolyVoxEntityItem.h +++ b/libraries/entities/src/PolyVoxEntityItem.h @@ -92,7 +92,6 @@ class PolyVoxEntityItem : public EntityItem { glm::vec3 _voxelVolumeSize; // this is always 3 bytes QByteArray _voxelData; PolyVoxSurfaceStyle _voxelSurfaceStyle; - }; #endif // hifi_PolyVoxEntityItem_h From 8241a2170baa0e7d95e757e1e32b54fc78f8532f Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 16 Jun 2015 09:50:42 -0700 Subject: [PATCH 12/41] Update cube, line, and sphere overlays to use batches --- interface/src/ui/overlays/Cube3DOverlay.cpp | 228 +++++++++++------- interface/src/ui/overlays/Line3DOverlay.cpp | 66 +++-- interface/src/ui/overlays/Sphere3DOverlay.cpp | 58 +++-- 3 files changed, 222 insertions(+), 130 deletions(-) diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index 6fc9fe6e27..73406c07a0 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -35,13 +35,6 @@ void Cube3DOverlay::render(RenderArgs* args) { return; // do nothing if we're not visible } - - float glowLevel = getGlowLevel(); - Glower* glower = NULL; - if (glowLevel > 0.0f) { - glower = new Glower(glowLevel); - } - float alpha = getAlpha(); xColor color = getColor(); const float MAX_COLOR = 255.0f; @@ -49,91 +42,162 @@ void Cube3DOverlay::render(RenderArgs* args) { //glDisable(GL_LIGHTING); - // TODO: handle registration point?? + // TODO: handle registration point?? glm::vec3 position = getPosition(); glm::vec3 center = getCenter(); glm::vec3 dimensions = getDimensions(); glm::quat rotation = getRotation(); - - glPushMatrix(); - glTranslatef(position.x, position.y, position.z); - glm::vec3 axis = glm::axis(rotation); - glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); - glPushMatrix(); - glm::vec3 positionToCenter = center - position; - glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z); - if (_isSolid) { - if (_borderSize > 0) { - // Draw a cube at a larger size behind the main cube, creating - // a border effect. - // Disable writing to the depth mask so that the "border" cube will not - // occlude the main cube. This means the border could be covered by - // overlays that are further back and drawn later, but this is good - // enough for the use-case. - glDepthMask(GL_FALSE); - glPushMatrix(); - glScalef(dimensions.x * _borderSize, dimensions.y * _borderSize, dimensions.z * _borderSize); - if (_drawOnHUD) { - DependencyManager::get()->renderSolidCube(1.0f, glm::vec4(1.0f, 1.0f, 1.0f, alpha)); - } else { - DependencyManager::get()->renderSolidCube(1.0f, glm::vec4(1.0f, 1.0f, 1.0f, alpha)); - } + auto batch = args->_batch; - glPopMatrix(); - glDepthMask(GL_TRUE); - } + if (batch) { + Transform transform; + transform.setTranslation(position); + transform.setRotation(rotation); + if (_isSolid) { + // if (_borderSize > 0) { + // // Draw a cube at a larger size behind the main cube, creating + // // a border effect. + // // Disable writing to the depth mask so that the "border" cube will not + // // occlude the main cube. This means the border could be covered by + // // overlays that are further back and drawn later, but this is good + // // enough for the use-case. + // transform.setScale(dimensions * _borderSize); + // batch->setModelTransform(transform); + // DependencyManager::get()->renderSolidCube(*batch, 1.0f, glm::vec4(1.0f, 1.0f, 1.0f, alpha)); + // } + + transform.setScale(dimensions); + batch->setModelTransform(transform); + + DependencyManager::get()->renderSolidCube(*batch, 1.0f, cubeColor); + } else { + + if (getIsDashedLine()) { + transform.setScale(1.0f); + batch->setModelTransform(transform); + + glm::vec3 halfDimensions = dimensions / 2.0f; + glm::vec3 bottomLeftNear(-halfDimensions.x, -halfDimensions.y, -halfDimensions.z); + glm::vec3 bottomRightNear(halfDimensions.x, -halfDimensions.y, -halfDimensions.z); + glm::vec3 topLeftNear(-halfDimensions.x, halfDimensions.y, -halfDimensions.z); + glm::vec3 topRightNear(halfDimensions.x, halfDimensions.y, -halfDimensions.z); + + glm::vec3 bottomLeftFar(-halfDimensions.x, -halfDimensions.y, halfDimensions.z); + glm::vec3 bottomRightFar(halfDimensions.x, -halfDimensions.y, halfDimensions.z); + glm::vec3 topLeftFar(-halfDimensions.x, halfDimensions.y, halfDimensions.z); + glm::vec3 topRightFar(halfDimensions.x, halfDimensions.y, halfDimensions.z); + + auto geometryCache = DependencyManager::get(); + + geometryCache->renderDashedLine(*batch, bottomLeftNear, bottomRightNear, cubeColor); + geometryCache->renderDashedLine(*batch, bottomRightNear, bottomRightFar, cubeColor); + geometryCache->renderDashedLine(*batch, bottomRightFar, bottomLeftFar, cubeColor); + geometryCache->renderDashedLine(*batch, bottomLeftFar, bottomLeftNear, cubeColor); + + geometryCache->renderDashedLine(*batch, topLeftNear, topRightNear, cubeColor); + geometryCache->renderDashedLine(*batch, topRightNear, topRightFar, cubeColor); + geometryCache->renderDashedLine(*batch, topRightFar, topLeftFar, cubeColor); + geometryCache->renderDashedLine(*batch, topLeftFar, topLeftNear, cubeColor); + + geometryCache->renderDashedLine(*batch, bottomLeftNear, topLeftNear, cubeColor); + geometryCache->renderDashedLine(*batch, bottomRightNear, topRightNear, cubeColor); + geometryCache->renderDashedLine(*batch, bottomLeftFar, topLeftFar, cubeColor); + geometryCache->renderDashedLine(*batch, bottomRightFar, topRightFar, cubeColor); - glPushMatrix(); - glScalef(dimensions.x, dimensions.y, dimensions.z); - if (_drawOnHUD) { - DependencyManager::get()->renderSolidCube(1.0f, cubeColor); - } else { - DependencyManager::get()->renderSolidCube(1.0f, cubeColor); - } - glPopMatrix(); } else { - glLineWidth(_lineWidth); - - if (getIsDashedLine()) { - glm::vec3 halfDimensions = dimensions / 2.0f; - glm::vec3 bottomLeftNear(-halfDimensions.x, -halfDimensions.y, -halfDimensions.z); - glm::vec3 bottomRightNear(halfDimensions.x, -halfDimensions.y, -halfDimensions.z); - glm::vec3 topLeftNear(-halfDimensions.x, halfDimensions.y, -halfDimensions.z); - glm::vec3 topRightNear(halfDimensions.x, halfDimensions.y, -halfDimensions.z); - - glm::vec3 bottomLeftFar(-halfDimensions.x, -halfDimensions.y, halfDimensions.z); - glm::vec3 bottomRightFar(halfDimensions.x, -halfDimensions.y, halfDimensions.z); - glm::vec3 topLeftFar(-halfDimensions.x, halfDimensions.y, halfDimensions.z); - glm::vec3 topRightFar(halfDimensions.x, halfDimensions.y, halfDimensions.z); - - auto geometryCache = DependencyManager::get(); - - geometryCache->renderDashedLine(bottomLeftNear, bottomRightNear, cubeColor); - geometryCache->renderDashedLine(bottomRightNear, bottomRightFar, cubeColor); - geometryCache->renderDashedLine(bottomRightFar, bottomLeftFar, cubeColor); - geometryCache->renderDashedLine(bottomLeftFar, bottomLeftNear, cubeColor); - - geometryCache->renderDashedLine(topLeftNear, topRightNear, cubeColor); - geometryCache->renderDashedLine(topRightNear, topRightFar, cubeColor); - geometryCache->renderDashedLine(topRightFar, topLeftFar, cubeColor); - geometryCache->renderDashedLine(topLeftFar, topLeftNear, cubeColor); - - geometryCache->renderDashedLine(bottomLeftNear, topLeftNear, cubeColor); - geometryCache->renderDashedLine(bottomRightNear, topRightNear, cubeColor); - geometryCache->renderDashedLine(bottomLeftFar, topLeftFar, cubeColor); - geometryCache->renderDashedLine(bottomRightFar, topRightFar, cubeColor); - - } else { - glScalef(dimensions.x, dimensions.y, dimensions.z); - DependencyManager::get()->renderWireCube(1.0f, cubeColor); - } + transform.setScale(dimensions); + batch->setModelTransform(transform); + DependencyManager::get()->renderWireCube(*batch, 1.0f, cubeColor); } - glPopMatrix(); - glPopMatrix(); + } + } else { + float glowLevel = getGlowLevel(); + Glower* glower = NULL; + if (glowLevel > 0.0f) { + glower = new Glower(glowLevel); + } - if (glower) { - delete glower; + glPushMatrix(); + glTranslatef(position.x, position.y, position.z); + glm::vec3 axis = glm::axis(rotation); + glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); + glPushMatrix(); + glm::vec3 positionToCenter = center - position; + glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z); + if (_isSolid) { + if (_borderSize > 0) { + // Draw a cube at a larger size behind the main cube, creating + // a border effect. + // Disable writing to the depth mask so that the "border" cube will not + // occlude the main cube. This means the border could be covered by + // overlays that are further back and drawn later, but this is good + // enough for the use-case. + glDepthMask(GL_FALSE); + glPushMatrix(); + glScalef(dimensions.x * _borderSize, dimensions.y * _borderSize, dimensions.z * _borderSize); + + if (_drawOnHUD) { + DependencyManager::get()->renderSolidCube(1.0f, glm::vec4(1.0f, 1.0f, 1.0f, alpha)); + } else { + DependencyManager::get()->renderSolidCube(1.0f, glm::vec4(1.0f, 1.0f, 1.0f, alpha)); + } + + glPopMatrix(); + glDepthMask(GL_TRUE); + } + + glPushMatrix(); + glScalef(dimensions.x, dimensions.y, dimensions.z); + if (_drawOnHUD) { + DependencyManager::get()->renderSolidCube(1.0f, cubeColor); + } else { + DependencyManager::get()->renderSolidCube(1.0f, cubeColor); + } + glPopMatrix(); + } else { + glLineWidth(_lineWidth); + + if (getIsDashedLine()) { + glm::vec3 halfDimensions = dimensions / 2.0f; + glm::vec3 bottomLeftNear(-halfDimensions.x, -halfDimensions.y, -halfDimensions.z); + glm::vec3 bottomRightNear(halfDimensions.x, -halfDimensions.y, -halfDimensions.z); + glm::vec3 topLeftNear(-halfDimensions.x, halfDimensions.y, -halfDimensions.z); + glm::vec3 topRightNear(halfDimensions.x, halfDimensions.y, -halfDimensions.z); + + glm::vec3 bottomLeftFar(-halfDimensions.x, -halfDimensions.y, halfDimensions.z); + glm::vec3 bottomRightFar(halfDimensions.x, -halfDimensions.y, halfDimensions.z); + glm::vec3 topLeftFar(-halfDimensions.x, halfDimensions.y, halfDimensions.z); + glm::vec3 topRightFar(halfDimensions.x, halfDimensions.y, halfDimensions.z); + + auto geometryCache = DependencyManager::get(); + + geometryCache->renderDashedLine(bottomLeftNear, bottomRightNear, cubeColor); + geometryCache->renderDashedLine(bottomRightNear, bottomRightFar, cubeColor); + geometryCache->renderDashedLine(bottomRightFar, bottomLeftFar, cubeColor); + geometryCache->renderDashedLine(bottomLeftFar, bottomLeftNear, cubeColor); + + geometryCache->renderDashedLine(topLeftNear, topRightNear, cubeColor); + geometryCache->renderDashedLine(topRightNear, topRightFar, cubeColor); + geometryCache->renderDashedLine(topRightFar, topLeftFar, cubeColor); + geometryCache->renderDashedLine(topLeftFar, topLeftNear, cubeColor); + + geometryCache->renderDashedLine(bottomLeftNear, topLeftNear, cubeColor); + geometryCache->renderDashedLine(bottomRightNear, topRightNear, cubeColor); + geometryCache->renderDashedLine(bottomLeftFar, topLeftFar, cubeColor); + geometryCache->renderDashedLine(bottomRightFar, topRightFar, cubeColor); + + } else { + glScalef(dimensions.x, dimensions.y, dimensions.z); + DependencyManager::get()->renderWireCube(1.0f, cubeColor); + } + } + glPopMatrix(); + glPopMatrix(); + + if (glower) { + delete glower; + } } } diff --git a/interface/src/ui/overlays/Line3DOverlay.cpp b/interface/src/ui/overlays/Line3DOverlay.cpp index 6672a88e45..34c983d7b2 100644 --- a/interface/src/ui/overlays/Line3DOverlay.cpp +++ b/interface/src/ui/overlays/Line3DOverlay.cpp @@ -37,41 +37,57 @@ void Line3DOverlay::render(RenderArgs* args) { return; // do nothing if we're not visible } - float glowLevel = getGlowLevel(); - Glower* glower = NULL; - if (glowLevel > 0.0f) { - glower = new Glower(glowLevel); - } - - glPushMatrix(); - - glDisable(GL_LIGHTING); - glLineWidth(_lineWidth); - float alpha = getAlpha(); xColor color = getColor(); const float MAX_COLOR = 255.0f; glm::vec4 colorv4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); - glm::vec3 position = getPosition(); - glm::quat rotation = getRotation(); + auto batch = args->_batch; - glTranslatef(position.x, position.y, position.z); - glm::vec3 axis = glm::axis(rotation); - glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); + if (batch) { + Transform transform; + transform.setTranslation(_position); + transform.setRotation(_rotation); + batch->setModelTransform(transform); - if (getIsDashedLine()) { - // TODO: add support for color to renderDashedLine() - DependencyManager::get()->renderDashedLine(_position, _end, colorv4, _geometryCacheID); + if (getIsDashedLine()) { + // TODO: add support for color to renderDashedLine() + DependencyManager::get()->renderDashedLine(*batch, _position, _end, colorv4, _geometryCacheID); + } else { + DependencyManager::get()->renderLine(*batch, _start, _end, colorv4, _geometryCacheID); + } } else { - DependencyManager::get()->renderLine(_start, _end, colorv4, _geometryCacheID); - } - glEnable(GL_LIGHTING); + float glowLevel = getGlowLevel(); + Glower* glower = NULL; + if (glowLevel > 0.0f) { + glower = new Glower(glowLevel); + } - glPopMatrix(); + glPushMatrix(); - if (glower) { - delete glower; + glDisable(GL_LIGHTING); + glLineWidth(_lineWidth); + + glm::vec3 position = getPosition(); + glm::quat rotation = getRotation(); + + glTranslatef(position.x, position.y, position.z); + glm::vec3 axis = glm::axis(rotation); + glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); + + if (getIsDashedLine()) { + // TODO: add support for color to renderDashedLine() + DependencyManager::get()->renderDashedLine(_position, _end, colorv4, _geometryCacheID); + } else { + DependencyManager::get()->renderLine(_start, _end, colorv4, _geometryCacheID); + } + glEnable(GL_LIGHTING); + + glPopMatrix(); + + if (glower) { + delete glower; + } } } diff --git a/interface/src/ui/overlays/Sphere3DOverlay.cpp b/interface/src/ui/overlays/Sphere3DOverlay.cpp index a0e8d06b41..f5fba0ed05 100644 --- a/interface/src/ui/overlays/Sphere3DOverlay.cpp +++ b/interface/src/ui/overlays/Sphere3DOverlay.cpp @@ -39,33 +39,45 @@ void Sphere3DOverlay::render(RenderArgs* args) { const float MAX_COLOR = 255.0f; glm::vec4 sphereColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); - glDisable(GL_LIGHTING); - - glm::vec3 position = getPosition(); - glm::vec3 center = getCenter(); - glm::vec3 dimensions = getDimensions(); - glm::quat rotation = getRotation(); + auto batch = args->_batch; - float glowLevel = getGlowLevel(); - Glower* glower = NULL; - if (glowLevel > 0.0f) { - glower = new Glower(glowLevel); - } + if (batch) { + Transform transform; + transform.setTranslation(_position); + transform.setRotation(_rotation); + transform.setScale(_dimensions); + + batch->setModelTransform(transform); + DependencyManager::get()->renderSphere(*batch, 1.0f, SLICES, SLICES, sphereColor, _isSolid); + } else { + glDisable(GL_LIGHTING); + + glm::vec3 position = getPosition(); + glm::vec3 center = getCenter(); + glm::vec3 dimensions = getDimensions(); + glm::quat rotation = getRotation(); + + float glowLevel = getGlowLevel(); + Glower* glower = NULL; + if (glowLevel > 0.0f) { + glower = new Glower(glowLevel); + } - glPushMatrix(); - glTranslatef(position.x, position.y, position.z); - glm::vec3 axis = glm::axis(rotation); - glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); glPushMatrix(); - glm::vec3 positionToCenter = center - position; - glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z); - glScalef(dimensions.x, dimensions.y, dimensions.z); - DependencyManager::get()->renderSphere(1.0f, SLICES, SLICES, sphereColor, _isSolid); + glTranslatef(position.x, position.y, position.z); + glm::vec3 axis = glm::axis(rotation); + glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); + glPushMatrix(); + glm::vec3 positionToCenter = center - position; + glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z); + glScalef(dimensions.x, dimensions.y, dimensions.z); + DependencyManager::get()->renderSphere(1.0f, SLICES, SLICES, sphereColor, _isSolid); + glPopMatrix(); glPopMatrix(); - glPopMatrix(); - - if (glower) { - delete glower; + + if (glower) { + delete glower; + } } } From a5f7ba51b67618845eecbca526b3029887884423 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 16 Jun 2015 10:13:47 -0700 Subject: [PATCH 13/41] only show polyvox property widgets if we are editing a polyvox. --- examples/html/entityProperties.html | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index f029088b1a..27a2929d1c 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -354,7 +354,8 @@ var elZoneAtmosphereScatteringWavelengthsZ = document.getElementById("property-zone-atmosphere-scattering-wavelengths-z"); var elZoneAtmosphereHasStars = document.getElementById("property-zone-atmosphere-has-stars"); - var elPolyVoxSelections = document.querySelectorAll(".poly-vox-section"); + var elPolyVoxSections = document.querySelectorAll(".poly-vox-section"); + allSections.push(elPolyVoxSections); var elVoxelVolumeSizeX = document.getElementById("property-voxel-volume-size-x"); var elVoxelVolumeSizeY = document.getElementById("property-voxel-volume-size-y"); var elVoxelVolumeSizeZ = document.getElementById("property-voxel-volume-size-z"); @@ -602,6 +603,10 @@ elParticleLocalGravity.value = properties.localGravity.toFixed(2); elParticleRadius.value = properties.particleRadius.toFixed(3); } else if (properties.type == "PolyVox") { + for (var i = 0; i < elPolyVoxSections.length; i++) { + elPolyVoxSections[i].style.display = 'block'; + } + elVoxelVolumeSizeX.value = properties.voxelVolumeSize.x.toFixed(2); elVoxelVolumeSizeY.value = properties.voxelVolumeSize.y.toFixed(2); elVoxelVolumeSizeZ.value = properties.voxelVolumeSize.z.toFixed(2); @@ -1014,9 +1019,9 @@
Voxel Volume Size
-
X
-
Y
-
Z
+
X
+
Y
+
Z
Surface Extractor
From d7eddc398b5b87b73e14dab2f716d71b64877087 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 16 Jun 2015 10:14:01 -0700 Subject: [PATCH 14/41] don't make changes if the polyvox is locked --- .../src/RenderablePolyVoxEntityItem.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp index d8e7ca0a18..71c3537a0c 100644 --- a/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyVoxEntityItem.cpp @@ -238,6 +238,9 @@ void RenderablePolyVoxEntityItem::setVoxelInternal(int x, int y, int z, uint8_t void RenderablePolyVoxEntityItem::setVoxel(int x, int y, int z, uint8_t toValue) { + if (_locked) { + return; + } setVoxelInternal(x, y, z, toValue); compressVolumeData(); } @@ -263,6 +266,10 @@ void RenderablePolyVoxEntityItem::updateOnCount(int x, int y, int z, uint8_t toV } void RenderablePolyVoxEntityItem::setAll(uint8_t toValue) { + if (_locked) { + return; + } + for (int z = 0; z < _voxelVolumeSize.z; z++) { for (int y = 0; y < _voxelVolumeSize.y; y++) { for (int x = 0; x < _voxelVolumeSize.x; x++) { @@ -275,11 +282,19 @@ void RenderablePolyVoxEntityItem::setAll(uint8_t toValue) { } void RenderablePolyVoxEntityItem::setVoxelInVolume(glm::vec3 position, uint8_t toValue) { + if (_locked) { + return; + } + // same as setVoxel but takes a vector rather than 3 floats. - setVoxel(position.x, position.y, position.z, toValue); + setVoxel((int)position.x, (int)position.y, (int)position.z, toValue); } void RenderablePolyVoxEntityItem::setSphereInVolume(glm::vec3 center, float radius, uint8_t toValue) { + if (_locked) { + return; + } + // This three-level for loop iterates over every voxel in the volume for (int z = 0; z < _voxelVolumeSize.z; z++) { for (int y = 0; y < _voxelVolumeSize.y; y++) { From 68a08d969df0df898258450a71025b9b7bc3adea Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Tue, 16 Jun 2015 10:19:40 -0700 Subject: [PATCH 15/41] code review fixes --- interface/src/devices/Joystick.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/devices/Joystick.cpp b/interface/src/devices/Joystick.cpp index 5d7e51b103..7525d66d74 100644 --- a/interface/src/devices/Joystick.cpp +++ b/interface/src/devices/Joystick.cpp @@ -44,8 +44,8 @@ void Joystick::closeJoystick() { void Joystick::update() { for (auto axisState : _axisStateMap) { - if (axisState.second < CONTROLLER_THRESHOLD && axisState.second > -CONTROLLER_THRESHOLD) { - _axisStateMap[axisState.first] = 0; + if (fabsf(axisState.second) < CONTROLLER_THRESHOLD) { + _axisStateMap[axisState.first] = 0.0f; } } } From 1ecc954656aa8acf41c611bd2884da9557b366ac Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Tue, 16 Jun 2015 10:25:30 -0700 Subject: [PATCH 16/41] coding standard fixes --- interface/src/devices/Joystick.cpp | 4 ++-- interface/src/devices/SixenseManager.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/devices/Joystick.cpp b/interface/src/devices/Joystick.cpp index 7525d66d74..a302becb77 100644 --- a/interface/src/devices/Joystick.cpp +++ b/interface/src/devices/Joystick.cpp @@ -17,7 +17,7 @@ #include "Joystick.h" -const float CONTROLLER_THRESHOLD = .25f; +const float CONTROLLER_THRESHOLD = 0.25f; #ifdef HAVE_SDL2 const float MAX_AXIS = 32768.0f; @@ -147,7 +147,7 @@ void Joystick::registerToUserInputMapper(UserInputMapper& mapper) { void Joystick::assignDefaultInputMapping(UserInputMapper& mapper) { #ifdef HAVE_SDL2 const float JOYSTICK_MOVE_SPEED = 1.0f; - const float DPAD_MOVE_SPEED = .5f; + const float DPAD_MOVE_SPEED = 0.5f; const float JOYSTICK_YAW_SPEED = 0.5f; const float JOYSTICK_PITCH_SPEED = 0.25f; const float BOOM_SPEED = 0.1f; diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 95a622e7ad..959a1e147f 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -161,7 +161,7 @@ void SixenseManager::update(float deltaTime) { if (sixenseGetNumActiveControllers() == 0) { _hydrasConnected = false; - if (_deviceID) { + if (_deviceID != 0) { Application::getUserInputMapper()->removeDevice(_deviceID); _deviceID = 0; if (_prevPalms[0]) { @@ -704,7 +704,7 @@ void SixenseManager::assignDefaultInputMapping(UserInputMapper& mapper) { const float JOYSTICK_YAW_SPEED = 0.5f; const float JOYSTICK_PITCH_SPEED = 0.25f; const float BUTTON_MOVE_SPEED = 1.0f; - const float BOOM_SPEED = .1f; + const float BOOM_SPEED = 0.1f; // Left Joystick: Movement, strafing mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(AXIS_Y_POS, 0), JOYSTICK_MOVE_SPEED); From 6d99d50f722e7bcd662e3e749e0f47d2a0b9453f Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 16 Jun 2015 10:51:42 -0700 Subject: [PATCH 17/41] Don't clip local audio sounds (https://app.asana.com/0/32622044445063/37633564937422) and quiet some warnings (of https://app.asana.com/0/32622044445063/37620738098871). --- libraries/audio/src/AudioInjector.cpp | 3 +-- libraries/audio/src/AudioInjectorLocalBuffer.cpp | 12 +++++++++--- libraries/audio/src/AudioInjectorLocalBuffer.h | 1 + 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index 912351e21a..333a944e1b 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -51,7 +51,7 @@ void AudioInjector::setIsFinished(bool isFinished) { emit finished(); if (_localBuffer) { - _localBuffer->stop(); + // delete will stop (and nosily if we do so ourselves here first). _localBuffer->deleteLater(); _localBuffer = NULL; } @@ -60,7 +60,6 @@ void AudioInjector::setIsFinished(bool isFinished) { if (_shouldDeleteAfterFinish) { // we've been asked to delete after finishing, trigger a queued deleteLater here - qCDebug(audio) << "AudioInjector triggering delete from setIsFinished"; QMetaObject::invokeMethod(this, "deleteLater", Qt::QueuedConnection); } } diff --git a/libraries/audio/src/AudioInjectorLocalBuffer.cpp b/libraries/audio/src/AudioInjectorLocalBuffer.cpp index f40e613437..457abeb89e 100644 --- a/libraries/audio/src/AudioInjectorLocalBuffer.cpp +++ b/libraries/audio/src/AudioInjectorLocalBuffer.cpp @@ -17,7 +17,8 @@ AudioInjectorLocalBuffer::AudioInjectorLocalBuffer(const QByteArray& rawAudioArr _shouldLoop(false), _isStopped(false), _currentOffset(0), - _volume(1.0f) + _volume(1.0f), + _isFinished(false) { } @@ -51,6 +52,11 @@ void copy(char* to, char* from, int size, qreal factor) { qint64 AudioInjectorLocalBuffer::readData(char* data, qint64 maxSize) { if (!_isStopped) { + if (_isFinished) { + emit bufferEmpty(); + return -1; // qt docs say -1 is appropriate when subsequent calls will not write data + } + // first copy to the end of the raw audio int bytesToEnd = _rawAudioArray.size() - _currentOffset; @@ -70,8 +76,8 @@ qint64 AudioInjectorLocalBuffer::readData(char* data, qint64 maxSize) { } if (!_shouldLoop && bytesRead == bytesToEnd) { - // we hit the end of the buffer, emit a signal - emit bufferEmpty(); + // If we emit bufferEmpty now, we'll clip the end of the sound. Wait until the next call. + _isFinished = true; } else if (_shouldLoop && _currentOffset == _rawAudioArray.size()) { _currentOffset = 0; } diff --git a/libraries/audio/src/AudioInjectorLocalBuffer.h b/libraries/audio/src/AudioInjectorLocalBuffer.h index 9753cbbd83..270e730590 100644 --- a/libraries/audio/src/AudioInjectorLocalBuffer.h +++ b/libraries/audio/src/AudioInjectorLocalBuffer.h @@ -44,6 +44,7 @@ private: int _currentOffset; float _volume; + bool _isFinished; }; #endif // hifi_AudioInjectorLocalBuffer_h \ No newline at end of file From 814e22364ad6fb46c22ebf6f58bc93796e7f4cd0 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Tue, 16 Jun 2015 11:30:28 -0700 Subject: [PATCH 18/41] coding standard fixes --- interface/src/devices/Joystick.cpp | 52 ++++++++++++------------ interface/src/devices/SixenseManager.cpp | 8 ++-- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/interface/src/devices/Joystick.cpp b/interface/src/devices/Joystick.cpp index a302becb77..07f3c4873c 100644 --- a/interface/src/devices/Joystick.cpp +++ b/interface/src/devices/Joystick.cpp @@ -61,20 +61,20 @@ void Joystick::handleAxisEvent(const SDL_ControllerAxisEvent& event) { switch (axis) { case SDL_CONTROLLER_AXIS_LEFTX: - _axisStateMap[makeInput(LEFT_AXIS_X_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; - _axisStateMap[makeInput(LEFT_AXIS_X_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(LEFT_AXIS_X_POS).getChannel()] = (event.value > 0.0f) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(LEFT_AXIS_X_NEG).getChannel()] = (event.value < 0.0f) ? -event.value / MAX_AXIS : 0.0f; break; case SDL_CONTROLLER_AXIS_LEFTY: - _axisStateMap[makeInput(LEFT_AXIS_Y_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; - _axisStateMap[makeInput(LEFT_AXIS_Y_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(LEFT_AXIS_Y_POS).getChannel()] = (event.value > 0.0f) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(LEFT_AXIS_Y_NEG).getChannel()] = (event.value < 0.0f) ? -event.value / MAX_AXIS : 0.0f; break; case SDL_CONTROLLER_AXIS_RIGHTX: - _axisStateMap[makeInput(RIGHT_AXIS_X_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; - _axisStateMap[makeInput(RIGHT_AXIS_X_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(RIGHT_AXIS_X_POS).getChannel()] = (event.value > 0.0f) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(RIGHT_AXIS_X_NEG).getChannel()] = (event.value < 0.0f) ? -event.value / MAX_AXIS : 0.0f; break; case SDL_CONTROLLER_AXIS_RIGHTY: - _axisStateMap[makeInput(RIGHT_AXIS_Y_POS).getChannel()] = (event.value > 0) ? event.value / MAX_AXIS : 0.0f; - _axisStateMap[makeInput(RIGHT_AXIS_Y_NEG).getChannel()] = (event.value < 0) ? -event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(RIGHT_AXIS_Y_POS).getChannel()] = (event.value > 0.0f) ? event.value / MAX_AXIS : 0.0f; + _axisStateMap[makeInput(RIGHT_AXIS_Y_NEG).getChannel()] = (event.value < 0.0f) ? -event.value / MAX_AXIS : 0.0f; break; case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: _axisStateMap[makeInput(RIGHT_SHOULDER).getChannel()] = event.value / MAX_AXIS; @@ -184,32 +184,32 @@ void Joystick::assignDefaultInputMapping(UserInputMapper& mapper) { // Hold front right shoulder button for precision controls // Left Joystick: Movement, strafing - mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(LEFT_AXIS_Y_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.); - mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(LEFT_AXIS_Y_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.); - mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(LEFT_AXIS_X_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.); - mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(LEFT_AXIS_X_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.); + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(LEFT_AXIS_Y_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(LEFT_AXIS_Y_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(LEFT_AXIS_X_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(LEFT_AXIS_X_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_MOVE_SPEED/2.0f); // Right Joystick: Camera orientation - mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(RIGHT_AXIS_X_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.); - mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(RIGHT_AXIS_X_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.); - mapper.addInputChannel(UserInputMapper::PITCH_UP, makeInput(RIGHT_AXIS_Y_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_PITCH_SPEED/2.); - mapper.addInputChannel(UserInputMapper::PITCH_DOWN, makeInput(RIGHT_AXIS_Y_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_PITCH_SPEED/2.); + mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(RIGHT_AXIS_X_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(RIGHT_AXIS_X_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::PITCH_UP, makeInput(RIGHT_AXIS_Y_NEG), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_PITCH_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::PITCH_DOWN, makeInput(RIGHT_AXIS_Y_POS), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_PITCH_SPEED/2.0f); // Dpad movement - mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(SDL_CONTROLLER_BUTTON_DPAD_UP), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); - mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(SDL_CONTROLLER_BUTTON_DPAD_DOWN), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); - mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(SDL_CONTROLLER_BUTTON_DPAD_RIGHT), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); - mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(SDL_CONTROLLER_BUTTON_DPAD_LEFT), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(SDL_CONTROLLER_BUTTON_DPAD_UP), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(SDL_CONTROLLER_BUTTON_DPAD_DOWN), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(SDL_CONTROLLER_BUTTON_DPAD_RIGHT), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(SDL_CONTROLLER_BUTTON_DPAD_LEFT), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.0f); // Button controls - mapper.addInputChannel(UserInputMapper::VERTICAL_UP, makeInput(SDL_CONTROLLER_BUTTON_Y), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); - mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(SDL_CONTROLLER_BUTTON_A), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.); - mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(SDL_CONTROLLER_BUTTON_X), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.); - mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(SDL_CONTROLLER_BUTTON_B), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.); + mapper.addInputChannel(UserInputMapper::VERTICAL_UP, makeInput(SDL_CONTROLLER_BUTTON_Y), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(SDL_CONTROLLER_BUTTON_A), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), DPAD_MOVE_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(SDL_CONTROLLER_BUTTON_X), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(SDL_CONTROLLER_BUTTON_B), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), JOYSTICK_YAW_SPEED/2.0f); // Zoom - mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(RIGHT_SHOULDER), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), BOOM_SPEED/2.); - mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(LEFT_SHOULDER), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), BOOM_SPEED/2.); + mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(RIGHT_SHOULDER), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), BOOM_SPEED/2.0f); + mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(LEFT_SHOULDER), makeInput(SDL_CONTROLLER_BUTTON_RIGHTSHOULDER), BOOM_SPEED/2.0f); #endif } diff --git a/interface/src/devices/SixenseManager.cpp b/interface/src/devices/SixenseManager.cpp index 959a1e147f..c2a53508e3 100644 --- a/interface/src/devices/SixenseManager.cpp +++ b/interface/src/devices/SixenseManager.cpp @@ -619,10 +619,10 @@ void SixenseManager::focusOutEvent() { }; void SixenseManager::handleAxisEvent(float stickX, float stickY, float trigger, int index) { - _axisStateMap[makeInput(AXIS_Y_POS, index).getChannel()] = (stickY > 0) ? stickY : 0.0f; - _axisStateMap[makeInput(AXIS_Y_NEG, index).getChannel()] = (stickY < 0) ? -stickY : 0.0f; - _axisStateMap[makeInput(AXIS_X_POS, index).getChannel()] = (stickX > 0) ? stickX : 0.0f; - _axisStateMap[makeInput(AXIS_X_NEG, index).getChannel()] = (stickX < 0) ? -stickX : 0.0f; + _axisStateMap[makeInput(AXIS_Y_POS, index).getChannel()] = (stickY > 0.0f) ? stickY : 0.0f; + _axisStateMap[makeInput(AXIS_Y_NEG, index).getChannel()] = (stickY < 0.0f) ? -stickY : 0.0f; + _axisStateMap[makeInput(AXIS_X_POS, index).getChannel()] = (stickX > 0.0f) ? stickX : 0.0f; + _axisStateMap[makeInput(AXIS_X_NEG, index).getChannel()] = (stickX < 0.0f) ? -stickX : 0.0f; _axisStateMap[makeInput(BACK_TRIGGER, index).getChannel()] = trigger; } From 156adb1a9870bf4ad0021b973f745984c7368dc8 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Tue, 16 Jun 2015 11:34:59 -0700 Subject: [PATCH 19/41] one more coding standard fix --- interface/src/avatar/MyAvatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 6fe99b89e4..586e7a1f56 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -70,7 +70,7 @@ const int SCRIPTED_MOTOR_CAMERA_FRAME = 0; const int SCRIPTED_MOTOR_AVATAR_FRAME = 1; const int SCRIPTED_MOTOR_WORLD_FRAME = 2; -const float MyAvatar::ZOOM_MIN = .5f; +const float MyAvatar::ZOOM_MIN = 0.5f; const float MyAvatar::ZOOM_MAX = 10.0f; const float MyAvatar::ZOOM_DEFAULT = 1.5f; From 167e7d13777693ce748ffdc3e145cd7244c8e4c0 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 16 Jun 2015 14:05:14 -0700 Subject: [PATCH 20/41] first cut at atmospheres in batch (doesn't work) --- interface/src/Application.cpp | 10 +- interface/src/Environment.cpp | 150 +++++++++++++++--- interface/src/Environment.h | 17 +- libraries/gpu/src/gpu/Batch.h | 2 + libraries/gpu/src/gpu/GLBackend.cpp | 28 ++++ .../model/src/model/SkyFromAtmosphere.slf | 6 +- .../model/src/model/SkyFromAtmosphere.slv | 21 +-- libraries/model/src/model/SkyFromSpace.slf | 4 +- libraries/model/src/model/SkyFromSpace.slv | 25 ++- 9 files changed, 217 insertions(+), 46 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 22cbad6775..4c84e39b64 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3255,6 +3255,9 @@ namespace render { template <> const Item::Bound payloadGetBound(const BackgroundRenderData::Pointer& stuff) { return Item::Bound(); } template <> void payloadRender(const BackgroundRenderData::Pointer& background, RenderArgs* args) { + Q_ASSERT(args->_batch); + gpu::Batch& batch = *args->_batch; + // Background rendering decision auto skyStage = DependencyManager::get()->getSkyStage(); auto skybox = model::SkyboxPointer(); @@ -3322,7 +3325,11 @@ namespace render { PerformanceTimer perfTimer("atmosphere"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... atmosphere..."); - background->_environment->renderAtmospheres(*(args->_viewFrustum)); + //gpu::Batch batch; + background->_environment->renderAtmospheres(batch, *(args->_viewFrustum)); + //gpu::GLBackend::renderBatch(batch, true); + //glUseProgram(0); + } } @@ -3333,7 +3340,6 @@ namespace render { if (skybox) { gpu::Batch batch; model::Skybox::render(batch, *(Application::getInstance()->getDisplayViewFrustum()), *skybox); - gpu::GLBackend::renderBatch(batch, true); glUseProgram(0); } diff --git a/interface/src/Environment.cpp b/interface/src/Environment.cpp index 9f197920d9..1e9c571a57 100644 --- a/interface/src/Environment.cpp +++ b/interface/src/Environment.cpp @@ -28,6 +28,11 @@ #include "Environment.h" +#include "../../build/libraries/model/SkyFromSpace_vert.h" +#include "../../build/libraries/model/SkyFromSpace_frag.h" +#include "../../build/libraries/model/SkyFromAtmosphere_vert.h" +#include "../../build/libraries/model/SkyFromAtmosphere_frag.h" + uint qHash(const HifiSockAddr& sockAddr) { if (sockAddr.getAddress().isNull()) { return 0; // shouldn't happen, but if it does, zero is a perfectly valid hash @@ -56,6 +61,15 @@ void Environment::init() { _skyFromAtmosphereProgram = createSkyProgram("Atmosphere", _skyFromAtmosphereUniformLocations); _skyFromSpaceProgram = createSkyProgram("Space", _skyFromSpaceUniformLocations); + + + + qDebug() << "line:" << __LINE__; + setupAtmosphereProgram(SkyFromSpace_vert, SkyFromSpace_frag, _newSkyFromSpaceProgram, _newSkyFromSpaceUniformLocations); + qDebug() << "line:" << __LINE__; + setupAtmosphereProgram(SkyFromAtmosphere_vert, SkyFromAtmosphere_frag, _newSkyFromAtmosphereProgram, _newSkyFromAtmosphereUniformLocations); + qDebug() << "line:" << __LINE__; + // start off with a default-constructed environment data _data[HifiSockAddr()][0]; @@ -63,22 +77,84 @@ void Environment::init() { _initialized = true; } +void Environment::setupAtmosphereProgram(const char* vertSource, const char* fragSource, gpu::PipelinePointer& pipelineProgram, int* locations) { + + auto VS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(vertSource))); + auto PS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(fragSource))); + + gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(VS, PS)); + + gpu::Shader::BindingSet slotBindings; + gpu::Shader::makeProgram(*program, slotBindings); + + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + state->setCullMode(gpu::State::CULL_NONE); + state->setDepthTest(false); + state->setBlendFunction(true,gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); + pipelineProgram = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); + + locations[CAMERA_POS_LOCATION] = program->getUniforms().findLocation("v3CameraPos"); + locations[LIGHT_POS_LOCATION] = program->getUniforms().findLocation("v3LightPos"); + locations[INV_WAVELENGTH_LOCATION] = program->getUniforms().findLocation("v3InvWavelength"); + locations[CAMERA_HEIGHT2_LOCATION] = program->getUniforms().findLocation("fCameraHeight2"); + locations[OUTER_RADIUS_LOCATION] = program->getUniforms().findLocation("fOuterRadius"); + locations[OUTER_RADIUS2_LOCATION] = program->getUniforms().findLocation("fOuterRadius2"); + locations[INNER_RADIUS_LOCATION] = program->getUniforms().findLocation("fInnerRadius"); + locations[KR_ESUN_LOCATION] = program->getUniforms().findLocation("fKrESun"); + locations[KM_ESUN_LOCATION] = program->getUniforms().findLocation("fKmESun"); + locations[KR_4PI_LOCATION] = program->getUniforms().findLocation("fKr4PI"); + locations[KM_4PI_LOCATION] = program->getUniforms().findLocation("fKm4PI"); + locations[SCALE_LOCATION] = program->getUniforms().findLocation("fScale"); + locations[SCALE_DEPTH_LOCATION] = program->getUniforms().findLocation("fScaleDepth"); + locations[SCALE_OVER_SCALE_DEPTH_LOCATION] = program->getUniforms().findLocation("fScaleOverScaleDepth"); + locations[G_LOCATION] = program->getUniforms().findLocation("g"); + locations[G2_LOCATION] = program->getUniforms().findLocation("g2"); + + /* + + program.addShaderFromSourceCode(QGLShader::Vertex, vertSource); + program.addShaderFromSourceCode(QGLShader::Fragment, fragSource); + program.link(); + + program.bind(); + + locations[CAMERA_POS_LOCATION] = program.uniformLocation("v3CameraPos"); + locations[LIGHT_POS_LOCATION] = program.uniformLocation("v3LightPos"); + locations[INV_WAVELENGTH_LOCATION] = program.uniformLocation("v3InvWavelength"); + locations[CAMERA_HEIGHT2_LOCATION] = program.uniformLocation("fCameraHeight2"); + locations[OUTER_RADIUS_LOCATION] = program.uniformLocation("fOuterRadius"); + locations[OUTER_RADIUS2_LOCATION] = program.uniformLocation("fOuterRadius2"); + locations[INNER_RADIUS_LOCATION] = program.uniformLocation("fInnerRadius"); + locations[KR_ESUN_LOCATION] = program.uniformLocation("fKrESun"); + locations[KM_ESUN_LOCATION] = program.uniformLocation("fKmESun"); + locations[KR_4PI_LOCATION] = program.uniformLocation("fKr4PI"); + locations[KM_4PI_LOCATION] = program.uniformLocation("fKm4PI"); + locations[SCALE_LOCATION] = program.uniformLocation("fScale"); + locations[SCALE_DEPTH_LOCATION] = program.uniformLocation("fScaleDepth"); + locations[SCALE_OVER_SCALE_DEPTH_LOCATION] = program.uniformLocation("fScaleOverScaleDepth"); + locations[G_LOCATION] = program.uniformLocation("g"); + locations[G2_LOCATION] = program.uniformLocation("g2"); + + program.release(); + */ +} + void Environment::resetToDefault() { _data.clear(); _data[HifiSockAddr()][0]; } -void Environment::renderAtmospheres(ViewFrustum& camera) { +void Environment::renderAtmospheres(gpu::Batch& batch, ViewFrustum& camera) { // get the lock for the duration of the call QMutexLocker locker(&_mutex); if (_environmentIsOverridden) { - renderAtmosphere(camera, _overrideData); + renderAtmosphere(batch, camera, _overrideData); } else { foreach (const ServerData& serverData, _data) { // TODO: do something about EnvironmentData foreach (const EnvironmentData& environmentData, serverData) { - renderAtmosphere(camera, environmentData); + renderAtmosphere(batch, camera, environmentData); } } } @@ -228,30 +304,39 @@ ProgramObject* Environment::createSkyProgram(const char* from, int* locations) { return program; } -void Environment::renderAtmosphere(ViewFrustum& camera, const EnvironmentData& data) { +void Environment::renderAtmosphere(gpu::Batch& batch, ViewFrustum& camera, const EnvironmentData& data) { glm::vec3 center = data.getAtmosphereCenter(); - glPushMatrix(); - glTranslatef(center.x, center.y, center.z); + //glPushMatrix(); + //glTranslatef(center.x, center.y, center.z); + + Transform transform; + transform.setTranslation(center); + transform.setScale(1.0f); + batch.setModelTransform(transform); glm::vec3 relativeCameraPos = camera.getPosition() - center; float height = glm::length(relativeCameraPos); // use the appropriate shader depending on whether we're inside or outside - ProgramObject* program; + //ProgramObject* program; int* locations; if (height < data.getAtmosphereOuterRadius()) { - program = _skyFromAtmosphereProgram; - locations = _skyFromAtmosphereUniformLocations; + //program = &_newSkyFromAtmosphereProgram; + batch.setPipeline(_newSkyFromAtmosphereProgram); + locations = _newSkyFromAtmosphereUniformLocations; } else { - program = _skyFromSpaceProgram; - locations = _skyFromSpaceUniformLocations; + //program = &_newSkyFromSpaceProgram; + batch.setPipeline(_newSkyFromSpaceProgram); + locations = _newSkyFromSpaceUniformLocations; } // the constants here are from Sean O'Neil's GPU Gems entry // (http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html), GameEngine.cpp - program->bind(); + + //program->bind(); + /* program->setUniform(locations[CAMERA_POS_LOCATION], relativeCameraPos); glm::vec3 lightDirection = glm::normalize(data.getSunLocation()); program->setUniform(locations[LIGHT_POS_LOCATION], lightDirection); @@ -273,15 +358,40 @@ void Environment::renderAtmosphere(ViewFrustum& camera, const EnvironmentData& d (1.0f / (data.getAtmosphereOuterRadius() - data.getAtmosphereInnerRadius())) / 0.25f); program->setUniformValue(locations[G_LOCATION], -0.990f); program->setUniformValue(locations[G2_LOCATION], -0.990f * -0.990f); + */ - glDepthMask(GL_FALSE); - glDisable(GL_DEPTH_TEST); - glDisable(GL_CULL_FACE); - glEnable(GL_BLEND); - DependencyManager::get()->renderSphere(1.0f, 100, 50, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); //Draw a unit sphere - glDepthMask(GL_TRUE); + + batch._glUniform3fv(locations[CAMERA_POS_LOCATION], relativeCameraPos); + glm::vec3 lightDirection = glm::normalize(data.getSunLocation()); + batch._glUniform3fv(locations[LIGHT_POS_LOCATION], lightDirection); + batch._glUniform3f(locations[INV_WAVELENGTH_LOCATION], + 1 / powf(data.getScatteringWavelengths().r, 4.0f), + 1 / powf(data.getScatteringWavelengths().g, 4.0f), + 1 / powf(data.getScatteringWavelengths().b, 4.0f)); + batch._glUniform1f(locations[CAMERA_HEIGHT2_LOCATION], height * height); + batch._glUniform1f(locations[OUTER_RADIUS_LOCATION], data.getAtmosphereOuterRadius()); + batch._glUniform1f(locations[OUTER_RADIUS2_LOCATION], data.getAtmosphereOuterRadius() * data.getAtmosphereOuterRadius()); + batch._glUniform1f(locations[INNER_RADIUS_LOCATION], data.getAtmosphereInnerRadius()); + batch._glUniform1f(locations[KR_ESUN_LOCATION], data.getRayleighScattering() * data.getSunBrightness()); + batch._glUniform1f(locations[KM_ESUN_LOCATION], data.getMieScattering() * data.getSunBrightness()); + batch._glUniform1f(locations[KR_4PI_LOCATION], data.getRayleighScattering() * 4.0f * PI); + batch._glUniform1f(locations[KM_4PI_LOCATION], data.getMieScattering() * 4.0f * PI); + batch._glUniform1f(locations[SCALE_LOCATION], 1.0f / (data.getAtmosphereOuterRadius() - data.getAtmosphereInnerRadius())); + batch._glUniform1f(locations[SCALE_DEPTH_LOCATION], 0.25f); + batch._glUniform1f(locations[SCALE_OVER_SCALE_DEPTH_LOCATION], + (1.0f / (data.getAtmosphereOuterRadius() - data.getAtmosphereInnerRadius())) / 0.25f); + batch._glUniform1f(locations[G_LOCATION], -0.990f); + batch._glUniform1f(locations[G2_LOCATION], -0.990f * -0.990f); + + + //glDepthMask(GL_FALSE); + //glDisable(GL_DEPTH_TEST); + //glDisable(GL_CULL_FACE); + //glEnable(GL_BLEND); + DependencyManager::get()->renderSphere(batch,1.0f, 100, 50, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); //Draw a unit sphere + //glDepthMask(GL_TRUE); - program->release(); + //program->release(); - glPopMatrix(); + //glPopMatrix(); } diff --git a/interface/src/Environment.h b/interface/src/Environment.h index c1b4171947..9048678230 100644 --- a/interface/src/Environment.h +++ b/interface/src/Environment.h @@ -16,6 +16,9 @@ #include #include +#include + +#include #include "EnvironmentData.h" @@ -29,7 +32,7 @@ public: void init(); void resetToDefault(); - void renderAtmospheres(ViewFrustum& camera); + void renderAtmospheres(gpu::Batch& batch, ViewFrustum& camera); void override(const EnvironmentData& overrideData) { _overrideData = overrideData; _environmentIsOverridden = true; } void endOverride() { _environmentIsOverridden = false; } @@ -46,12 +49,12 @@ private: ProgramObject* createSkyProgram(const char* from, int* locations); - void renderAtmosphere(ViewFrustum& camera, const EnvironmentData& data); + void renderAtmosphere(gpu::Batch& batch, ViewFrustum& camera, const EnvironmentData& data); bool _initialized; ProgramObject* _skyFromAtmosphereProgram; ProgramObject* _skyFromSpaceProgram; - + enum { CAMERA_POS_LOCATION, LIGHT_POS_LOCATION, @@ -74,6 +77,14 @@ private: int _skyFromAtmosphereUniformLocations[LOCATION_COUNT]; int _skyFromSpaceUniformLocations[LOCATION_COUNT]; + + void setupAtmosphereProgram(const char* vertSource, const char* fragSource, gpu::PipelinePointer& pipelineProgram, int* locations); + + + gpu::PipelinePointer _newSkyFromAtmosphereProgram; + gpu::PipelinePointer _newSkyFromSpaceProgram; + int _newSkyFromAtmosphereUniformLocations[LOCATION_COUNT]; + int _newSkyFromSpaceUniformLocations[LOCATION_COUNT]; typedef QHash ServerData; diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 405ea9459d..77c9308af5 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -150,6 +150,7 @@ public: void _glUseProgram(GLuint program); void _glUniform1f(GLint location, GLfloat v0); void _glUniform2f(GLint location, GLfloat v0, GLfloat v1); + void _glUniform3f(GLint location, GLfloat v0, GLfloat v1); void _glUniform4fv(GLint location, GLsizei count, const GLfloat* value); void _glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); @@ -210,6 +211,7 @@ public: COMMAND_glUseProgram, COMMAND_glUniform1f, COMMAND_glUniform2f, + COMMAND_glUniform3f, COMMAND_glUniform4fv, COMMAND_glUniformMatrix4fv, diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index da6979fb27..7ba344dfbd 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -61,6 +61,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = (&::gpu::GLBackend::do_glUseProgram), (&::gpu::GLBackend::do_glUniform1f), (&::gpu::GLBackend::do_glUniform2f), + (&::gpu::GLBackend::do_glUniform3f), (&::gpu::GLBackend::do_glUniform4fv), (&::gpu::GLBackend::do_glUniformMatrix4fv), @@ -462,6 +463,7 @@ void Batch::_glUniform2f(GLint location, GLfloat v0, GLfloat v1) { DO_IT_NOW(_glUniform2f, 1); } + void GLBackend::do_glUniform2f(Batch& batch, uint32 paramOffset) { if (_pipeline._program == 0) { // We should call updatePipeline() to bind the program but we are not doing that @@ -475,6 +477,32 @@ void GLBackend::do_glUniform2f(Batch& batch, uint32 paramOffset) { (void) CHECK_GL_ERROR(); } +void Batch::_glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) { + ADD_COMMAND_GL(glUniform3f); + + _params.push_back(v2); + _params.push_back(v1); + _params.push_back(v0); + _params.push_back(location); + + DO_IT_NOW(_glUniform3f, 1); +} + +void GLBackend::do_glUniform3f(Batch& batch, uint32 paramOffset) { + if (_pipeline._program == 0) { + // We should call updatePipeline() to bind the program but we are not doing that + // because these uniform setters are deprecated and we don;t want to create side effect + return; + } + glUniform3f( + batch._params[paramOffset + 3]._int, + batch._params[paramOffset + 2]._float, + batch._params[paramOffset + 1]._float, + batch._params[paramOffset + 0]._float); + (void) CHECK_GL_ERROR(); +} + + void Batch::_glUniform4fv(GLint location, GLsizei count, const GLfloat* value) { ADD_COMMAND_GL(glUniform4fv); diff --git a/libraries/model/src/model/SkyFromAtmosphere.slf b/libraries/model/src/model/SkyFromAtmosphere.slf index 02036d0d7c..b82cddc282 100755 --- a/libraries/model/src/model/SkyFromAtmosphere.slf +++ b/libraries/model/src/model/SkyFromAtmosphere.slf @@ -51,7 +51,8 @@ uniform vec3 v3LightPos; uniform float g; uniform float g2; -varying vec3 position; +varying vec3 myPosition; + float scale(float fCos) { @@ -59,10 +60,11 @@ float scale(float fCos) return fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25)))); } + void main (void) { // Get the ray from the camera to the vertex, and its length (which is the far point of the ray passing through the atmosphere) - vec3 v3Pos = position; + vec3 v3Pos = myPosition; vec3 v3Ray = v3Pos - v3CameraPos; float fFar = length(v3Ray); v3Ray /= fFar; diff --git a/libraries/model/src/model/SkyFromAtmosphere.slv b/libraries/model/src/model/SkyFromAtmosphere.slv index 785f89bb48..c19cb34c6a 100755 --- a/libraries/model/src/model/SkyFromAtmosphere.slv +++ b/libraries/model/src/model/SkyFromAtmosphere.slv @@ -33,6 +33,9 @@ // Copyright (c) 2004 Sean O'Neil // +<@include gpu/Transform.slh@> +<$declareStandardTransform()$> + uniform vec3 v3CameraPos; // The camera's current position uniform vec3 v3LightPos; // The direction vector to the light source uniform vec3 v3InvWavelength; // 1 / pow(wavelength, 4) for the red, green, and blue channels @@ -50,19 +53,19 @@ uniform float fScaleOverScaleDepth; // fScale / fScaleDepth const int nSamples = 2; const float fSamples = 2.0; -varying vec3 position; +varying vec3 myPosition; -float scale(float fCos) -{ - float x = 1.0 - fCos; - return fScaleDepth * exp(-0.00287 + x*(0.459 + x*(3.83 + x*(-6.80 + x*5.25)))); -} - void main(void) { // Get the ray from the camera to the vertex, and its length (which is the far point of the ray passing through the atmosphere) - position = gl_Vertex.xyz * fOuterRadius; + myPosition = gl_Vertex.xyz * fOuterRadius; - gl_Position = gl_ModelViewProjectionMatrix * vec4(position, 1.0); + //gl_Position = gl_ModelViewProjectionMatrix * vec4(position, 1.0); + + // standard transform + TransformCamera cam = getTransformCamera(); + TransformObject obj = getTransformObject(); + vec4 v4pos = vec4(myPosition, 1.0); + <$transformModelToClipPos(cam, obj, v4pos, gl_Position)$> } diff --git a/libraries/model/src/model/SkyFromSpace.slf b/libraries/model/src/model/SkyFromSpace.slf index 5f6ce80efa..4e13438ccb 100755 --- a/libraries/model/src/model/SkyFromSpace.slf +++ b/libraries/model/src/model/SkyFromSpace.slf @@ -53,7 +53,7 @@ uniform float g2; const int nSamples = 2; const float fSamples = 2.0; -varying vec3 position; +varying vec3 myPosition; float scale(float fCos) { @@ -65,7 +65,7 @@ float scale(float fCos) void main (void) { // Get the ray from the camera to the vertex and its length (which is the far point of the ray passing through the atmosphere) - vec3 v3Pos = position; + vec3 v3Pos = myPosition; vec3 v3Ray = v3Pos - v3CameraPos; float fFar = length(v3Ray); v3Ray /= fFar; diff --git a/libraries/model/src/model/SkyFromSpace.slv b/libraries/model/src/model/SkyFromSpace.slv index 6740d1909e..9090d76da2 100755 --- a/libraries/model/src/model/SkyFromSpace.slv +++ b/libraries/model/src/model/SkyFromSpace.slv @@ -1,5 +1,6 @@ -#version 120 - +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> // // For licensing information, see http://http.developer.nvidia.com/GPUGems/gpugems_app01.html: // @@ -32,12 +33,20 @@ // Copyright (c) 2004 Sean O'Neil // +<@include gpu/Transform.slh@> +<$declareStandardTransform()$> + uniform float fOuterRadius; // The outer (atmosphere) radius -varying vec3 position; +varying vec3 myPosition; -void main(void) -{ - position = gl_Vertex.xyz * fOuterRadius; - gl_Position = gl_ModelViewProjectionMatrix * vec4(position, 1.0); -} + +void main(void) { + myPosition = gl_Vertex.xyz * fOuterRadius; + + // standard transform + TransformCamera cam = getTransformCamera(); + TransformObject obj = getTransformObject(); + vec4 v4pos = vec4(myPosition, 1.0); + <$transformModelToClipPos(cam, obj, v4pos, gl_Position)$> +} \ No newline at end of file From d47f5a2abb87c47109f62322bab410083e630f1b Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 16 Jun 2015 16:44:33 -0700 Subject: [PATCH 21/41] Update Rectangle, Grid, and Billboard overlays to use batches --- .../src/ui/overlays/BillboardOverlay.cpp | 122 +++++++----- interface/src/ui/overlays/Grid3DOverlay.cpp | 181 +++++++++++------- .../src/ui/overlays/Rectangle3DOverlay.cpp | 146 +++++++++----- 3 files changed, 274 insertions(+), 175 deletions(-) diff --git a/interface/src/ui/overlays/BillboardOverlay.cpp b/interface/src/ui/overlays/BillboardOverlay.cpp index 3e3e823737..ed0ddd8dc7 100644 --- a/interface/src/ui/overlays/BillboardOverlay.cpp +++ b/interface/src/ui/overlays/BillboardOverlay.cpp @@ -43,72 +43,88 @@ void BillboardOverlay::render(RenderArgs* args) { return; } - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0.5f); + glm::quat rotation; + if (_isFacingAvatar) { + // rotate about vertical to face the camera + rotation = Application::getInstance()->getCamera()->getRotation(); + rotation *= glm::angleAxis(glm::pi(), glm::vec3(0.0f, 1.0f, 0.0f)); + rotation *= getRotation(); + } else { + rotation = getRotation(); + } - glEnable(GL_TEXTURE_2D); - glDisable(GL_LIGHTING); + float imageWidth = _texture->getWidth(); + float imageHeight = _texture->getHeight(); - glBindTexture(GL_TEXTURE_2D, _texture->getID()); + QRect fromImage; + if (_fromImage.isNull()) { + fromImage.setX(0); + fromImage.setY(0); + fromImage.setWidth(imageWidth); + fromImage.setHeight(imageHeight); + } else { + float scaleX = imageWidth / _texture->getOriginalWidth(); + float scaleY = imageHeight / _texture->getOriginalHeight(); - glPushMatrix(); { - glTranslatef(_position.x, _position.y, _position.z); - glm::quat rotation; - if (_isFacingAvatar) { - // rotate about vertical to face the camera - rotation = Application::getInstance()->getCamera()->getRotation(); - rotation *= glm::angleAxis(glm::pi(), glm::vec3(0.0f, 1.0f, 0.0f)); - rotation *= getRotation(); - } else { - rotation = getRotation(); - } - glm::vec3 axis = glm::axis(rotation); - glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); - glScalef(_scale, _scale, _scale); + fromImage.setX(scaleX * _fromImage.x()); + fromImage.setY(scaleY * _fromImage.y()); + fromImage.setWidth(scaleX * _fromImage.width()); + fromImage.setHeight(scaleY * _fromImage.height()); + } - const float MAX_COLOR = 255.0f; - xColor color = getColor(); - float alpha = getAlpha(); + float maxSize = glm::max(fromImage.width(), fromImage.height()); + float x = fromImage.width() / (2.0f * maxSize); + float y = -fromImage.height() / (2.0f * maxSize); - float imageWidth = _texture->getWidth(); - float imageHeight = _texture->getHeight(); + glm::vec2 topLeft(-x, -y); + glm::vec2 bottomRight(x, y); + glm::vec2 texCoordTopLeft(fromImage.x() / imageWidth, fromImage.y() / imageHeight); + glm::vec2 texCoordBottomRight((fromImage.x() + fromImage.width()) / imageWidth, + (fromImage.y() + fromImage.height()) / imageHeight); - QRect fromImage; - if (_fromImage.isNull()) { - fromImage.setX(0); - fromImage.setY(0); - fromImage.setWidth(imageWidth); - fromImage.setHeight(imageHeight); - } else { - float scaleX = imageWidth / _texture->getOriginalWidth(); - float scaleY = imageHeight / _texture->getOriginalHeight(); + const float MAX_COLOR = 255.0f; + xColor color = getColor(); + float alpha = getAlpha(); - fromImage.setX(scaleX * _fromImage.x()); - fromImage.setY(scaleY * _fromImage.y()); - fromImage.setWidth(scaleX * _fromImage.width()); - fromImage.setHeight(scaleY * _fromImage.height()); - } + auto batch = args->_batch; - float maxSize = glm::max(fromImage.width(), fromImage.height()); - float x = fromImage.width() / (2.0f * maxSize); - float y = -fromImage.height() / (2.0f * maxSize); + if (batch) { + Transform transform; + transform.setTranslation(_position); + transform.setRotation(rotation); + transform.setScale(_scale); - glm::vec2 topLeft(-x, -y); - glm::vec2 bottomRight(x, y); - glm::vec2 texCoordTopLeft(fromImage.x() / imageWidth, fromImage.y() / imageHeight); - glm::vec2 texCoordBottomRight((fromImage.x() + fromImage.width()) / imageWidth, - (fromImage.y() + fromImage.height()) / imageHeight); - - DependencyManager::get()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, + batch->setModelTransform(transform); + batch->setUniformTexture(0, _texture->getGPUTexture()); + + DependencyManager::get()->renderQuad(*batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha)); + } else { + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.5f); - } glPopMatrix(); + glEnable(GL_TEXTURE_2D); + glDisable(GL_LIGHTING); - glDisable(GL_TEXTURE_2D); - glEnable(GL_LIGHTING); - glDisable(GL_ALPHA_TEST); + glBindTexture(GL_TEXTURE_2D, _texture->getID()); - glBindTexture(GL_TEXTURE_2D, 0); + glPushMatrix(); { + glTranslatef(_position.x, _position.y, _position.z); + glm::vec3 axis = glm::axis(rotation); + glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); + glScalef(_scale, _scale, _scale); + + DependencyManager::get()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, + glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha)); + + } glPopMatrix(); + + glDisable(GL_TEXTURE_2D); + glEnable(GL_LIGHTING); + glDisable(GL_ALPHA_TEST); + + glBindTexture(GL_TEXTURE_2D, 0); + } } void BillboardOverlay::setProperties(const QScriptValue &properties) { diff --git a/interface/src/ui/overlays/Grid3DOverlay.cpp b/interface/src/ui/overlays/Grid3DOverlay.cpp index b39b2c3274..e68e5b47f2 100644 --- a/interface/src/ui/overlays/Grid3DOverlay.cpp +++ b/interface/src/ui/overlays/Grid3DOverlay.cpp @@ -36,87 +36,128 @@ void Grid3DOverlay::render(RenderArgs* args) { return; // do nothing if we're not visible } - if (!_gridProgram.isLinked()) { - if (!_gridProgram.addShaderFromSourceFile(QGLShader::Vertex, PathUtils::resourcesPath() + "shaders/grid.vert")) { - qDebug() << "Failed to compile: " + _gridProgram.log(); - return; - } - if (!_gridProgram.addShaderFromSourceFile(QGLShader::Fragment, PathUtils::resourcesPath() + "shaders/grid.frag")) { - qDebug() << "Failed to compile: " + _gridProgram.log(); - return; - } - if (!_gridProgram.link()) { - qDebug() << "Failed to link: " + _gridProgram.log(); - return; - } - } - - // Render code largely taken from MetavoxelEditor::render() - glDisable(GL_LIGHTING); - - glDepthMask(GL_FALSE); - - glPushMatrix(); - - glm::quat rotation = getRotation(); - - glm::vec3 axis = glm::axis(rotation); - - glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); - - glLineWidth(1.5f); - - // center the grid around the camera position on the plane - glm::vec3 rotated = glm::inverse(rotation) * Application::getInstance()->getCamera()->getPosition(); - float spacing = _minorGridWidth; - - float alpha = getAlpha(); - xColor color = getColor(); - glm::vec3 position = getPosition(); - const int MINOR_GRID_DIVISIONS = 200; const int MAJOR_GRID_DIVISIONS = 100; const float MAX_COLOR = 255.0f; + // center the grid around the camera position on the plane + glm::vec3 rotated = glm::inverse(_rotation) * Application::getInstance()->getCamera()->getPosition(); + float spacing = _minorGridWidth; + + float alpha = getAlpha(); + xColor color = getColor(); glm::vec4 gridColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); - _gridProgram.bind(); + auto batch = args->_batch; - // Minor grid - glPushMatrix(); - { - glTranslatef(_minorGridWidth * (floorf(rotated.x / spacing) - MINOR_GRID_DIVISIONS / 2), - spacing * (floorf(rotated.y / spacing) - MINOR_GRID_DIVISIONS / 2), position.z); + if (batch) { + Transform transform; + transform.setRotation(_rotation); - float scale = MINOR_GRID_DIVISIONS * spacing; - glScalef(scale, scale, scale); - DependencyManager::get()->renderGrid(MINOR_GRID_DIVISIONS, MINOR_GRID_DIVISIONS, gridColor); + // Minor grid + { + batch->_glLineWidth(1.0f); + auto position = glm::vec3(_minorGridWidth * (floorf(rotated.x / spacing) - MINOR_GRID_DIVISIONS / 2), + spacing * (floorf(rotated.y / spacing) - MINOR_GRID_DIVISIONS / 2), + _position.z); + float scale = MINOR_GRID_DIVISIONS * spacing; + + transform.setTranslation(position); + transform.setScale(scale); + + batch->setModelTransform(transform); + + DependencyManager::get()->renderGrid(*batch, MINOR_GRID_DIVISIONS, MINOR_GRID_DIVISIONS, gridColor); + } + + // Major grid + { + batch->_glLineWidth(4.0f); + spacing *= _majorGridEvery; + auto position = glm::vec3(spacing * (floorf(rotated.x / spacing) - MAJOR_GRID_DIVISIONS / 2), + spacing * (floorf(rotated.y / spacing) - MAJOR_GRID_DIVISIONS / 2), + _position.z); + float scale = MAJOR_GRID_DIVISIONS * spacing; + + transform.setTranslation(position); + transform.setScale(scale); + + batch->setModelTransform(transform); + + DependencyManager::get()->renderGrid(*batch, MAJOR_GRID_DIVISIONS, MAJOR_GRID_DIVISIONS, gridColor); + } + } else { + if (!_gridProgram.isLinked()) { + if (!_gridProgram.addShaderFromSourceFile(QGLShader::Vertex, PathUtils::resourcesPath() + "shaders/grid.vert")) { + qDebug() << "Failed to compile: " + _gridProgram.log(); + return; + } + if (!_gridProgram.addShaderFromSourceFile(QGLShader::Fragment, PathUtils::resourcesPath() + "shaders/grid.frag")) { + qDebug() << "Failed to compile: " + _gridProgram.log(); + return; + } + if (!_gridProgram.link()) { + qDebug() << "Failed to link: " + _gridProgram.log(); + return; + } + } + + // Render code largely taken from MetavoxelEditor::render() + glDisable(GL_LIGHTING); + + glDepthMask(GL_FALSE); + + glPushMatrix(); + + glm::quat rotation = getRotation(); + + glm::vec3 axis = glm::axis(rotation); + + glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); + + glLineWidth(1.5f); + + glm::vec3 position = getPosition(); + + _gridProgram.bind(); + + // Minor grid + glPushMatrix(); + { + glTranslatef(_minorGridWidth * (floorf(rotated.x / spacing) - MINOR_GRID_DIVISIONS / 2), + spacing * (floorf(rotated.y / spacing) - MINOR_GRID_DIVISIONS / 2), position.z); + + float scale = MINOR_GRID_DIVISIONS * spacing; + glScalef(scale, scale, scale); + + DependencyManager::get()->renderGrid(MINOR_GRID_DIVISIONS, MINOR_GRID_DIVISIONS, gridColor); + } + glPopMatrix(); + + // Major grid + glPushMatrix(); + { + glLineWidth(4.0f); + spacing *= _majorGridEvery; + glTranslatef(spacing * (floorf(rotated.x / spacing) - MAJOR_GRID_DIVISIONS / 2), + spacing * (floorf(rotated.y / spacing) - MAJOR_GRID_DIVISIONS / 2), position.z); + + float scale = MAJOR_GRID_DIVISIONS * spacing; + glScalef(scale, scale, scale); + + DependencyManager::get()->renderGrid(MAJOR_GRID_DIVISIONS, MAJOR_GRID_DIVISIONS, gridColor); + } + glPopMatrix(); + + _gridProgram.release(); + + glPopMatrix(); + + glEnable(GL_LIGHTING); + glDepthMask(GL_TRUE); } - glPopMatrix(); - - // Major grid - glPushMatrix(); - { - glLineWidth(4.0f); - spacing *= _majorGridEvery; - glTranslatef(spacing * (floorf(rotated.x / spacing) - MAJOR_GRID_DIVISIONS / 2), - spacing * (floorf(rotated.y / spacing) - MAJOR_GRID_DIVISIONS / 2), position.z); - - float scale = MAJOR_GRID_DIVISIONS * spacing; - glScalef(scale, scale, scale); - - DependencyManager::get()->renderGrid(MAJOR_GRID_DIVISIONS, MAJOR_GRID_DIVISIONS, gridColor); - } - glPopMatrix(); - - _gridProgram.release(); - - glPopMatrix(); - - glEnable(GL_LIGHTING); - glDepthMask(GL_TRUE); } void Grid3DOverlay::setProperties(const QScriptValue& properties) { diff --git a/interface/src/ui/overlays/Rectangle3DOverlay.cpp b/interface/src/ui/overlays/Rectangle3DOverlay.cpp index 8662030e23..dc5fdeabb2 100644 --- a/interface/src/ui/overlays/Rectangle3DOverlay.cpp +++ b/interface/src/ui/overlays/Rectangle3DOverlay.cpp @@ -41,74 +41,116 @@ void Rectangle3DOverlay::render(RenderArgs* args) { const float MAX_COLOR = 255.0f; glm::vec4 rectangleColor(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha); - glDisable(GL_LIGHTING); - glm::vec3 position = getPosition(); glm::vec3 center = getCenter(); glm::vec2 dimensions = getDimensions(); glm::vec2 halfDimensions = dimensions * 0.5f; glm::quat rotation = getRotation(); - float glowLevel = getGlowLevel(); - Glower* glower = NULL; - if (glowLevel > 0.0f) { - glower = new Glower(glowLevel); - } + auto batch = args->_batch; - glPushMatrix(); - glTranslatef(position.x, position.y, position.z); - glm::vec3 axis = glm::axis(rotation); - glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); - glPushMatrix(); - glm::vec3 positionToCenter = center - position; - glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z); - //glScalef(dimensions.x, dimensions.y, 1.0f); + if (batch) { + Transform transform; + transform.setTranslation(position); + transform.setRotation(rotation); - glLineWidth(_lineWidth); + batch->setModelTransform(transform); + if (getIsSolid()) { + glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, 0.0f); + glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, 0.0f); + DependencyManager::get()->renderQuad(*batch, topLeft, bottomRight, rectangleColor); + } else { auto geometryCache = DependencyManager::get(); + if (getIsDashedLine()) { + glm::vec3 point1(-halfDimensions.x, -halfDimensions.y, 0.0f); + glm::vec3 point2(halfDimensions.x, -halfDimensions.y, 0.0f); + glm::vec3 point3(halfDimensions.x, halfDimensions.y, 0.0f); + glm::vec3 point4(-halfDimensions.x, halfDimensions.y, 0.0f); - // for our overlay, is solid means we draw a solid "filled" rectangle otherwise we just draw a border line... - if (getIsSolid()) { - glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, 0.0f); - glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, 0.0f); - DependencyManager::get()->renderQuad(topLeft, bottomRight, rectangleColor); + geometryCache->renderDashedLine(*batch, point1, point2, rectangleColor); + geometryCache->renderDashedLine(*batch, point2, point3, rectangleColor); + geometryCache->renderDashedLine(*batch, point3, point4, rectangleColor); + geometryCache->renderDashedLine(*batch, point4, point1, rectangleColor); } else { - if (getIsDashedLine()) { + if (halfDimensions != _previousHalfDimensions) { + QVector border; + border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f); + border << glm::vec3(halfDimensions.x, -halfDimensions.y, 0.0f); + border << glm::vec3(halfDimensions.x, halfDimensions.y, 0.0f); + border << glm::vec3(-halfDimensions.x, halfDimensions.y, 0.0f); + border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f); + geometryCache->updateVertices(_geometryCacheID, border, rectangleColor); - glm::vec3 point1(-halfDimensions.x, -halfDimensions.y, 0.0f); - glm::vec3 point2(halfDimensions.x, -halfDimensions.y, 0.0f); - glm::vec3 point3(halfDimensions.x, halfDimensions.y, 0.0f); - glm::vec3 point4(-halfDimensions.x, halfDimensions.y, 0.0f); - - geometryCache->renderDashedLine(point1, point2, rectangleColor); - geometryCache->renderDashedLine(point2, point3, rectangleColor); - geometryCache->renderDashedLine(point3, point4, rectangleColor); - geometryCache->renderDashedLine(point4, point1, rectangleColor); - - } else { - - if (halfDimensions != _previousHalfDimensions) { - QVector border; - border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f); - border << glm::vec3(halfDimensions.x, -halfDimensions.y, 0.0f); - border << glm::vec3(halfDimensions.x, halfDimensions.y, 0.0f); - border << glm::vec3(-halfDimensions.x, halfDimensions.y, 0.0f); - border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f); - geometryCache->updateVertices(_geometryCacheID, border, rectangleColor); - - _previousHalfDimensions = halfDimensions; - - } - geometryCache->renderVertices(gpu::LINE_STRIP, _geometryCacheID); + _previousHalfDimensions = halfDimensions; } + geometryCache->renderVertices(*batch, gpu::LINE_STRIP, _geometryCacheID); } - + } + } else { + glDisable(GL_LIGHTING); + + float glowLevel = getGlowLevel(); + Glower* glower = NULL; + if (glowLevel > 0.0f) { + glower = new Glower(glowLevel); + } + + glPushMatrix(); + glTranslatef(position.x, position.y, position.z); + glm::vec3 axis = glm::axis(rotation); + glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); + glPushMatrix(); + glm::vec3 positionToCenter = center - position; + glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z); + //glScalef(dimensions.x, dimensions.y, 1.0f); + + glLineWidth(_lineWidth); + + auto geometryCache = DependencyManager::get(); + + // for our overlay, is solid means we draw a solid "filled" rectangle otherwise we just draw a border line... + if (getIsSolid()) { + glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, 0.0f); + glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, 0.0f); + DependencyManager::get()->renderQuad(topLeft, bottomRight, rectangleColor); + } else { + if (getIsDashedLine()) { + + glm::vec3 point1(-halfDimensions.x, -halfDimensions.y, 0.0f); + glm::vec3 point2(halfDimensions.x, -halfDimensions.y, 0.0f); + glm::vec3 point3(halfDimensions.x, halfDimensions.y, 0.0f); + glm::vec3 point4(-halfDimensions.x, halfDimensions.y, 0.0f); + + geometryCache->renderDashedLine(point1, point2, rectangleColor); + geometryCache->renderDashedLine(point2, point3, rectangleColor); + geometryCache->renderDashedLine(point3, point4, rectangleColor); + geometryCache->renderDashedLine(point4, point1, rectangleColor); + + } else { + + if (halfDimensions != _previousHalfDimensions) { + QVector border; + border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f); + border << glm::vec3(halfDimensions.x, -halfDimensions.y, 0.0f); + border << glm::vec3(halfDimensions.x, halfDimensions.y, 0.0f); + border << glm::vec3(-halfDimensions.x, halfDimensions.y, 0.0f); + border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f); + geometryCache->updateVertices(_geometryCacheID, border, rectangleColor); + + _previousHalfDimensions = halfDimensions; + + } + geometryCache->renderVertices(gpu::LINE_STRIP, _geometryCacheID); + } + } + + glPopMatrix(); glPopMatrix(); - glPopMatrix(); - - if (glower) { - delete glower; + + if (glower) { + delete glower; + } } } From 569971582d3d7f9bffa18803858c8b29a4ef4739 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 16 Jun 2015 18:39:35 -0700 Subject: [PATCH 22/41] more hacking on trying to port atmospheres to the new pipeline --- interface/src/Environment.cpp | 96 +++---------------- libraries/gpu/src/gpu/Batch.h | 4 +- libraries/gpu/src/gpu/GLBackend.cpp | 25 +++++ libraries/gpu/src/gpu/GLBackend.h | 2 + .../model/src/model/SkyFromAtmosphere.slf | 8 +- .../model/src/model/SkyFromAtmosphere.slv | 1 - 6 files changed, 50 insertions(+), 86 deletions(-) diff --git a/interface/src/Environment.cpp b/interface/src/Environment.cpp index 1e9c571a57..66b463949a 100644 --- a/interface/src/Environment.cpp +++ b/interface/src/Environment.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -32,6 +33,8 @@ #include "../../build/libraries/model/SkyFromSpace_frag.h" #include "../../build/libraries/model/SkyFromAtmosphere_vert.h" #include "../../build/libraries/model/SkyFromAtmosphere_frag.h" +#include "../../build/libraries/render-utils/simple_vert.h" +#include "../../build/libraries/render-utils/simple_frag.h" uint qHash(const HifiSockAddr& sockAddr) { if (sockAddr.getAddress().isNull()) { @@ -64,11 +67,11 @@ void Environment::init() { - qDebug() << "line:" << __LINE__; + qDebug() << "here:" << __LINE__; setupAtmosphereProgram(SkyFromSpace_vert, SkyFromSpace_frag, _newSkyFromSpaceProgram, _newSkyFromSpaceUniformLocations); - qDebug() << "line:" << __LINE__; + qDebug() << "here:" << __LINE__; setupAtmosphereProgram(SkyFromAtmosphere_vert, SkyFromAtmosphere_frag, _newSkyFromAtmosphereProgram, _newSkyFromAtmosphereUniformLocations); - qDebug() << "line:" << __LINE__; + qDebug() << "here:" << __LINE__; // start off with a default-constructed environment data @@ -77,7 +80,7 @@ void Environment::init() { _initialized = true; } -void Environment::setupAtmosphereProgram(const char* vertSource, const char* fragSource, gpu::PipelinePointer& pipelineProgram, int* locations) { +void Environment::setupAtmosphereProgram(const char* vertSource, const char* fragSource, gpu::PipelinePointer& pipeline, int* locations) { auto VS = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(vertSource))); auto PS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(fragSource))); @@ -91,7 +94,7 @@ void Environment::setupAtmosphereProgram(const char* vertSource, const char* fra state->setCullMode(gpu::State::CULL_NONE); state->setDepthTest(false); state->setBlendFunction(true,gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); - pipelineProgram = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); + pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); locations[CAMERA_POS_LOCATION] = program->getUniforms().findLocation("v3CameraPos"); locations[LIGHT_POS_LOCATION] = program->getUniforms().findLocation("v3LightPos"); @@ -109,34 +112,6 @@ void Environment::setupAtmosphereProgram(const char* vertSource, const char* fra locations[SCALE_OVER_SCALE_DEPTH_LOCATION] = program->getUniforms().findLocation("fScaleOverScaleDepth"); locations[G_LOCATION] = program->getUniforms().findLocation("g"); locations[G2_LOCATION] = program->getUniforms().findLocation("g2"); - - /* - - program.addShaderFromSourceCode(QGLShader::Vertex, vertSource); - program.addShaderFromSourceCode(QGLShader::Fragment, fragSource); - program.link(); - - program.bind(); - - locations[CAMERA_POS_LOCATION] = program.uniformLocation("v3CameraPos"); - locations[LIGHT_POS_LOCATION] = program.uniformLocation("v3LightPos"); - locations[INV_WAVELENGTH_LOCATION] = program.uniformLocation("v3InvWavelength"); - locations[CAMERA_HEIGHT2_LOCATION] = program.uniformLocation("fCameraHeight2"); - locations[OUTER_RADIUS_LOCATION] = program.uniformLocation("fOuterRadius"); - locations[OUTER_RADIUS2_LOCATION] = program.uniformLocation("fOuterRadius2"); - locations[INNER_RADIUS_LOCATION] = program.uniformLocation("fInnerRadius"); - locations[KR_ESUN_LOCATION] = program.uniformLocation("fKrESun"); - locations[KM_ESUN_LOCATION] = program.uniformLocation("fKmESun"); - locations[KR_4PI_LOCATION] = program.uniformLocation("fKr4PI"); - locations[KM_4PI_LOCATION] = program.uniformLocation("fKm4PI"); - locations[SCALE_LOCATION] = program.uniformLocation("fScale"); - locations[SCALE_DEPTH_LOCATION] = program.uniformLocation("fScaleDepth"); - locations[SCALE_OVER_SCALE_DEPTH_LOCATION] = program.uniformLocation("fScaleOverScaleDepth"); - locations[G_LOCATION] = program.uniformLocation("g"); - locations[G2_LOCATION] = program.uniformLocation("g2"); - - program.release(); - */ } void Environment::resetToDefault() { @@ -305,29 +280,24 @@ ProgramObject* Environment::createSkyProgram(const char* from, int* locations) { } void Environment::renderAtmosphere(gpu::Batch& batch, ViewFrustum& camera, const EnvironmentData& data) { + glm::vec3 center = data.getAtmosphereCenter(); - //glPushMatrix(); - //glTranslatef(center.x, center.y, center.z); - Transform transform; transform.setTranslation(center); - transform.setScale(1.0f); + //transform.setScale(2.0f); batch.setModelTransform(transform); glm::vec3 relativeCameraPos = camera.getPosition() - center; float height = glm::length(relativeCameraPos); // use the appropriate shader depending on whether we're inside or outside - //ProgramObject* program; int* locations; if (height < data.getAtmosphereOuterRadius()) { - //program = &_newSkyFromAtmosphereProgram; batch.setPipeline(_newSkyFromAtmosphereProgram); locations = _newSkyFromAtmosphereUniformLocations; } else { - //program = &_newSkyFromSpaceProgram; batch.setPipeline(_newSkyFromSpaceProgram); locations = _newSkyFromSpaceUniformLocations; } @@ -335,39 +305,13 @@ void Environment::renderAtmosphere(gpu::Batch& batch, ViewFrustum& camera, const // the constants here are from Sean O'Neil's GPU Gems entry // (http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html), GameEngine.cpp - //program->bind(); - /* - program->setUniform(locations[CAMERA_POS_LOCATION], relativeCameraPos); + batch._glUniform3f(locations[CAMERA_POS_LOCATION], relativeCameraPos.x, relativeCameraPos.y, relativeCameraPos.z); glm::vec3 lightDirection = glm::normalize(data.getSunLocation()); - program->setUniform(locations[LIGHT_POS_LOCATION], lightDirection); - program->setUniformValue(locations[INV_WAVELENGTH_LOCATION], - 1 / powf(data.getScatteringWavelengths().r, 4.0f), - 1 / powf(data.getScatteringWavelengths().g, 4.0f), - 1 / powf(data.getScatteringWavelengths().b, 4.0f)); - program->setUniformValue(locations[CAMERA_HEIGHT2_LOCATION], height * height); - program->setUniformValue(locations[OUTER_RADIUS_LOCATION], data.getAtmosphereOuterRadius()); - program->setUniformValue(locations[OUTER_RADIUS2_LOCATION], data.getAtmosphereOuterRadius() * data.getAtmosphereOuterRadius()); - program->setUniformValue(locations[INNER_RADIUS_LOCATION], data.getAtmosphereInnerRadius()); - program->setUniformValue(locations[KR_ESUN_LOCATION], data.getRayleighScattering() * data.getSunBrightness()); - program->setUniformValue(locations[KM_ESUN_LOCATION], data.getMieScattering() * data.getSunBrightness()); - program->setUniformValue(locations[KR_4PI_LOCATION], data.getRayleighScattering() * 4.0f * PI); - program->setUniformValue(locations[KM_4PI_LOCATION], data.getMieScattering() * 4.0f * PI); - program->setUniformValue(locations[SCALE_LOCATION], 1.0f / (data.getAtmosphereOuterRadius() - data.getAtmosphereInnerRadius())); - program->setUniformValue(locations[SCALE_DEPTH_LOCATION], 0.25f); - program->setUniformValue(locations[SCALE_OVER_SCALE_DEPTH_LOCATION], - (1.0f / (data.getAtmosphereOuterRadius() - data.getAtmosphereInnerRadius())) / 0.25f); - program->setUniformValue(locations[G_LOCATION], -0.990f); - program->setUniformValue(locations[G2_LOCATION], -0.990f * -0.990f); - */ - - - batch._glUniform3fv(locations[CAMERA_POS_LOCATION], relativeCameraPos); - glm::vec3 lightDirection = glm::normalize(data.getSunLocation()); - batch._glUniform3fv(locations[LIGHT_POS_LOCATION], lightDirection); + batch._glUniform3f(locations[LIGHT_POS_LOCATION], lightDirection.x, lightDirection.y, lightDirection.z); batch._glUniform3f(locations[INV_WAVELENGTH_LOCATION], - 1 / powf(data.getScatteringWavelengths().r, 4.0f), - 1 / powf(data.getScatteringWavelengths().g, 4.0f), - 1 / powf(data.getScatteringWavelengths().b, 4.0f)); + 1 / powf(data.getScatteringWavelengths().r, 4.0f), + 1 / powf(data.getScatteringWavelengths().g, 4.0f), + 1 / powf(data.getScatteringWavelengths().b, 4.0f)); batch._glUniform1f(locations[CAMERA_HEIGHT2_LOCATION], height * height); batch._glUniform1f(locations[OUTER_RADIUS_LOCATION], data.getAtmosphereOuterRadius()); batch._glUniform1f(locations[OUTER_RADIUS2_LOCATION], data.getAtmosphereOuterRadius() * data.getAtmosphereOuterRadius()); @@ -383,15 +327,5 @@ void Environment::renderAtmosphere(gpu::Batch& batch, ViewFrustum& camera, const batch._glUniform1f(locations[G_LOCATION], -0.990f); batch._glUniform1f(locations[G2_LOCATION], -0.990f * -0.990f); - - //glDepthMask(GL_FALSE); - //glDisable(GL_DEPTH_TEST); - //glDisable(GL_CULL_FACE); - //glEnable(GL_BLEND); DependencyManager::get()->renderSphere(batch,1.0f, 100, 50, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); //Draw a unit sphere - //glDepthMask(GL_TRUE); - - //program->release(); - - //glPopMatrix(); } diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 77c9308af5..bbd2121c54 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -150,7 +150,8 @@ public: void _glUseProgram(GLuint program); void _glUniform1f(GLint location, GLfloat v0); void _glUniform2f(GLint location, GLfloat v0, GLfloat v1); - void _glUniform3f(GLint location, GLfloat v0, GLfloat v1); + void _glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); + void _glUniform3fv(GLint location, GLsizei count, const GLfloat* value); void _glUniform4fv(GLint location, GLsizei count, const GLfloat* value); void _glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); @@ -212,6 +213,7 @@ public: COMMAND_glUniform1f, COMMAND_glUniform2f, COMMAND_glUniform3f, + COMMAND_glUniform3fv, COMMAND_glUniform4fv, COMMAND_glUniformMatrix4fv, diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 7ba344dfbd..20a6b60901 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -62,6 +62,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = (&::gpu::GLBackend::do_glUniform1f), (&::gpu::GLBackend::do_glUniform2f), (&::gpu::GLBackend::do_glUniform3f), + (&::gpu::GLBackend::do_glUniform3fv), (&::gpu::GLBackend::do_glUniform4fv), (&::gpu::GLBackend::do_glUniformMatrix4fv), @@ -502,6 +503,30 @@ void GLBackend::do_glUniform3f(Batch& batch, uint32 paramOffset) { (void) CHECK_GL_ERROR(); } +void Batch::_glUniform3fv(GLint location, GLsizei count, const GLfloat* value) { + ADD_COMMAND_GL(glUniform3fv); + + const int VEC3_SIZE = 3 * sizeof(float); + _params.push_back(cacheData(count * VEC3_SIZE, value)); + _params.push_back(count); + _params.push_back(location); + + DO_IT_NOW(_glUniform3fv, 3); +} +void GLBackend::do_glUniform3fv(Batch& batch, uint32 paramOffset) { + if (_pipeline._program == 0) { + // We should call updatePipeline() to bind the program but we are not doing that + // because these uniform setters are deprecated and we don;t want to create side effect + return; + } + glUniform3fv( + batch._params[paramOffset + 2]._int, + batch._params[paramOffset + 1]._uint, + (const GLfloat*)batch.editData(batch._params[paramOffset + 0]._uint)); + + (void) CHECK_GL_ERROR(); +} + void Batch::_glUniform4fv(GLint location, GLsizei count, const GLfloat* value) { ADD_COMMAND_GL(glUniform4fv); diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index e7a5e62df8..c87394869c 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -379,6 +379,8 @@ protected: void do_glUseProgram(Batch& batch, uint32 paramOffset); void do_glUniform1f(Batch& batch, uint32 paramOffset); void do_glUniform2f(Batch& batch, uint32 paramOffset); + void do_glUniform3f(Batch& batch, uint32 paramOffset); + void do_glUniform3fv(Batch& batch, uint32 paramOffset); void do_glUniform4fv(Batch& batch, uint32 paramOffset); void do_glUniformMatrix4fv(Batch& batch, uint32 paramOffset); diff --git a/libraries/model/src/model/SkyFromAtmosphere.slf b/libraries/model/src/model/SkyFromAtmosphere.slf index b82cddc282..a9e2bc6156 100755 --- a/libraries/model/src/model/SkyFromAtmosphere.slf +++ b/libraries/model/src/model/SkyFromAtmosphere.slf @@ -104,7 +104,9 @@ void main (void) float fCos = dot(v3LightPos, v3Direction) / length(v3Direction); float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos*fCos) / pow(1.0 + g2 - 2.0*g*fCos, 1.5); - gl_FragColor.rgb = frontColor.rgb + fMiePhase * secondaryFrontColor.rgb; - gl_FragColor.a = gl_FragColor.b; - gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(1.0/2.2)); + + vec3 finalColor = frontColor.rgb + fMiePhase * secondaryFrontColor.rgb; + gl_FragData[0].rgb = finalColor; + gl_FragData[0].a = finalColor.b; + gl_FragData[0].rgb = pow(finalColor.rgb, vec3(1.0/2.2)); } diff --git a/libraries/model/src/model/SkyFromAtmosphere.slv b/libraries/model/src/model/SkyFromAtmosphere.slv index c19cb34c6a..99c782adf1 100755 --- a/libraries/model/src/model/SkyFromAtmosphere.slv +++ b/libraries/model/src/model/SkyFromAtmosphere.slv @@ -55,7 +55,6 @@ const float fSamples = 2.0; varying vec3 myPosition; - void main(void) { // Get the ray from the camera to the vertex, and its length (which is the far point of the ray passing through the atmosphere) From 006899d73ff5afec4ca538a87bed39ff084997ce Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 16 Jun 2015 22:23:14 -0700 Subject: [PATCH 23/41] more hacking almost working --- interface/src/Application.cpp | 9 +++++---- interface/src/Environment.cpp | 23 ++++++++++++++++++++--- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5726dcacd5..efe7df4240 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3330,10 +3330,11 @@ namespace render { PerformanceTimer perfTimer("atmosphere"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... atmosphere..."); - //gpu::Batch batch; - background->_environment->renderAtmospheres(batch, *(args->_viewFrustum)); - //gpu::GLBackend::renderBatch(batch, true); - //glUseProgram(0); + gpu::Batch batch; + //DependencyManager::get()->renderSolidSphere(batch,0.5f, 100, 50, glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)); //Draw a unit sphere + background->_environment->renderAtmospheres(batch, *(args->_viewFrustum)); + gpu::GLBackend::renderBatch(batch, true); + glUseProgram(0); } diff --git a/interface/src/Environment.cpp b/interface/src/Environment.cpp index 66b463949a..b80e4795d4 100644 --- a/interface/src/Environment.cpp +++ b/interface/src/Environment.cpp @@ -36,6 +36,9 @@ #include "../../build/libraries/render-utils/simple_vert.h" #include "../../build/libraries/render-utils/simple_frag.h" +#include "../../build/libraries/render-utils/other_simple_vert.h" +#include "../../build/libraries/render-utils/other_simple_frag.h" + uint qHash(const HifiSockAddr& sockAddr) { if (sockAddr.getAddress().isNull()) { return 0; // shouldn't happen, but if it does, zero is a perfectly valid hash @@ -69,8 +72,10 @@ void Environment::init() { qDebug() << "here:" << __LINE__; setupAtmosphereProgram(SkyFromSpace_vert, SkyFromSpace_frag, _newSkyFromSpaceProgram, _newSkyFromSpaceUniformLocations); + //setupAtmosphereProgram(other_simple_vert, other_simple_frag, _newSkyFromSpaceProgram, _newSkyFromSpaceUniformLocations); qDebug() << "here:" << __LINE__; setupAtmosphereProgram(SkyFromAtmosphere_vert, SkyFromAtmosphere_frag, _newSkyFromAtmosphereProgram, _newSkyFromAtmosphereUniformLocations); + //setupAtmosphereProgram(other_simple_vert, other_simple_frag, _newSkyFromAtmosphereProgram, _newSkyFromAtmosphereUniformLocations); qDebug() << "here:" << __LINE__; @@ -91,9 +96,19 @@ void Environment::setupAtmosphereProgram(const char* vertSource, const char* fra gpu::Shader::makeProgram(*program, slotBindings); gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + + /* state->setCullMode(gpu::State::CULL_NONE); state->setDepthTest(false); state->setBlendFunction(true,gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); + */ + + state->setCullMode(gpu::State::CULL_NONE); + state->setDepthTest(false); + state->setBlendFunction(false, + gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, + gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + pipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); locations[CAMERA_POS_LOCATION] = program->getUniforms().findLocation("v3CameraPos"); @@ -280,12 +295,13 @@ ProgramObject* Environment::createSkyProgram(const char* from, int* locations) { } void Environment::renderAtmosphere(gpu::Batch& batch, ViewFrustum& camera, const EnvironmentData& data) { - + glm::vec3 center = data.getAtmosphereCenter(); Transform transform; transform.setTranslation(center); //transform.setScale(2.0f); + //transform.setTranslation(glm::vec3(0,0,0)); batch.setModelTransform(transform); glm::vec3 relativeCameraPos = camera.getPosition() - center; @@ -304,7 +320,8 @@ void Environment::renderAtmosphere(gpu::Batch& batch, ViewFrustum& camera, const // the constants here are from Sean O'Neil's GPU Gems entry // (http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html), GameEngine.cpp - + + batch._glUniform3f(locations[CAMERA_POS_LOCATION], relativeCameraPos.x, relativeCameraPos.y, relativeCameraPos.z); glm::vec3 lightDirection = glm::normalize(data.getSunLocation()); batch._glUniform3f(locations[LIGHT_POS_LOCATION], lightDirection.x, lightDirection.y, lightDirection.z); @@ -327,5 +344,5 @@ void Environment::renderAtmosphere(gpu::Batch& batch, ViewFrustum& camera, const batch._glUniform1f(locations[G_LOCATION], -0.990f); batch._glUniform1f(locations[G2_LOCATION], -0.990f * -0.990f); - DependencyManager::get()->renderSphere(batch,1.0f, 100, 50, glm::vec4(1.0f, 1.0f, 1.0f, 1.0f)); //Draw a unit sphere + DependencyManager::get()->renderSphere(batch,1.0f, 100, 50, glm::vec4(1.0f, 0.0f, 0.0f, 0.5f)); //Draw a unit sphere } From 5c547037f26ab6d51c2c55c9c484fddfd6a85a7e Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 17 Jun 2015 15:54:20 +0200 Subject: [PATCH 24/41] Migrating the overaly 3d rendering in their own job and their own shader --- .../src/ui/overlays/BillboardOverlay.cpp | 2 + interface/src/ui/overlays/Cube3DOverlay.cpp | 3 +- .../render-utils/src/RenderDeferredTask.cpp | 73 ++++++++++++++++++- .../render-utils/src/RenderDeferredTask.h | 11 +++ libraries/render-utils/src/overlay3D.slf | 28 +++++++ libraries/render-utils/src/overlay3D.slv | 40 ++++++++++ libraries/shared/src/RenderArgs.h | 5 ++ 7 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 libraries/render-utils/src/overlay3D.slf create mode 100644 libraries/render-utils/src/overlay3D.slv diff --git a/interface/src/ui/overlays/BillboardOverlay.cpp b/interface/src/ui/overlays/BillboardOverlay.cpp index ed0ddd8dc7..e7b043f44f 100644 --- a/interface/src/ui/overlays/BillboardOverlay.cpp +++ b/interface/src/ui/overlays/BillboardOverlay.cpp @@ -99,6 +99,8 @@ void BillboardOverlay::render(RenderArgs* args) { DependencyManager::get()->renderQuad(*batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha)); + + batch->setUniformTexture(0, args->_whiteTexture); // restore default white color after me } else { glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.5f); diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index 73406c07a0..d048b1a05a 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -69,8 +69,9 @@ void Cube3DOverlay::render(RenderArgs* args) { transform.setScale(dimensions); batch->setModelTransform(transform); + DependencyManager::get()->renderSolidCube(*batch, 1.0f, cubeColor); - DependencyManager::get()->renderSolidCube(*batch, 1.0f, cubeColor); + //DependencyManager::get()->renderSolidCube(*batch, 1.0f, cubeColor); } else { if (getIsDashedLine()) { diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index d9dda279e0..ce3c6769ca 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -15,9 +15,12 @@ #include "DeferredLightingEffect.h" #include "ViewFrustum.h" #include "RenderArgs.h" +#include "TextureCache.h" #include +#include "overlay3D_vert.h" +#include "overlay3D_frag.h" using namespace render; @@ -50,7 +53,7 @@ RenderDeferredTask::RenderDeferredTask() : Task() { _jobs.push_back(Job(RenderDeferred())); _jobs.push_back(Job(ResolveDeferred())); _jobs.push_back(Job(DrawTransparentDeferred())); - _jobs.push_back(Job(DrawPostLayered())); + _jobs.push_back(Job(DrawOverlay3D())); _jobs.push_back(Job(ResetGLState())); } @@ -225,10 +228,76 @@ template <> void render::jobRun(const DrawTransparentDeferred& job, const SceneC renderItems(sceneContext, renderContext, renderedItems, renderContext->_maxDrawnTransparentItems); + // Before rendering the batch make sure we re in sync with gl state + args->_context->syncCache(); args->_context->render((*args->_batch)); args->_batch = nullptr; // reset blend function to standard... - glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); + // glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE); } } + +const gpu::PipelinePointer& DrawOverlay3D::getOpaquePipeline() const { + if (!_opaquePipeline) { + auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(overlay3D_vert))); + auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(overlay3D_frag))); + + auto program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps)); + + auto state = gpu::StatePointer(new gpu::State()); + state->setDepthTest(true, true, gpu::LESS_EQUAL); + + _opaquePipeline.reset(gpu::Pipeline::create(program, state)); + } + return _opaquePipeline; +} + +template <> void render::jobRun(const DrawOverlay3D& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { + PerformanceTimer perfTimer("DrawOverlay3D"); + assert(renderContext->args); + assert(renderContext->args->_viewFrustum); + + // render backgrounds + auto& scene = sceneContext->_scene; + auto& items = scene->getMasterBucket().at(ItemFilter::Builder::opaqueShape().withLayered()); + + + ItemIDsBounds inItems; + inItems.reserve(items.size()); + for (auto id : items) { + auto& item = scene->getItem(id); + if (item.getKey().isVisible() && (item.getLayer() == 1)) { + inItems.emplace_back(id); + } + } + + RenderArgs* args = renderContext->args; + gpu::Batch batch; + args->_batch = &batch; + args->_whiteTexture = DependencyManager::get()->getWhiteTexture(); + + + glm::mat4 projMat; + Transform viewMat; + args->_viewFrustum->evalProjectionMatrix(projMat); + args->_viewFrustum->evalViewTransform(viewMat); + if (args->_renderMode == RenderArgs::MIRROR_RENDER_MODE) { + viewMat.postScale(glm::vec3(-1.0f, 1.0f, 1.0f)); + } + batch.setProjectionTransform(projMat); + batch.setViewTransform(viewMat); + batch.setPipeline(job.getOpaquePipeline()); + batch.setUniformTexture(0, args->_whiteTexture); + + if (!inItems.empty()) { + batch.clearFramebuffer(gpu::Framebuffer::BUFFER_DEPTH, glm::vec4(), 1.f, 0); + renderItems(sceneContext, renderContext, inItems); + } + + // Before rendering the batch make sure we re in sync with gl state + args->_context->syncCache(); + args->_context->render((*args->_batch)); + args->_batch = nullptr; + args->_whiteTexture.reset(); +} diff --git a/libraries/render-utils/src/RenderDeferredTask.h b/libraries/render-utils/src/RenderDeferredTask.h index e2cac53c0d..3b0ffdfc9b 100755 --- a/libraries/render-utils/src/RenderDeferredTask.h +++ b/libraries/render-utils/src/RenderDeferredTask.h @@ -14,6 +14,8 @@ #include "render/DrawTask.h" +#include "gpu/Pipeline.h" + class PrepareDeferred { public: }; @@ -50,6 +52,15 @@ namespace render { template <> void jobRun(const DrawTransparentDeferred& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); } +class DrawOverlay3D { + mutable gpu::PipelinePointer _opaquePipeline; //lazy evaluation hence mutable +public: + const gpu::PipelinePointer& getOpaquePipeline() const; +}; +namespace render { +template <> void jobRun(const DrawOverlay3D& job, const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); +} + class RenderDeferredTask : public render::Task { public: diff --git a/libraries/render-utils/src/overlay3D.slf b/libraries/render-utils/src/overlay3D.slf new file mode 100644 index 0000000000..8686066dd8 --- /dev/null +++ b/libraries/render-utils/src/overlay3D.slf @@ -0,0 +1,28 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// model.frag +// fragment shader +// +// Created by Sam Gateau on 6/16/15. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +uniform sampler2D diffuseMap; + +varying vec2 varTexcoord; + +varying vec3 varEyeNormal; + +varying vec4 varColor; + + +void main(void) { + vec4 diffuse = texture2D(diffuseMap, varTexcoord.st); + + + gl_FragColor = vec4(varColor * diffuse); +} diff --git a/libraries/render-utils/src/overlay3D.slv b/libraries/render-utils/src/overlay3D.slv new file mode 100644 index 0000000000..b272b2bfd0 --- /dev/null +++ b/libraries/render-utils/src/overlay3D.slv @@ -0,0 +1,40 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// overlay3D.slv +// +// Created by Sam Gateau on 6/16/15. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +<@include gpu/Transform.slh@> + +<$declareStandardTransform()$> + +attribute vec2 attribTexcoord; + +varying vec2 varTexcoord; + +// interpolated eye position +varying vec4 varEyePosition; + +// the interpolated normal +varying vec3 varEyeNormal; + +varying vec4 varColor; + +void main(void) { + varTexcoord = attribTexcoord; + + // pass along the color + varColor = gl_Color; + + // standard transform + TransformCamera cam = getTransformCamera(); + TransformObject obj = getTransformObject(); + <$transformModelToEyeAndClipPos(cam, obj, gl_Vertex, varEyePosition, gl_Position)$> + <$transformModelToEyeDir(cam, obj, gl_Normal, varEyeNormal.xyz)$> +} diff --git a/libraries/shared/src/RenderArgs.h b/libraries/shared/src/RenderArgs.h index 84b3a202b4..9673623b13 100644 --- a/libraries/shared/src/RenderArgs.h +++ b/libraries/shared/src/RenderArgs.h @@ -13,6 +13,8 @@ #define hifi_RenderArgs_h #include +#include + class AABox; class OctreeRenderer; @@ -20,6 +22,7 @@ class ViewFrustum; namespace gpu { class Batch; class Context; +class Texture; } class RenderDetails { @@ -109,6 +112,8 @@ public: gpu::Batch* _batch = nullptr; ShoudRenderFunctor _shouldRender; + std::shared_ptr _whiteTexture; + RenderDetails _details; float _alphaThreshold = 0.5f; From d703748ec3ad34ad87062bcbe7a8f1bb5792f0ef Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 17 Jun 2015 16:44:02 +0200 Subject: [PATCH 25/41] trying to solve the rendering of overlay3d --- interface/src/ui/overlays/OverlaysPayload.cpp | 8 +++++--- libraries/render-utils/src/overlay3D.slf | 6 ++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/interface/src/ui/overlays/OverlaysPayload.cpp b/interface/src/ui/overlays/OverlaysPayload.cpp index d5e4b34f6b..bcfba67313 100644 --- a/interface/src/ui/overlays/OverlaysPayload.cpp +++ b/interface/src/ui/overlays/OverlaysPayload.cpp @@ -66,8 +66,8 @@ namespace render { } template <> void payloadRender(const Overlay::Pointer& overlay, RenderArgs* args) { if (args) { - glPushMatrix(); if (overlay->getAnchor() == Overlay::MY_AVATAR) { + glPushMatrix(); MyAvatar* avatar = DependencyManager::get()->getMyAvatar(); glm::quat myAvatarRotation = avatar->getOrientation(); glm::vec3 myAvatarPosition = avatar->getPosition(); @@ -78,9 +78,11 @@ namespace render { glTranslatef(myAvatarPosition.x, myAvatarPosition.y, myAvatarPosition.z); glRotatef(angle, axis.x, axis.y, axis.z); glScalef(myAvatarScale, myAvatarScale, myAvatarScale); + overlay->render(args); + glPopMatrix(); + } else { + overlay->render(args); } - overlay->render(args); - glPopMatrix(); } } } diff --git a/libraries/render-utils/src/overlay3D.slf b/libraries/render-utils/src/overlay3D.slf index 8686066dd8..e38086ebb5 100644 --- a/libraries/render-utils/src/overlay3D.slf +++ b/libraries/render-utils/src/overlay3D.slf @@ -22,7 +22,9 @@ varying vec4 varColor; void main(void) { vec4 diffuse = texture2D(diffuseMap, varTexcoord.st); - + if (diffuse.a < 0.5) { + discard; + } - gl_FragColor = vec4(varColor * diffuse); + gl_FragColor = vec4(varColor.rgb * (1 - diffuse.a) + diffuse.a * diffuse.rgb, 1.0); } From febc3333cd45839381d37733298e58c9aaa5b07b Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 17 Jun 2015 16:50:35 +0200 Subject: [PATCH 26/41] Solving the rendering of textured overlay3d --- libraries/gpu/src/gpu/GLBackendShader.cpp | 6 +++++- libraries/render-utils/src/overlay3D.slv | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackendShader.cpp b/libraries/gpu/src/gpu/GLBackendShader.cpp index e0ea2f2d98..45adbcdb3c 100755 --- a/libraries/gpu/src/gpu/GLBackendShader.cpp +++ b/libraries/gpu/src/gpu/GLBackendShader.cpp @@ -61,7 +61,11 @@ void makeBindings(GLBackend::GLShader* shader) { if (loc >= 0) { glBindAttribLocation(glprogram, gpu::Stream::TEXCOORD, "texcoord"); } - + loc = glGetAttribLocation(glprogram, "attribTexcoord"); + if (loc >= 0) { + glBindAttribLocation(glprogram, gpu::Stream::TEXCOORD, "attribTexcoord"); + } + loc = glGetAttribLocation(glprogram, "tangent"); if (loc >= 0) { glBindAttribLocation(glprogram, gpu::Stream::TANGENT, "tangent"); diff --git a/libraries/render-utils/src/overlay3D.slv b/libraries/render-utils/src/overlay3D.slv index b272b2bfd0..cdb11c1d08 100644 --- a/libraries/render-utils/src/overlay3D.slv +++ b/libraries/render-utils/src/overlay3D.slv @@ -14,7 +14,7 @@ <$declareStandardTransform()$> -attribute vec2 attribTexcoord; +//attribute vec2 texcoord; varying vec2 varTexcoord; @@ -27,7 +27,7 @@ varying vec3 varEyeNormal; varying vec4 varColor; void main(void) { - varTexcoord = attribTexcoord; + varTexcoord = gl_MultiTexCoord0.xy; // pass along the color varColor = gl_Color; From 3176c8e93c1e82aae16b22ae986e16bf6588a9ed Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 17 Jun 2015 17:09:33 +0200 Subject: [PATCH 27/41] polish before PR --- interface/src/ui/overlays/Cube3DOverlay.cpp | 2 -- libraries/render-utils/src/overlay3D.slf | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index d048b1a05a..37b30a5bcb 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -70,8 +70,6 @@ void Cube3DOverlay::render(RenderArgs* args) { transform.setScale(dimensions); batch->setModelTransform(transform); DependencyManager::get()->renderSolidCube(*batch, 1.0f, cubeColor); - - //DependencyManager::get()->renderSolidCube(*batch, 1.0f, cubeColor); } else { if (getIsDashedLine()) { diff --git a/libraries/render-utils/src/overlay3D.slf b/libraries/render-utils/src/overlay3D.slf index e38086ebb5..69ea8c0e76 100644 --- a/libraries/render-utils/src/overlay3D.slf +++ b/libraries/render-utils/src/overlay3D.slf @@ -25,6 +25,5 @@ void main(void) { if (diffuse.a < 0.5) { discard; } - - gl_FragColor = vec4(varColor.rgb * (1 - diffuse.a) + diffuse.a * diffuse.rgb, 1.0); + gl_FragColor = vec4(varColor * diffuse); } From 2356a071dd4298216d1b16e49b83e36054d44ac0 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 17 Jun 2015 08:48:04 -0700 Subject: [PATCH 28/41] some cleanup --- interface/src/Environment.cpp | 71 ++++------------------------------- interface/src/Environment.h | 15 ++------ 2 files changed, 11 insertions(+), 75 deletions(-) diff --git a/interface/src/Environment.cpp b/interface/src/Environment.cpp index b80e4795d4..b333d648ef 100644 --- a/interface/src/Environment.cpp +++ b/interface/src/Environment.cpp @@ -33,11 +33,6 @@ #include "../../build/libraries/model/SkyFromSpace_frag.h" #include "../../build/libraries/model/SkyFromAtmosphere_vert.h" #include "../../build/libraries/model/SkyFromAtmosphere_frag.h" -#include "../../build/libraries/render-utils/simple_vert.h" -#include "../../build/libraries/render-utils/simple_frag.h" - -#include "../../build/libraries/render-utils/other_simple_vert.h" -#include "../../build/libraries/render-utils/other_simple_frag.h" uint qHash(const HifiSockAddr& sockAddr) { if (sockAddr.getAddress().isNull()) { @@ -53,10 +48,6 @@ Environment::Environment() } Environment::~Environment() { - if (_initialized) { - delete _skyFromAtmosphereProgram; - delete _skyFromSpaceProgram; - } } void Environment::init() { @@ -65,19 +56,8 @@ void Environment::init() { return; } - _skyFromAtmosphereProgram = createSkyProgram("Atmosphere", _skyFromAtmosphereUniformLocations); - _skyFromSpaceProgram = createSkyProgram("Space", _skyFromSpaceUniformLocations); - - - - qDebug() << "here:" << __LINE__; - setupAtmosphereProgram(SkyFromSpace_vert, SkyFromSpace_frag, _newSkyFromSpaceProgram, _newSkyFromSpaceUniformLocations); - //setupAtmosphereProgram(other_simple_vert, other_simple_frag, _newSkyFromSpaceProgram, _newSkyFromSpaceUniformLocations); - qDebug() << "here:" << __LINE__; - setupAtmosphereProgram(SkyFromAtmosphere_vert, SkyFromAtmosphere_frag, _newSkyFromAtmosphereProgram, _newSkyFromAtmosphereUniformLocations); - //setupAtmosphereProgram(other_simple_vert, other_simple_frag, _newSkyFromAtmosphereProgram, _newSkyFromAtmosphereUniformLocations); - qDebug() << "here:" << __LINE__; - + setupAtmosphereProgram(SkyFromSpace_vert, SkyFromSpace_frag, _skyFromSpaceProgram, _skyFromSpaceUniformLocations); + setupAtmosphereProgram(SkyFromAtmosphere_vert, SkyFromAtmosphere_frag, _skyFromAtmosphereProgram, _skyFromAtmosphereUniformLocations); // start off with a default-constructed environment data _data[HifiSockAddr()][0]; @@ -97,15 +77,9 @@ void Environment::setupAtmosphereProgram(const char* vertSource, const char* fra gpu::StatePointer state = gpu::StatePointer(new gpu::State()); - /* state->setCullMode(gpu::State::CULL_NONE); state->setDepthTest(false); - state->setBlendFunction(true,gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); - */ - - state->setCullMode(gpu::State::CULL_NONE); - state->setDepthTest(false); - state->setBlendFunction(false, + state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); @@ -267,41 +241,12 @@ int Environment::parseData(const HifiSockAddr& senderAddress, const QByteArray& return bytesRead; } -ProgramObject* Environment::createSkyProgram(const char* from, int* locations) { - ProgramObject* program = new ProgramObject(); - QByteArray prefix = QString(PathUtils::resourcesPath() + "/shaders/SkyFrom" + from).toUtf8(); - program->addShaderFromSourceFile(QGLShader::Vertex, prefix + ".vert"); - program->addShaderFromSourceFile(QGLShader::Fragment, prefix + ".frag"); - program->link(); - - locations[CAMERA_POS_LOCATION] = program->uniformLocation("v3CameraPos"); - locations[LIGHT_POS_LOCATION] = program->uniformLocation("v3LightPos"); - locations[INV_WAVELENGTH_LOCATION] = program->uniformLocation("v3InvWavelength"); - locations[CAMERA_HEIGHT2_LOCATION] = program->uniformLocation("fCameraHeight2"); - locations[OUTER_RADIUS_LOCATION] = program->uniformLocation("fOuterRadius"); - locations[OUTER_RADIUS2_LOCATION] = program->uniformLocation("fOuterRadius2"); - locations[INNER_RADIUS_LOCATION] = program->uniformLocation("fInnerRadius"); - locations[KR_ESUN_LOCATION] = program->uniformLocation("fKrESun"); - locations[KM_ESUN_LOCATION] = program->uniformLocation("fKmESun"); - locations[KR_4PI_LOCATION] = program->uniformLocation("fKr4PI"); - locations[KM_4PI_LOCATION] = program->uniformLocation("fKm4PI"); - locations[SCALE_LOCATION] = program->uniformLocation("fScale"); - locations[SCALE_DEPTH_LOCATION] = program->uniformLocation("fScaleDepth"); - locations[SCALE_OVER_SCALE_DEPTH_LOCATION] = program->uniformLocation("fScaleOverScaleDepth"); - locations[G_LOCATION] = program->uniformLocation("g"); - locations[G2_LOCATION] = program->uniformLocation("g2"); - - return program; -} - void Environment::renderAtmosphere(gpu::Batch& batch, ViewFrustum& camera, const EnvironmentData& data) { glm::vec3 center = data.getAtmosphereCenter(); Transform transform; transform.setTranslation(center); - //transform.setScale(2.0f); - //transform.setTranslation(glm::vec3(0,0,0)); batch.setModelTransform(transform); glm::vec3 relativeCameraPos = camera.getPosition() - center; @@ -310,18 +255,16 @@ void Environment::renderAtmosphere(gpu::Batch& batch, ViewFrustum& camera, const // use the appropriate shader depending on whether we're inside or outside int* locations; if (height < data.getAtmosphereOuterRadius()) { - batch.setPipeline(_newSkyFromAtmosphereProgram); - locations = _newSkyFromAtmosphereUniformLocations; + batch.setPipeline(_skyFromAtmosphereProgram); + locations = _skyFromAtmosphereUniformLocations; } else { - batch.setPipeline(_newSkyFromSpaceProgram); - locations = _newSkyFromSpaceUniformLocations; + batch.setPipeline(_skyFromSpaceProgram); + locations = _skyFromSpaceUniformLocations; } // the constants here are from Sean O'Neil's GPU Gems entry // (http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter16.html), GameEngine.cpp - - batch._glUniform3f(locations[CAMERA_POS_LOCATION], relativeCameraPos.x, relativeCameraPos.y, relativeCameraPos.z); glm::vec3 lightDirection = glm::normalize(data.getSunLocation()); batch._glUniform3f(locations[LIGHT_POS_LOCATION], lightDirection.x, lightDirection.y, lightDirection.z); diff --git a/interface/src/Environment.h b/interface/src/Environment.h index 9048678230..547f46c9fe 100644 --- a/interface/src/Environment.h +++ b/interface/src/Environment.h @@ -47,13 +47,9 @@ private: bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration); // NOTE: Deprecated - ProgramObject* createSkyProgram(const char* from, int* locations); - void renderAtmosphere(gpu::Batch& batch, ViewFrustum& camera, const EnvironmentData& data); bool _initialized; - ProgramObject* _skyFromAtmosphereProgram; - ProgramObject* _skyFromSpaceProgram; enum { CAMERA_POS_LOCATION, @@ -75,16 +71,13 @@ private: LOCATION_COUNT }; - int _skyFromAtmosphereUniformLocations[LOCATION_COUNT]; - int _skyFromSpaceUniformLocations[LOCATION_COUNT]; - void setupAtmosphereProgram(const char* vertSource, const char* fragSource, gpu::PipelinePointer& pipelineProgram, int* locations); - gpu::PipelinePointer _newSkyFromAtmosphereProgram; - gpu::PipelinePointer _newSkyFromSpaceProgram; - int _newSkyFromAtmosphereUniformLocations[LOCATION_COUNT]; - int _newSkyFromSpaceUniformLocations[LOCATION_COUNT]; + gpu::PipelinePointer _skyFromAtmosphereProgram; + gpu::PipelinePointer _skyFromSpaceProgram; + int _skyFromAtmosphereUniformLocations[LOCATION_COUNT]; + int _skyFromSpaceUniformLocations[LOCATION_COUNT]; typedef QHash ServerData; From b5731135ddeb2c4feae495d00f4f4aff399f8f3c Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 17 Jun 2015 09:08:41 -0700 Subject: [PATCH 29/41] cleanup --- interface/src/Application.cpp | 8 +++++--- interface/src/Environment.cpp | 10 +++------- interface/src/Environment.h | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index efe7df4240..1ead8fe4f8 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3330,11 +3330,13 @@ namespace render { PerformanceTimer perfTimer("atmosphere"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide() ... atmosphere..."); - gpu::Batch batch; - //DependencyManager::get()->renderSolidSphere(batch,0.5f, 100, 50, glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)); //Draw a unit sphere + background->_environment->renderAtmospheres(batch, *(args->_viewFrustum)); + + // FIX ME - If I don't call this renderBatch() here, then the atmosphere doesn't render, but it + // seems like these payloadRender() methods shouldn't be doing this. We need to investigate why + // the engine isn't rendering our batch gpu::GLBackend::renderBatch(batch, true); - glUseProgram(0); } diff --git a/interface/src/Environment.cpp b/interface/src/Environment.cpp index b333d648ef..09dd8f792e 100644 --- a/interface/src/Environment.cpp +++ b/interface/src/Environment.cpp @@ -15,18 +15,15 @@ #include #include -#include +#include #include +#include +#include #include #include #include #include -#include "Application.h" -#include "Camera.h" -#include "world.h" -#include "InterfaceLogging.h" - #include "Environment.h" #include "../../build/libraries/model/SkyFromSpace_vert.h" @@ -52,7 +49,6 @@ Environment::~Environment() { void Environment::init() { if (_initialized) { - qCDebug(interfaceapp, "[ERROR] Environment is already initialized."); return; } diff --git a/interface/src/Environment.h b/interface/src/Environment.h index 547f46c9fe..fe0c564493 100644 --- a/interface/src/Environment.h +++ b/interface/src/Environment.h @@ -18,7 +18,7 @@ #include #include -#include +//#include #include "EnvironmentData.h" From ea98581d22c20cbba734941fc69b0477afed39e8 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 17 Jun 2015 09:18:00 -0700 Subject: [PATCH 30/41] reorganize files to cleanup headers --- libraries/model/CMakeLists.txt | 3 ++- .../render-utils}/src/Environment.cpp | 13 +++++-------- .../render-utils}/src/Environment.h | 0 .../src}/SkyFromAtmosphere.slf | 0 .../src}/SkyFromAtmosphere.slv | 0 .../src/model => render-utils/src}/SkyFromSpace.slf | 0 .../src/model => render-utils/src}/SkyFromSpace.slv | 0 7 files changed, 7 insertions(+), 9 deletions(-) rename {interface => libraries/render-utils}/src/Environment.cpp (97%) rename {interface => libraries/render-utils}/src/Environment.h (100%) rename libraries/{model/src/model => render-utils/src}/SkyFromAtmosphere.slf (100%) rename libraries/{model/src/model => render-utils/src}/SkyFromAtmosphere.slv (100%) rename libraries/{model/src/model => render-utils/src}/SkyFromSpace.slf (100%) rename libraries/{model/src/model => render-utils/src}/SkyFromSpace.slv (100%) diff --git a/libraries/model/CMakeLists.txt b/libraries/model/CMakeLists.txt index 278c40c435..7456716946 100755 --- a/libraries/model/CMakeLists.txt +++ b/libraries/model/CMakeLists.txt @@ -1,5 +1,6 @@ set(TARGET_NAME model) - + + AUTOSCRIBE_SHADER_LIB(gpu) # use setup_hifi_library macro to setup our project and link appropriate Qt modules diff --git a/interface/src/Environment.cpp b/libraries/render-utils/src/Environment.cpp similarity index 97% rename from interface/src/Environment.cpp rename to libraries/render-utils/src/Environment.cpp index 09dd8f792e..411beca0ae 100644 --- a/interface/src/Environment.cpp +++ b/libraries/render-utils/src/Environment.cpp @@ -9,27 +9,24 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include "InterfaceConfig.h" - #include #include #include -#include +#include "GeometryCache.h" #include #include #include #include #include -#include #include #include "Environment.h" -#include "../../build/libraries/model/SkyFromSpace_vert.h" -#include "../../build/libraries/model/SkyFromSpace_frag.h" -#include "../../build/libraries/model/SkyFromAtmosphere_vert.h" -#include "../../build/libraries/model/SkyFromAtmosphere_frag.h" +#include "SkyFromSpace_vert.h" +#include "SkyFromSpace_frag.h" +#include "SkyFromAtmosphere_vert.h" +#include "SkyFromAtmosphere_frag.h" uint qHash(const HifiSockAddr& sockAddr) { if (sockAddr.getAddress().isNull()) { diff --git a/interface/src/Environment.h b/libraries/render-utils/src/Environment.h similarity index 100% rename from interface/src/Environment.h rename to libraries/render-utils/src/Environment.h diff --git a/libraries/model/src/model/SkyFromAtmosphere.slf b/libraries/render-utils/src/SkyFromAtmosphere.slf similarity index 100% rename from libraries/model/src/model/SkyFromAtmosphere.slf rename to libraries/render-utils/src/SkyFromAtmosphere.slf diff --git a/libraries/model/src/model/SkyFromAtmosphere.slv b/libraries/render-utils/src/SkyFromAtmosphere.slv similarity index 100% rename from libraries/model/src/model/SkyFromAtmosphere.slv rename to libraries/render-utils/src/SkyFromAtmosphere.slv diff --git a/libraries/model/src/model/SkyFromSpace.slf b/libraries/render-utils/src/SkyFromSpace.slf similarity index 100% rename from libraries/model/src/model/SkyFromSpace.slf rename to libraries/render-utils/src/SkyFromSpace.slf diff --git a/libraries/model/src/model/SkyFromSpace.slv b/libraries/render-utils/src/SkyFromSpace.slv similarity index 100% rename from libraries/model/src/model/SkyFromSpace.slv rename to libraries/render-utils/src/SkyFromSpace.slv From 0e18c75b0bacd7f6f67e8200690de81cc24e507d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 17 Jun 2015 09:23:12 -0700 Subject: [PATCH 31/41] cleanup --- libraries/render-utils/src/SkyFromAtmosphere.slf | 4 ++-- libraries/render-utils/src/SkyFromAtmosphere.slv | 8 +++----- libraries/render-utils/src/SkyFromSpace.slf | 4 ++-- libraries/render-utils/src/SkyFromSpace.slv | 8 ++++---- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/libraries/render-utils/src/SkyFromAtmosphere.slf b/libraries/render-utils/src/SkyFromAtmosphere.slf index a9e2bc6156..53d0573737 100755 --- a/libraries/render-utils/src/SkyFromAtmosphere.slf +++ b/libraries/render-utils/src/SkyFromAtmosphere.slf @@ -51,7 +51,7 @@ uniform vec3 v3LightPos; uniform float g; uniform float g2; -varying vec3 myPosition; +varying vec3 position; float scale(float fCos) @@ -64,7 +64,7 @@ float scale(float fCos) void main (void) { // Get the ray from the camera to the vertex, and its length (which is the far point of the ray passing through the atmosphere) - vec3 v3Pos = myPosition; + vec3 v3Pos = position; vec3 v3Ray = v3Pos - v3CameraPos; float fFar = length(v3Ray); v3Ray /= fFar; diff --git a/libraries/render-utils/src/SkyFromAtmosphere.slv b/libraries/render-utils/src/SkyFromAtmosphere.slv index 99c782adf1..29c907b94c 100755 --- a/libraries/render-utils/src/SkyFromAtmosphere.slv +++ b/libraries/render-utils/src/SkyFromAtmosphere.slv @@ -53,18 +53,16 @@ uniform float fScaleOverScaleDepth; // fScale / fScaleDepth const int nSamples = 2; const float fSamples = 2.0; -varying vec3 myPosition; +varying vec3 position; void main(void) { // Get the ray from the camera to the vertex, and its length (which is the far point of the ray passing through the atmosphere) - myPosition = gl_Vertex.xyz * fOuterRadius; + position = gl_Vertex.xyz * fOuterRadius; - //gl_Position = gl_ModelViewProjectionMatrix * vec4(position, 1.0); - // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); - vec4 v4pos = vec4(myPosition, 1.0); + vec4 v4pos = vec4(position, 1.0); <$transformModelToClipPos(cam, obj, v4pos, gl_Position)$> } diff --git a/libraries/render-utils/src/SkyFromSpace.slf b/libraries/render-utils/src/SkyFromSpace.slf index 4e13438ccb..5f6ce80efa 100755 --- a/libraries/render-utils/src/SkyFromSpace.slf +++ b/libraries/render-utils/src/SkyFromSpace.slf @@ -53,7 +53,7 @@ uniform float g2; const int nSamples = 2; const float fSamples = 2.0; -varying vec3 myPosition; +varying vec3 position; float scale(float fCos) { @@ -65,7 +65,7 @@ float scale(float fCos) void main (void) { // Get the ray from the camera to the vertex and its length (which is the far point of the ray passing through the atmosphere) - vec3 v3Pos = myPosition; + vec3 v3Pos = position; vec3 v3Ray = v3Pos - v3CameraPos; float fFar = length(v3Ray); v3Ray /= fFar; diff --git a/libraries/render-utils/src/SkyFromSpace.slv b/libraries/render-utils/src/SkyFromSpace.slv index 9090d76da2..6427af6715 100755 --- a/libraries/render-utils/src/SkyFromSpace.slv +++ b/libraries/render-utils/src/SkyFromSpace.slv @@ -38,15 +38,15 @@ uniform float fOuterRadius; // The outer (atmosphere) radius -varying vec3 myPosition; +varying vec3 position; void main(void) { - myPosition = gl_Vertex.xyz * fOuterRadius; + position = gl_Vertex.xyz * fOuterRadius; // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); - vec4 v4pos = vec4(myPosition, 1.0); + vec4 v4pos = vec4(position, 1.0); <$transformModelToClipPos(cam, obj, v4pos, gl_Position)$> -} \ No newline at end of file +} From 268bb370ccafc9d395cb40e600005410e8bb092c Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 17 Jun 2015 09:24:42 -0700 Subject: [PATCH 32/41] cleanup --- libraries/model/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/model/CMakeLists.txt b/libraries/model/CMakeLists.txt index 7456716946..1520378f1a 100755 --- a/libraries/model/CMakeLists.txt +++ b/libraries/model/CMakeLists.txt @@ -1,6 +1,5 @@ set(TARGET_NAME model) - AUTOSCRIBE_SHADER_LIB(gpu) # use setup_hifi_library macro to setup our project and link appropriate Qt modules From 8162c37013131d4b4011057dcc01e4e5a9bcf6c3 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 17 Jun 2015 09:33:15 -0700 Subject: [PATCH 33/41] cleanup --- libraries/model/CMakeLists.txt | 2 +- libraries/render-utils/src/Environment.h | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/libraries/model/CMakeLists.txt b/libraries/model/CMakeLists.txt index 1520378f1a..278c40c435 100755 --- a/libraries/model/CMakeLists.txt +++ b/libraries/model/CMakeLists.txt @@ -1,5 +1,5 @@ set(TARGET_NAME model) - + AUTOSCRIBE_SHADER_LIB(gpu) # use setup_hifi_library macro to setup our project and link appropriate Qt modules diff --git a/libraries/render-utils/src/Environment.h b/libraries/render-utils/src/Environment.h index fe0c564493..65e0df4b36 100644 --- a/libraries/render-utils/src/Environment.h +++ b/libraries/render-utils/src/Environment.h @@ -18,9 +18,7 @@ #include #include -//#include - -#include "EnvironmentData.h" +#include class ViewFrustum; class ProgramObject; From 467609f2b69e0b6c9382071a99523f978735b5b2 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 17 Jun 2015 09:44:26 -0700 Subject: [PATCH 34/41] standardize skybox and atmosphere batch --- interface/src/Application.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1ead8fe4f8..8d5f8810fd 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3332,12 +3332,6 @@ namespace render { "Application::displaySide() ... atmosphere..."); background->_environment->renderAtmospheres(batch, *(args->_viewFrustum)); - - // FIX ME - If I don't call this renderBatch() here, then the atmosphere doesn't render, but it - // seems like these payloadRender() methods shouldn't be doing this. We need to investigate why - // the engine isn't rendering our batch - gpu::GLBackend::renderBatch(batch, true); - } } @@ -3346,12 +3340,13 @@ namespace render { skybox = skyStage->getSkybox(); if (skybox) { - gpu::Batch batch; model::Skybox::render(batch, *(Application::getInstance()->getDisplayViewFrustum()), *skybox); - gpu::GLBackend::renderBatch(batch, true); - glUseProgram(0); } } + // FIX ME - If I don't call this renderBatch() here, then the atmosphere and skybox don't render, but it + // seems like these payloadRender() methods shouldn't be doing this. We need to investigate why the engine + // isn't rendering our batch + gpu::GLBackend::renderBatch(batch, true); } } From 689e10cc27185c0d17973e28fdbe01eba06e3f75 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 17 Jun 2015 09:53:50 -0700 Subject: [PATCH 35/41] build buster fix --- libraries/model/src/model/Stage.cpp | 15 --------------- libraries/model/src/model/Stage.h | 2 -- 2 files changed, 17 deletions(-) diff --git a/libraries/model/src/model/Stage.cpp b/libraries/model/src/model/Stage.cpp index a255a1f7c9..a3a8b9f3fd 100644 --- a/libraries/model/src/model/Stage.cpp +++ b/libraries/model/src/model/Stage.cpp @@ -14,9 +14,6 @@ #include #include -#include "SkyFromAtmosphere_vert.h" -#include "SkyFromAtmosphere_frag.h" - using namespace model; @@ -207,17 +204,6 @@ SunSkyStage::SunSkyStage() : // Begining of march setYearTime(60.0f); - auto skyFromAtmosphereVertex = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(SkyFromAtmosphere_vert))); - auto skyFromAtmosphereFragment = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(SkyFromAtmosphere_frag))); - auto skyShader = gpu::ShaderPointer(gpu::Shader::createProgram(skyFromAtmosphereVertex, skyFromAtmosphereFragment)); - - auto skyState = gpu::StatePointer(new gpu::State()); - // skyState->setStencilEnable(false); - // skyState->setBlendEnable(false); - - _skyPipeline = gpu::PipelinePointer(gpu::Pipeline::create(skyShader, skyState)); - - _skybox.reset(new Skybox()); _skybox->setColor(Color(1.0f, 0.0f, 0.0f)); @@ -310,7 +296,6 @@ void SunSkyStage::updateGraphicsObject() const { static int firstTime = 0; if (firstTime == 0) { firstTime++; - gpu::Shader::makeProgram(*(_skyPipeline->getProgram())); } } diff --git a/libraries/model/src/model/Stage.h b/libraries/model/src/model/Stage.h index fc90b0c903..b4df45e024 100644 --- a/libraries/model/src/model/Stage.h +++ b/libraries/model/src/model/Stage.h @@ -229,8 +229,6 @@ protected: AtmospherePointer _atmosphere; mutable SkyboxPointer _skybox; - gpu::PipelinePointer _skyPipeline; - float _dayTime = 12.0f; int _yearTime = 0; mutable EarthSunModel _earthSunModel; From e9bf553254c2edf9e80caf691c94a5e79db554a0 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 17 Jun 2015 09:59:38 -0700 Subject: [PATCH 36/41] CR feedback --- libraries/render-utils/src/SkyFromAtmosphere.slf | 5 ++--- libraries/render-utils/src/SkyFromSpace.slf | 7 ++++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/render-utils/src/SkyFromAtmosphere.slf b/libraries/render-utils/src/SkyFromAtmosphere.slf index 53d0573737..1e1718677c 100755 --- a/libraries/render-utils/src/SkyFromAtmosphere.slf +++ b/libraries/render-utils/src/SkyFromAtmosphere.slf @@ -106,7 +106,6 @@ void main (void) float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos*fCos) / pow(1.0 + g2 - 2.0*g*fCos, 1.5); vec3 finalColor = frontColor.rgb + fMiePhase * secondaryFrontColor.rgb; - gl_FragData[0].rgb = finalColor; - gl_FragData[0].a = finalColor.b; - gl_FragData[0].rgb = pow(finalColor.rgb, vec3(1.0/2.2)); + gl_FragColor.a = finalColor.b; + gl_FragColor.rgb = pow(finalColor.rgb, vec3(1.0/2.2)); } diff --git a/libraries/render-utils/src/SkyFromSpace.slf b/libraries/render-utils/src/SkyFromSpace.slf index 5f6ce80efa..2373511932 100755 --- a/libraries/render-utils/src/SkyFromSpace.slf +++ b/libraries/render-utils/src/SkyFromSpace.slf @@ -108,7 +108,8 @@ void main (void) float fMiePhase = 1.5 * ((1.0 - g2) / (2.0 + g2)) * (1.0 + fCos*fCos) / pow(1.0 + g2 - 2.0*g*fCos, 1.5); vec3 color = v3FrontColor * (v3InvWavelength * fKrESun); vec3 secondaryColor = v3FrontColor * fKmESun; - gl_FragColor.rgb = color + fMiePhase * secondaryColor; - gl_FragColor.a = gl_FragColor.b; - gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(1.0/2.2)); + + vec3 finalColor = color + fMiePhase * secondaryColor; + gl_FragColor.a = finalColor.b; + gl_FragColor.rgb = pow(finalColor.rgb, vec3(1.0/2.2)); } From fb59939cf4b2781e045b07837fda4a1f06c1db30 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 17 Jun 2015 10:02:02 -0700 Subject: [PATCH 37/41] CR feedback --- libraries/model/src/model/Stage.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libraries/model/src/model/Stage.cpp b/libraries/model/src/model/Stage.cpp index a3a8b9f3fd..220ee31c65 100644 --- a/libraries/model/src/model/Stage.cpp +++ b/libraries/model/src/model/Stage.cpp @@ -292,11 +292,6 @@ void SunSkyStage::updateGraphicsObject() const { case NUM_BACKGROUND_MODES: Q_UNREACHABLE(); }; - - static int firstTime = 0; - if (firstTime == 0) { - firstTime++; - } } void SunSkyStage::setBackgroundMode(BackgroundMode mode) { From dc4ae082f87e70db6005b3a47d321e1fde86bdb7 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 17 Jun 2015 10:13:49 -0700 Subject: [PATCH 38/41] make goToUser public again --- libraries/networking/src/AddressManager.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index a0fc7eb0be..b4c34176a4 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -72,6 +72,8 @@ public slots: void goBack(); void goForward(); + void goToUser(const QString& username); + void storeCurrentAddress(); void copyAddress(); @@ -100,7 +102,6 @@ private slots: void handleAPIResponse(QNetworkReply& requestReply); void handleAPIError(QNetworkReply& errorReply); - void goToUser(const QString& username); void goToAddressFromObject(const QVariantMap& addressMap, const QNetworkReply& reply); private: void setHost(const QString& host, LookupTrigger trigger); From bc20ea6ed284dacc5a324246e56824c94b02b491 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 17 Jun 2015 11:18:43 -0700 Subject: [PATCH 39/41] fix for path handling on return of place info --- libraries/networking/src/AddressManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 6941d7335d..a8ed54fdd1 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -305,7 +305,7 @@ void AddressManager::goToAddressFromObject(const QVariantMap& dataObject, const << returnedPath; } } else { - handlePath(overridePath, trigger); + handlePath(returnedPath, trigger); } } else { // we didn't override the path or get one back - ask the DS for the viewpoint of its index path From 45a5f1364a21abb89771654baf97b498bafe2b89 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Wed, 17 Jun 2015 11:56:44 -0700 Subject: [PATCH 40/41] fix compile issue if you don't have sdl2 --- interface/src/devices/SDL2Manager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/devices/SDL2Manager.cpp b/interface/src/devices/SDL2Manager.cpp index 32408fce18..e039a80b0d 100644 --- a/interface/src/devices/SDL2Manager.cpp +++ b/interface/src/devices/SDL2Manager.cpp @@ -74,9 +74,11 @@ SDL2Manager* SDL2Manager::getInstance() { } void SDL2Manager::focusOutEvent() { +#ifdef HAVE_SDL2 for (auto joystick : _openJoysticks) { joystick->focusOutEvent(); } +#endif } void SDL2Manager::update() { From b4dfaba55ec57bf18830723e0691fc2a73ffed1d Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Wed, 17 Jun 2015 11:59:15 -0700 Subject: [PATCH 41/41] Incorporate ctrlaltdavid's changes. --- libraries/audio-client/src/AudioClient.cpp | 11 ++++++++++- libraries/audio-client/src/AudioClient.h | 5 +++++ libraries/audio/src/AudioInjector.cpp | 5 +---- libraries/audio/src/AudioInjectorLocalBuffer.cpp | 13 ++----------- libraries/audio/src/AudioInjectorLocalBuffer.h | 4 ---- 5 files changed, 18 insertions(+), 20 deletions(-) diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 6450f25208..84022d0fb9 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -1011,7 +1011,10 @@ bool AudioClient::outputLocalInjector(bool isStereo, AudioInjector* injector) { localOutput->moveToThread(injector->getLocalBuffer()->thread()); // have it be stopped when that local buffer is about to close - connect(injector->getLocalBuffer(), &AudioInjectorLocalBuffer::bufferEmpty, localOutput, &QAudioOutput::stop); + connect(localOutput, &QAudioOutput::stateChanged, this, &AudioClient::audioStateChanged); + connect(this, &AudioClient::audioFinished, localOutput, &QAudioOutput::stop); + connect(this, &AudioClient::audioFinished, injector, &AudioInjector::stop); + connect(injector->getLocalBuffer(), &QIODevice::aboutToClose, localOutput, &QAudioOutput::stop); qCDebug(audioclient) << "Starting QAudioOutput for local injector" << localOutput; @@ -1329,3 +1332,9 @@ void AudioClient::saveSettings() { windowSecondsForDesiredReduction.set(_receivedAudioStream.getWindowSecondsForDesiredReduction()); repetitionWithFade.set(_receivedAudioStream.getRepetitionWithFade()); } + +void AudioClient::audioStateChanged(QAudio::State state) { + if (state == QAudio::IdleState) { + emit audioFinished(); + } +} diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index 642edde84a..d2492e1064 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -188,6 +188,8 @@ signals: void receivedFirstPacket(); void disconnected(); + void audioFinished(); + protected: AudioClient(); ~AudioClient(); @@ -196,6 +198,9 @@ protected: deleteLater(); } +private slots: + void audioStateChanged(QAudio::State state); + private: void outputFormatChanged(); diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index 333a944e1b..675a3b8b28 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -51,7 +51,7 @@ void AudioInjector::setIsFinished(bool isFinished) { emit finished(); if (_localBuffer) { - // delete will stop (and nosily if we do so ourselves here first). + _localBuffer->stop(); _localBuffer->deleteLater(); _localBuffer = NULL; } @@ -121,9 +121,6 @@ void AudioInjector::injectLocally() { success = _localAudioInterface->outputLocalInjector(_options.stereo, this); - // if we're not looping and the buffer tells us it is empty then emit finished - connect(_localBuffer, &AudioInjectorLocalBuffer::bufferEmpty, this, &AudioInjector::stop); - if (!success) { qCDebug(audio) << "AudioInjector::injectLocally could not output locally via _localAudioInterface"; } diff --git a/libraries/audio/src/AudioInjectorLocalBuffer.cpp b/libraries/audio/src/AudioInjectorLocalBuffer.cpp index 457abeb89e..27e93a678e 100644 --- a/libraries/audio/src/AudioInjectorLocalBuffer.cpp +++ b/libraries/audio/src/AudioInjectorLocalBuffer.cpp @@ -17,8 +17,7 @@ AudioInjectorLocalBuffer::AudioInjectorLocalBuffer(const QByteArray& rawAudioArr _shouldLoop(false), _isStopped(false), _currentOffset(0), - _volume(1.0f), - _isFinished(false) + _volume(1.0f) { } @@ -52,11 +51,6 @@ void copy(char* to, char* from, int size, qreal factor) { qint64 AudioInjectorLocalBuffer::readData(char* data, qint64 maxSize) { if (!_isStopped) { - if (_isFinished) { - emit bufferEmpty(); - return -1; // qt docs say -1 is appropriate when subsequent calls will not write data - } - // first copy to the end of the raw audio int bytesToEnd = _rawAudioArray.size() - _currentOffset; @@ -75,10 +69,7 @@ qint64 AudioInjectorLocalBuffer::readData(char* data, qint64 maxSize) { _currentOffset += bytesRead; } - if (!_shouldLoop && bytesRead == bytesToEnd) { - // If we emit bufferEmpty now, we'll clip the end of the sound. Wait until the next call. - _isFinished = true; - } else if (_shouldLoop && _currentOffset == _rawAudioArray.size()) { + if (_shouldLoop && _currentOffset == _rawAudioArray.size()) { _currentOffset = 0; } diff --git a/libraries/audio/src/AudioInjectorLocalBuffer.h b/libraries/audio/src/AudioInjectorLocalBuffer.h index 270e730590..32a1221b78 100644 --- a/libraries/audio/src/AudioInjectorLocalBuffer.h +++ b/libraries/audio/src/AudioInjectorLocalBuffer.h @@ -32,9 +32,6 @@ public: void setCurrentOffset(int currentOffset) { _currentOffset = currentOffset; } void setVolume(float volume) { _volume = glm::clamp(volume, 0.0f, 1.0f); } -signals: - void bufferEmpty(); - private: qint64 recursiveReadFromFront(char* data, qint64 maxSize); @@ -44,7 +41,6 @@ private: int _currentOffset; float _volume; - bool _isFinished; }; #endif // hifi_AudioInjectorLocalBuffer_h \ No newline at end of file