From 3f26e1b63ad18ab228b2138e6ab9f4d3f068909f Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Sat, 13 Dec 2014 23:04:19 +0100 Subject: [PATCH 01/93] RealSense Initial --- cmake/modules/FindRSSDK.cmake | 33 ++++ interface/CMakeLists.txt | 2 +- interface/src/Application.cpp | 2 + interface/src/Menu.cpp | 10 ++ interface/src/Menu.h | 2 + interface/src/devices/RealSense.cpp | 233 ++++++++++++++++++++++++++++ interface/src/devices/RealSense.h | 63 ++++++++ 7 files changed, 344 insertions(+), 1 deletion(-) create mode 100644 cmake/modules/FindRSSDK.cmake create mode 100644 interface/src/devices/RealSense.cpp create mode 100644 interface/src/devices/RealSense.h diff --git a/cmake/modules/FindRSSDK.cmake b/cmake/modules/FindRSSDK.cmake new file mode 100644 index 0000000000..c31b0efcd9 --- /dev/null +++ b/cmake/modules/FindRSSDK.cmake @@ -0,0 +1,33 @@ +# Try to find the RSSDK library +# +# You must provide a RSSDK_ROOT_DIR which contains lib and include directories +# +# Once done this will define +# +# RSSDK_FOUND - system found RSSDK +# RSSDK_INCLUDE_DIRS - the RSSDK include directory +# RSSDK_LIBRARIES - Link this to use RSSDK +# +# Created on 12/7/2014 by Thijs Wenker +# Copyright (c) 2014 High Fidelity +# + +include("${MACRO_DIR}/HifiLibrarySearchHints.cmake") +hifi_library_search_hints("rssdk") + +find_path(RSSDK_INCLUDE_DIRS pxcbase.h PATH_SUFFIXES include HINTS ${RSSDK_SEARCH_DIRS}) + +if (WIN32) + find_library(RSSDK_LIBRARY_DEBUG libpxc_d PATH_SUFFIXES lib/Win32 HINTS ${RSSDK_SEARCH_DIRS}) + find_library(RSSDK_LIBRARY_RELEASE libpxc PATH_SUFFIXES lib/Win32 HINTS ${RSSDK_SEARCH_DIRS}) +endif () + +include(SelectLibraryConfigurations) +select_library_configurations(RSSDK) + +set(RSSDK_LIBRARIES "${RSSDK_LIBRARY}") + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(RSSDK DEFAULT_MSG RSSDK_INCLUDE_DIRS RSSDK_LIBRARIES) + +mark_as_advanced(RSSDK_INCLUDE_DIRS RSSDK_LIBRARIES RSSDK_SEARCH_DIRS) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 38dd02c655..bc25778940 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -2,7 +2,7 @@ set(TARGET_NAME interface) project(${TARGET_NAME}) # set a default root dir for each of our optional externals if it was not passed -set(OPTIONAL_EXTERNALS "Faceshift" "LibOVR" "PrioVR" "Sixense" "Visage" "LeapMotion" "RtMidi" "Qxmpp" "SDL2" "Gverb") +set(OPTIONAL_EXTERNALS "Faceshift" "LibOVR" "PrioVR" "Sixense" "Visage" "LeapMotion" "RtMidi" "Qxmpp" "SDL2" "Gverb" "RSSDK") foreach(EXTERNAL ${OPTIONAL_EXTERNALS}) string(TOUPPER ${EXTERNAL} ${EXTERNAL}_UPPERCASE) if (NOT ${${EXTERNAL}_UPPERCASE}_ROOT_DIR) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3824185f52..08e3a78653 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -76,6 +76,7 @@ #include "Util.h" #include "devices/Leapmotion.h" +#include "devices/RealSense.h" #include "devices/MIDIManager.h" #include "devices/OculusManager.h" #include "devices/TV3DManager.h" @@ -1994,6 +1995,7 @@ void Application::init() { _visage.init(); Leapmotion::init(); + RealSense::init(); // fire off an immediate domain-server check in now that settings are loaded NodeList::getInstance()->sendDomainServerCheckIn(); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index ae12b5ff26..37e4d96ed6 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -49,6 +49,7 @@ #include "ui/ModelsBrowser.h" #include "ui/LoginDialog.h" #include "ui/NodeBounds.h" +#include "devices/RealSense.h" #include "devices/OculusManager.h" @@ -493,6 +494,11 @@ Menu::Menu() : QMenu* leapOptionsMenu = handOptionsMenu->addMenu("Leap Motion"); addCheckableActionToQMenuAndActionHash(leapOptionsMenu, MenuOption::LeapMotionOnHMD, 0, false); +#ifdef HAVE_RSSDK + QMenu* realSenseOptionsMenu = handOptionsMenu->addMenu("RealSense"); + addActionToQMenuAndActionHash(realSenseOptionsMenu, MenuOption::LoadRSSDKFile, 0, this, SLOT(loadRSSDKFile())); +#endif + QMenu* networkMenu = developerMenu->addMenu("Network"); addCheckableActionToQMenuAndActionHash(networkMenu, MenuOption::DisableNackPackets, 0, false); addCheckableActionToQMenuAndActionHash(networkMenu, @@ -1346,6 +1352,10 @@ void Menu::showChat() { } } +void Menu::loadRSSDKFile() { + RealSense::getInstance()->loadRSSDKFile(); +} + void Menu::toggleChat() { #ifdef HAVE_QXMPP _chatAction->setEnabled(XmppClient::getInstance().getXMPPClient().isConnected()); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 138828d3e8..4ed5be8057 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -236,6 +236,7 @@ private slots: void displayAddressNotFoundMessage(); void muteEnvironment(); void changeVSync(); + void loadRSSDKFile(); private: static Menu* _instance; @@ -414,6 +415,7 @@ namespace MenuOption { const QString LeapMotionOnHMD = "Leap Motion on HMD"; const QString LoadScript = "Open and Run Script File..."; const QString LoadScriptURL = "Open and Run Script from URL..."; + const QString LoadRSSDKFile = "Load .rssdk file"; const QString LodTools = "LOD Tools"; const QString Login = "Login"; const QString Log = "Log"; diff --git a/interface/src/devices/RealSense.cpp b/interface/src/devices/RealSense.cpp new file mode 100644 index 0000000000..08492d8377 --- /dev/null +++ b/interface/src/devices/RealSense.cpp @@ -0,0 +1,233 @@ +// +// RealSense.cpp +// interface/src/devices +// +// Created by Thijs Wenker on 12/10/14 +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#include "RealSense.h" +#include "Menu.h" +#include "SharedUtil.h" + +const int PALMROOT_NUM_JOINTS = 2; +const int FINGER_NUM_JOINTS = 4; + +const DeviceTracker::Name RealSense::NAME = "RealSense"; + +// find the index of a joint from +// the side: true = right +// the finger & the bone: +// finger in [0..4] : bone in [0..3] a finger phalange +// [-1] up the hand branch : bone in [0..2] <=> [ hand, forearm, arm] +MotionTracker::Index evalRealSenseJointIndex(bool isRightSide, int finger, int bone) { + + MotionTracker::Index offset = 1 // start after root + + (int(isRightSide) * PXCHandData::NUMBER_OF_JOINTS) // then offset for side + + PALMROOT_NUM_JOINTS; // then add the arm/forearm/hand chain + if (finger >= 0) { + // from there go down in the correct finger and bone + return offset + (finger * FINGER_NUM_JOINTS) + bone; + } else { + // or go back up for the correct root bone + return offset - 1 - bone; + } +} + +// static +void RealSense::init() { + DeviceTracker* device = DeviceTracker::getDevice(NAME); + if (!device) { + // create a new RealSense and register it + RealSense* realSense = new RealSense(); + DeviceTracker::registerDevice(NAME, realSense); + } +} + +// static +RealSense* RealSense::getInstance() { + DeviceTracker* device = DeviceTracker::getDevice(NAME); + if (!device) { + // create a new RealSense and register it + RealSense* realSense = new RealSense(); + DeviceTracker::registerDevice(NAME, realSense); + } + return dynamic_cast< RealSense* > (device); +} + +RealSense::RealSense() : + MotionTracker(), + _active(false), + _handData(NULL) +{ + _session = PXCSession_Create(); + initSession(false, NULL); + + // Create the RealSense joint hierarchy + std::vector< Semantic > sides; + sides.push_back("joint_L_"); + sides.push_back("joint_R_"); + + std::vector< Semantic > rootBones; + rootBones.push_back("wrist"); + rootBones.push_back("hand"); + + std::vector< Semantic > fingers; + fingers.push_back("thumb"); + fingers.push_back("index"); + fingers.push_back("middle"); + fingers.push_back("ring"); + fingers.push_back("pinky"); + + std::vector< Semantic > fingerBones; + fingerBones.push_back("1"); + fingerBones.push_back("2"); + fingerBones.push_back("3"); + fingerBones.push_back("4"); + + std::vector< Index > palms; + for (unsigned int s = 0; s < sides.size(); s++) { + Index rootJoint = 0; + for (unsigned int rb = 0; rb < rootBones.size(); rb++) { + rootJoint = addJoint(sides[s] + rootBones[rb], rootJoint); + } + + // capture the hand index for debug + palms.push_back(rootJoint); + + for (unsigned int f = 0; f < fingers.size(); f++) { + for (unsigned int b = 0; b < fingerBones.size(); b++) { + rootJoint = addJoint(sides[s] + fingers[f] + fingerBones[b], rootJoint); + } + } + } +} + +RealSense::~RealSense() { + _manager->Release(); +} + +void RealSense::initSession(bool playback, QString filename) { + _active = false; + _properlyInitialized = false; + if (_handData != NULL) { + _handData->Release(); + _handController->Release(); + _session->Release(); + } + _manager = _session->CreateSenseManager(); + if (playback) { + _manager->QueryCaptureManager()->SetFileName(filename.toStdWString().c_str(), false); + } + _manager->QueryCaptureManager()->SetRealtime(!playback); + _manager->EnableHand(0); + _handController = _manager->QueryHand(); + + if (_manager->Init() == PXC_STATUS_NO_ERROR) { + _handData = _handController->CreateOutput(); + + PXCCapture::Device *device = _manager->QueryCaptureManager()->QueryDevice(); + PXCCapture::DeviceInfo dinfo; + _manager->QueryCaptureManager()->QueryDevice()->QueryDeviceInfo(&dinfo); + if (dinfo.model == PXCCapture::DEVICE_MODEL_IVCAM) + { + device->SetDepthConfidenceThreshold(1); + device->SetMirrorMode(PXCCapture::Device::MIRROR_MODE_DISABLED); + device->SetIVCAMFilterOption(6); + } + _properlyInitialized = true; + } +} + +#ifdef HAVE_RSSDK +glm::quat quatFromPXCPoint4DF32(const PXCPoint4DF32& basis) { + return glm::quat(basis.w, basis.x, basis.y, basis.z); +} + +glm::vec3 vec3FromPXCPoint3DF32(const PXCPoint3DF32& vec) { + return glm::vec3(vec.x, vec.y, vec.z); +} +#endif + +void RealSense::update() { +#ifdef HAVE_RSSDK + bool wasActive = _active; + _active = _manager->IsConnected() && _properlyInitialized; + if (_active || wasActive) { + // Go through all the joints and increment their counter since last update. + // Increment all counters once after controller first becomes inactive so that each joint reports itself as inactive. + // TODO C++11 for (auto jointIt = _jointsArray.begin(); jointIt != _jointsArray.end(); jointIt++) { + for (JointTracker::Vector::iterator jointIt = _jointsArray.begin(); jointIt != _jointsArray.end(); jointIt++) { + (*jointIt).tickNewFrame(); + } + } + + if (!_active) { + return; + } + + pxcStatus sts = _manager->AcquireFrame(true); + _handData->Update(); + PXCHandData::JointData nodes[2][PXCHandData::NUMBER_OF_JOINTS] = {}; + PXCHandData::ExtremityData extremitiesPointsNodes[2][PXCHandData::NUMBER_OF_EXTREMITIES] = {}; + for (pxcI32 i = 0; i < _handData->QueryNumberOfHands(); i++) { + PXCHandData::IHand* handData; + if (_handData->QueryHandData(PXCHandData::ACCESS_ORDER_BY_TIME, i, handData) == PXC_STATUS_NO_ERROR) { + int rightSide = handData->QueryBodySide() == PXCHandData::BODY_SIDE_RIGHT; + PXCHandData::JointData jointData; + JointTracker* parentJointTracker = _jointsArray.data(); + //Iterate Joints + int rootBranchIndex = -1; + JointTracker* palmJoint = NULL; + for (int j = 0; j < PXCHandData::NUMBER_OF_JOINTS; j++) { + handData->QueryTrackedJoint((PXCHandData::JointType)j, jointData); + nodes[i][j] = jointData; + if (j == PXCHandData::JOINT_WRIST) { + JointTracker* wrist = editJointTracker(evalRealSenseJointIndex(rightSide, rootBranchIndex, 1)); // 1 is the index of the wrist joint + wrist->editAbsFrame().setTranslation(vec3FromPXCPoint3DF32(jointData.positionWorld)); + wrist->editAbsFrame().setRotation(quatFromPXCPoint4DF32(jointData.globalOrientation)); + wrist->updateLocFromAbsTransform(parentJointTracker); + wrist->activeFrame(); + parentJointTracker = wrist; + continue; + } else if (j == PXCHandData::JOINT_CENTER) { + palmJoint = editJointTracker(evalRealSenseJointIndex(rightSide, rootBranchIndex, 0)); // 0 is the index of the palm joint + palmJoint->editAbsFrame().setTranslation(vec3FromPXCPoint3DF32(jointData.positionWorld)); + palmJoint->editAbsFrame().setRotation(quatFromPXCPoint4DF32(jointData.globalOrientation)); + palmJoint->updateLocFromAbsTransform(parentJointTracker); + palmJoint->activeFrame(); + parentJointTracker = palmJoint; + continue; + } + int finger_index = j - PALMROOT_NUM_JOINTS; + int finger = finger_index / FINGER_NUM_JOINTS; + int finger_bone = finger_index % FINGER_NUM_JOINTS; + JointTracker* ljointTracker = editJointTracker(evalRealSenseJointIndex(rightSide, finger, finger_bone)); + if (jointData.confidence > 0) { + ljointTracker->editAbsFrame().setTranslation(vec3FromPXCPoint3DF32(jointData.positionWorld)); + ljointTracker->editAbsFrame().setRotation(quatFromPXCPoint4DF32(jointData.globalOrientation)); + ljointTracker->updateLocFromAbsTransform(parentJointTracker); + ljointTracker->activeFrame(); + } + if (finger_bone == (FINGER_NUM_JOINTS - 1)) { + parentJointTracker = palmJoint; + continue; + } + parentJointTracker = ljointTracker; + } + } + } + _manager->ReleaseFrame(); +#endif // HAVE_RSSDK +} + +void RealSense::loadRSSDKFile() { + QString fileNameString = QFileDialog::getOpenFileName(Application::getInstance()->getGLWidget(), tr("Open RSSDK clip"), + NULL, + tr("RSSDK Recordings (*.rssdk)")); + if (!fileNameString.isEmpty()) { + initSession(true, fileNameString); + } +} diff --git a/interface/src/devices/RealSense.h b/interface/src/devices/RealSense.h new file mode 100644 index 0000000000..015f1e7ce6 --- /dev/null +++ b/interface/src/devices/RealSense.h @@ -0,0 +1,63 @@ +// +// RealSense.h +// interface/src/devices +// +// Created by Thijs Wenker on 12/10/14 +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_RealSense_h +#define hifi_RealSense_h + +#include + +#include "MotionTracker.h" + +#ifdef HAVE_RSSDK +#include +#include +#include +#include +#include +#endif + +/// Handles interaction with the RealSense skeleton tracking suit. +class RealSense : public QObject, public MotionTracker { + Q_OBJECT + +public: + static const Name NAME; + + static void init(); + + /// RealSense MotionTracker factory + static RealSense* getInstance(); + + bool isActive() const { return _active; } + + virtual void update(); + + void loadRSSDKFile(); + +protected: + RealSense(); + virtual ~RealSense(); + + void initSession(bool playback, QString filename); + +private: +#ifdef HAVE_RSSDK + PXCSession* _session; + PXCSenseManager* _manager; + PXCHandModule* _handController; + PXCHandData* _handData; + PXCHandConfiguration* _config; +#endif + bool _properlyInitialized; + bool _active; +}; + +#endif // hifi_RealSense_h From c4a9cae943c0efd659c6efb59d319e7c73f7ab16 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Mon, 15 Dec 2014 21:47:00 +0100 Subject: [PATCH 02/93] flipped some values to get a nicer hand-tracking --- interface/src/devices/RealSense.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/interface/src/devices/RealSense.cpp b/interface/src/devices/RealSense.cpp index 08492d8377..2c041a33c9 100644 --- a/interface/src/devices/RealSense.cpp +++ b/interface/src/devices/RealSense.cpp @@ -21,7 +21,7 @@ const DeviceTracker::Name RealSense::NAME = "RealSense"; // the side: true = right // the finger & the bone: // finger in [0..4] : bone in [0..3] a finger phalange -// [-1] up the hand branch : bone in [0..2] <=> [ hand, forearm, arm] +// [-1] up the hand branch : bone in [0..1] <=> [ hand, forearm] MotionTracker::Index evalRealSenseJointIndex(bool isRightSide, int finger, int bone) { MotionTracker::Index offset = 1 // start after root @@ -116,6 +116,7 @@ void RealSense::initSession(bool playback, QString filename) { _handData->Release(); _handController->Release(); _session->Release(); + _config->Release(); } _manager = _session->CreateSenseManager(); if (playback) { @@ -139,15 +140,20 @@ void RealSense::initSession(bool playback, QString filename) { } _properlyInitialized = true; } + + _config = _handController->CreateActiveConfiguration(); + _config->EnableStabilizer(true); + _config->SetTrackingMode(PXCHandData::TRACKING_MODE_FULL_HAND); + _config->ApplyChanges(); } #ifdef HAVE_RSSDK glm::quat quatFromPXCPoint4DF32(const PXCPoint4DF32& basis) { - return glm::quat(basis.w, basis.x, basis.y, basis.z); + return glm::normalize(glm::quat(basis.w, basis.x, basis.y, basis.z) * glm::quat(glm::vec3(0, M_PI, 0))); } glm::vec3 vec3FromPXCPoint3DF32(const PXCPoint3DF32& vec) { - return glm::vec3(vec.x, vec.y, vec.z); + return glm::vec3(-vec.x, vec.y, -vec.z); } #endif From 2633b0dee72d4e285bee3429c1b9eee6b0fec653 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Mon, 15 Dec 2014 22:26:47 +0100 Subject: [PATCH 03/93] reordered includes --- interface/src/Menu.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 9ef794db97..a9a039cd38 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -40,6 +40,7 @@ #include "AccountManager.h" #include "devices/Faceshift.h" #include "devices/OculusManager.h" +#include "devices/RealSense.h" #include "devices/Visage.h" #include "Menu.h" #include "scripting/LocationScriptingInterface.h" @@ -53,8 +54,6 @@ #include "ui/ModelsBrowser.h" #include "ui/LoginDialog.h" #include "ui/NodeBounds.h" -#include "devices/RealSense.h" -#include "devices/OculusManager.h" Menu* Menu::_instance = NULL; From 99b0cca8f32f4c93e8c5243dd8f855b598b6ff30 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Thu, 18 Dec 2014 00:08:20 +0100 Subject: [PATCH 04/93] realsenseHands.js example --- examples/realsenseHands.js | 525 +++++++++++++++++++++++++++++++++++++ 1 file changed, 525 insertions(+) create mode 100644 examples/realsenseHands.js diff --git a/examples/realsenseHands.js b/examples/realsenseHands.js new file mode 100644 index 0000000000..6b1a5c0a23 --- /dev/null +++ b/examples/realsenseHands.js @@ -0,0 +1,525 @@ +// +// realsenseHands.js +// examples +// +// Created by Thijs Wenker on 18 Dec 2014. +// Copyright 2014 High Fidelity, Inc. +// +// This is an example script that uses the Intel RealSense to make the avatar's hands replicate the user's hand actions. +// Most of this script is copied from leapHands.js +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +var leapHands = (function () { + + var isOnHMD, + MotionTracker = "RealSense", + LEAP_ON_HMD_MENU_ITEM = "Leap Motion on HMD", + LEAP_OFFSET = 0.019, // Thickness of Leap Motion plus HMD clip + HMD_OFFSET = 0.070, // Eyeballs to front surface of Oculus DK2 TODO: Confirm and make depend on device and eye relief + hasHandAndWristJoints, + handToWristOffset = [], // For avatars without a wrist joint we control an estimate of a proper hand joint position + HAND_OFFSET = 0.4, // Relative distance of wrist to hand versus wrist to index finger knuckle + hands, + wrists, + NUM_HANDS = 2, // 0 = left; 1 = right + fingers, + NUM_FINGERS = 5, // 0 = thumb; ...; 4 = pinky + THUMB = 0, + MIDDLE_FINGER = 2, + NUM_FINGER_JOINTS = 3, // 0 = metacarpal(hand)-proximal(finger) joint; ...; 2 = intermediate-distal joint + MAX_HAND_INACTIVE_COUNT = 20, + calibrationStatus, + UNCALIBRATED = 0, + CALIBRATING = 1, + CALIBRATED = 2, + CALIBRATION_TIME = 1000, // milliseconds + avatarScale, + avatarFaceModelURL, + avatarSkeletonModelURL, + settingsTimer; + + function printSkeletonJointNames() { + var jointNames, + i; + + print(MyAvatar.skeletonModelURL); + + print("Skeleton joint names ..."); + jointNames = MyAvatar.getJointNames(); + for (i = 0; i < jointNames.length; i += 1) { + print(i + ": " + jointNames[i]); + } + print("... skeleton joint names"); + + /* + http://public.highfidelity.io/models/skeletons/ron_standing.fst + Skeleton joint names ... + 0: Hips + 1: RightUpLeg + 2: RightLeg + 3: RightFoot + 4: RightToeBase + 5: RightToe_End + 6: LeftUpLeg + 7: LeftLeg + 8: LeftFoot + 9: LeftToeBase + 10: LeftToe_End + 11: Spine + 12: Spine1 + 13: Spine2 + 14: RightShoulder + 15: RightArm + 16: RightForeArm + 17: RightHand + 18: RightHandPinky1 + 19: RightHandPinky2 + 20: RightHandPinky3 + 21: RightHandPinky4 + 22: RightHandRing1 + 23: RightHandRing2 + 24: RightHandRing3 + 25: RightHandRing4 + 26: RightHandMiddle1 + 27: RightHandMiddle2 + 28: RightHandMiddle3 + 29: RightHandMiddle4 + 30: RightHandIndex1 + 31: RightHandIndex2 + 32: RightHandIndex3 + 33: RightHandIndex4 + 34: RightHandThumb1 + 35: RightHandThumb2 + 36: RightHandThumb3 + 37: RightHandThumb4 + 38: LeftShoulder + 39: LeftArm + 40: LeftForeArm + 41: LeftHand + 42: LeftHandPinky1 + 43: LeftHandPinky2 + 44: LeftHandPinky3 + 45: LeftHandPinky4 + 46: LeftHandRing1 + 47: LeftHandRing2 + 48: LeftHandRing3 + 49: LeftHandRing4 + 50: LeftHandMiddle1 + 51: LeftHandMiddle2 + 52: LeftHandMiddle3 + 53: LeftHandMiddle4 + 54: LeftHandIndex1 + 55: LeftHandIndex2 + 56: LeftHandIndex3 + 57: LeftHandIndex4 + 58: LeftHandThumb1 + 59: LeftHandThumb2 + 60: LeftHandThumb3 + 61: LeftHandThumb4 + 62: Neck + 63: Head + 64: HeadTop_End + 65: body + ... skeleton joint names + */ + } + + function finishCalibration() { + var avatarPosition, + handPosition, + middleFingerPosition, + leapHandHeight, + h; + + if (!isOnHMD) { + if (hands[0].controller.isActive() && hands[1].controller.isActive()) { + leapHandHeight = (hands[0].controller.getAbsTranslation().y + hands[1].controller.getAbsTranslation().y) / 2.0; + } else { + calibrationStatus = UNCALIBRATED; + return; + } + } + + avatarPosition = MyAvatar.position; + + for (h = 0; h < NUM_HANDS; h += 1) { + handPosition = MyAvatar.getJointPosition(hands[h].jointName); + if (!hasHandAndWristJoints) { + middleFingerPosition = MyAvatar.getJointPosition(fingers[h][MIDDLE_FINGER][0].jointName); + handToWristOffset[h] = Vec3.multiply(Vec3.subtract(handPosition, middleFingerPosition), 1.0 - HAND_OFFSET); + } + + if (isOnHMD) { + // Offset of Leap Motion origin from physical eye position + hands[h].zeroPosition = { x: 0.0, y: 0.0, z: HMD_OFFSET + LEAP_OFFSET }; + } else { + hands[h].zeroPosition = { + x: handPosition.x - avatarPosition.x, + y: handPosition.y - avatarPosition.y, + z: avatarPosition.z - handPosition.z + }; + hands[h].zeroPosition = Vec3.multiplyQbyV(MyAvatar.orientation, hands[h].zeroPosition); + hands[h].zeroPosition.y = hands[h].zeroPosition.y - leapHandHeight; + } + } + + MyAvatar.clearJointData("LeftHand"); + MyAvatar.clearJointData("LeftForeArm"); + MyAvatar.clearJointData("LeftArm"); + MyAvatar.clearJointData("RightHand"); + MyAvatar.clearJointData("RightForeArm"); + MyAvatar.clearJointData("RightArm"); + + calibrationStatus = CALIBRATED; + print("Leap Motion: Calibrated"); + } + + function calibrate() { + var jointNames, + i; + + calibrationStatus = CALIBRATING; + + avatarScale = MyAvatar.scale; + avatarFaceModelURL = MyAvatar.faceModelURL; + avatarSkeletonModelURL = MyAvatar.skeletonModelURL; + + // Does this skeleton have both wrist and hand joints? + hasHandAndWristJoints = false; + jointNames = MyAvatar.getJointNames(); + for (i = 0; i < jointNames.length; i += 1) { + hasHandAndWristJoints = hasHandAndWristJoints || jointNames[i].toLowerCase() === "leftwrist"; + } + + // Set avatar arms vertical, forearms horizontal, as "zero" position for calibration + MyAvatar.setJointData("LeftArm", Quat.fromPitchYawRollDegrees(90.0, 0.0, -90.0)); + MyAvatar.setJointData("LeftForeArm", Quat.fromPitchYawRollDegrees(90.0, 0.0, 180.0)); + MyAvatar.setJointData("LeftHand", Quat.fromPitchYawRollRadians(0.0, 0.0, 0.0)); + MyAvatar.setJointData("RightArm", Quat.fromPitchYawRollDegrees(90.0, 0.0, 90.0)); + MyAvatar.setJointData("RightForeArm", Quat.fromPitchYawRollDegrees(90.0, 0.0, 180.0)); + MyAvatar.setJointData("RightHand", Quat.fromPitchYawRollRadians(0.0, 0.0, 0.0)); + + + // Wait for arms to assume their positions before calculating + Script.setTimeout(finishCalibration, CALIBRATION_TIME); + } + + function checkCalibration() { + + if (calibrationStatus === CALIBRATED) { + return true; + } + + if (calibrationStatus !== CALIBRATING) { + calibrate(); + } + + return false; + } + + function setIsOnHMD() { + isOnHMD = Menu.isOptionChecked(LEAP_ON_HMD_MENU_ITEM); + print("Leap Motion: " + (isOnHMD ? "Is on HMD" : "Is on desk")); + } + + function checkSettings() { + if (calibrationStatus > UNCALIBRATED && (MyAvatar.scale !== avatarScale + || MyAvatar.faceModelURL !== avatarFaceModelURL + || MyAvatar.skeletonModelURL !== avatarSkeletonModelURL + || Menu.isOptionChecked(LEAP_ON_HMD_MENU_ITEM) !== isOnHMD)) { + print("Leap Motion: Recalibrate..."); + calibrationStatus = UNCALIBRATED; + + setIsOnHMD(); + } + } + + function setUp() { + + wrists = [ + { + jointName: "LeftWrist", + controller: Controller.createInputController(MotionTracker, "joint_L_wrist") + }, + { + jointName: "RightWrist", + controller: Controller.createInputController(MotionTracker, "joint_R_wrist") + } + ]; + + hands = [ + { + jointName: "LeftHand", + controller: Controller.createInputController(MotionTracker, "joint_L_hand"), + inactiveCount: 0 + }, + { + jointName: "RightHand", + controller: Controller.createInputController(MotionTracker, "joint_R_hand"), + inactiveCount: 0 + } + ]; + + // The Leap controller's first joint is the hand-metacarpal joint but this joint's data is not used because it's too + // dependent on the model skeleton exactly matching the Leap skeleton; using just the second and subsequent joints + // seems to work better over all. + fingers = [{}, {}]; + fingers[0] = [ + [ + { jointName: "LeftHandThumb1", controller: Controller.createInputController(MotionTracker, "joint_L_thumb2") }, + { jointName: "LeftHandThumb2", controller: Controller.createInputController(MotionTracker, "joint_L_thumb3") }, + { jointName: "LeftHandThumb3", controller: Controller.createInputController(MotionTracker, "joint_L_thumb4") } + ], + [ + { jointName: "LeftHandIndex1", controller: Controller.createInputController(MotionTracker, "joint_L_index2") }, + { jointName: "LeftHandIndex2", controller: Controller.createInputController(MotionTracker, "joint_L_index3") }, + { jointName: "LeftHandIndex3", controller: Controller.createInputController(MotionTracker, "joint_L_index4") } + ], + [ + { jointName: "LeftHandMiddle1", controller: Controller.createInputController(MotionTracker, "joint_L_middle2") }, + { jointName: "LeftHandMiddle2", controller: Controller.createInputController(MotionTracker, "joint_L_middle3") }, + { jointName: "LeftHandMiddle3", controller: Controller.createInputController(MotionTracker, "joint_L_middle4") } + ], + [ + { jointName: "LeftHandRing1", controller: Controller.createInputController(MotionTracker, "joint_L_ring2") }, + { jointName: "LeftHandRing2", controller: Controller.createInputController(MotionTracker, "joint_L_ring3") }, + { jointName: "LeftHandRing3", controller: Controller.createInputController(MotionTracker, "joint_L_ring4") } + ], + [ + { jointName: "LeftHandPinky1", controller: Controller.createInputController(MotionTracker, "joint_L_pinky2") }, + { jointName: "LeftHandPinky2", controller: Controller.createInputController(MotionTracker, "joint_L_pinky3") }, + { jointName: "LeftHandPinky3", controller: Controller.createInputController(MotionTracker, "joint_L_pinky4") } + ] + ]; + fingers[1] = [ + [ + { jointName: "RightHandThumb1", controller: Controller.createInputController(MotionTracker, "joint_R_thumb2") }, + { jointName: "RightHandThumb2", controller: Controller.createInputController(MotionTracker, "joint_R_thumb3") }, + { jointName: "RightHandThumb3", controller: Controller.createInputController(MotionTracker, "joint_R_thumb4") } + ], + [ + { jointName: "RightHandIndex1", controller: Controller.createInputController(MotionTracker, "joint_R_index2") }, + { jointName: "RightHandIndex2", controller: Controller.createInputController(MotionTracker, "joint_R_index3") }, + { jointName: "RightHandIndex3", controller: Controller.createInputController(MotionTracker, "joint_R_index4") } + ], + [ + { jointName: "RightHandMiddle1", controller: Controller.createInputController(MotionTracker, "joint_R_middle2") }, + { jointName: "RightHandMiddle2", controller: Controller.createInputController(MotionTracker, "joint_R_middle3") }, + { jointName: "RightHandMiddle3", controller: Controller.createInputController(MotionTracker, "joint_R_middle4") } + ], + [ + { jointName: "RightHandRing1", controller: Controller.createInputController(MotionTracker, "joint_R_ring2") }, + { jointName: "RightHandRing2", controller: Controller.createInputController(MotionTracker, "joint_R_ring3") }, + { jointName: "RightHandRing3", controller: Controller.createInputController(MotionTracker, "joint_R_ring4") } + ], + [ + { jointName: "RightHandPinky1", controller: Controller.createInputController(MotionTracker, "joint_R_pinky2") }, + { jointName: "RightHandPinky2", controller: Controller.createInputController(MotionTracker, "joint_R_pinky3") }, + { jointName: "RightHandPinky3", controller: Controller.createInputController(MotionTracker, "joint_R_pinky4") } + ] + ]; + + setIsOnHMD(); + + settingsTimer = Script.setInterval(checkSettings, 2000); + + calibrationStatus = UNCALIBRATED; + } + + function moveHands() { + var h, + i, + j, + side, + handOffset, + wristOffset, + handRotation, + locRotation, + cameraOrientation, + inverseAvatarOrientation; + + for (h = 0; h < NUM_HANDS; h += 1) { + side = h === 0 ? -1.0 : 1.0; + + if (hands[h].controller.isActive()) { + + // Calibrate if necessary. + if (!checkCalibration()) { + return; + } + + // Hand position ... + handOffset = hands[h].controller.getAbsTranslation(); + handRotation = hands[h].controller.getAbsRotation(); + + if (isOnHMD) { + + // Adjust to control wrist position if "hand" joint is at wrist ... + if (!hasHandAndWristJoints) { + wristOffset = Vec3.multiplyQbyV(handRotation, handToWristOffset[h]); + handOffset = Vec3.sum(handOffset, wristOffset); + } + + // Hand offset in camera coordinates ... + handOffset = { + x: hands[h].zeroPosition.x - handOffset.x, + y: hands[h].zeroPosition.y - handOffset.z, + z: hands[h].zeroPosition.z + handOffset.y + }; + handOffset.z = -handOffset.z; + + // Hand offset in world coordinates ... + cameraOrientation = Camera.getOrientation(); + handOffset = Vec3.sum(Camera.getPosition(), Vec3.multiplyQbyV(cameraOrientation, handOffset)); + + // Hand offset in avatar coordinates ... + inverseAvatarOrientation = Quat.inverse(MyAvatar.orientation); + handOffset = Vec3.subtract(handOffset, MyAvatar.position); + handOffset = Vec3.multiplyQbyV(inverseAvatarOrientation, handOffset); + handOffset.z = -handOffset.z; + handOffset.x = -handOffset.x; + + // Hand rotation in camera coordinates ... + handRotation = { + x: handRotation.z, + y: handRotation.y, + z: handRotation.x, + w: handRotation.w + }; + + // Hand rotation in avatar coordinates ... + if (h === 0) { + handRotation.x = -handRotation.x; + handRotation = Quat.multiply(Quat.angleAxis(90.0, { x: 1, y: 0, z: 0 }), handRotation); + handRotation = Quat.multiply(Quat.angleAxis(90.0, { x: 0, y: 0, z: 1 }), handRotation); + } else { + handRotation.z = -handRotation.z; + handRotation = Quat.multiply(Quat.angleAxis(90.0, { x: 1, y: 0, z: 0 }), handRotation); + handRotation = Quat.multiply(Quat.angleAxis(-90.0, { x: 0, y: 0, z: 1 }), handRotation); + } + + cameraOrientation.x = -cameraOrientation.x; + cameraOrientation.z = -cameraOrientation.z; + handRotation = Quat.multiply(cameraOrientation, handRotation); + handRotation = Quat.multiply(inverseAvatarOrientation, handRotation); + + } else { + + // Hand offset in camera coordinates ... + handOffset = { + x: -handOffset.x, + y: hands[h].zeroPosition.y + handOffset.y, + z: hands[h].zeroPosition.z - handOffset.z + }; + + // Hand rotation in camera coordinates ... + handRotation = { + x: handRotation.y, + y: handRotation.z, + z: -handRotation.x, + w: handRotation.w + }; + + // Hand rotation in avatar coordinates ... + if (h === 0) { + handRotation = Quat.multiply(Quat.angleAxis(90.0, { x: 0, y: 1, z: 0 }), + handRotation); + handRotation = Quat.multiply(Quat.angleAxis(-90.0, { x: 1, y: 0, z: 0 }), + handRotation); + } else { + handRotation = Quat.multiply(Quat.angleAxis(-90.0, { x: 0, y: 1, z: 0 }), + handRotation); + handRotation = Quat.multiply(Quat.angleAxis(-90.0, { x: 1, y: 0, z: 0 }), + handRotation); + } + } + + // Set hand position and orientation ... + MyAvatar.setJointModelPositionAndOrientation(hands[h].jointName, handOffset, handRotation, true); + + // Set finger joints ... + for (i = 0; i < NUM_FINGERS; i += 1) { + for (j = 0; j < NUM_FINGER_JOINTS; j += 1) { + if (fingers[h][i][j].controller !== null) { + locRotation = fingers[h][i][j].controller.getLocRotation(); + if (i === THUMB) { + locRotation = { + x: side * locRotation.y, + y: side * -locRotation.z, + z: side * -locRotation.x, + w: locRotation.w + }; + } else { + locRotation = { + x: -locRotation.x, + y: -locRotation.z, + z: -locRotation.y, + w: locRotation.w + }; + } + MyAvatar.setJointData(fingers[h][i][j].jointName, locRotation); + } + } + } + + hands[h].inactiveCount = 0; + + } else { + + if (hands[h].inactiveCount < MAX_HAND_INACTIVE_COUNT) { + + hands[h].inactiveCount += 1; + + if (hands[h].inactiveCount === MAX_HAND_INACTIVE_COUNT) { + if (h === 0) { + MyAvatar.clearJointData("LeftHand"); + MyAvatar.clearJointData("LeftForeArm"); + MyAvatar.clearJointData("LeftArm"); + } else { + MyAvatar.clearJointData("RightHand"); + MyAvatar.clearJointData("RightForeArm"); + MyAvatar.clearJointData("RightArm"); + } + } + } + } + } + } + + function tearDown() { + var h, + i, + j; + + Script.clearInterval(settingsTimer); + + for (h = 0; h < NUM_HANDS; h += 1) { + Controller.releaseInputController(hands[h].controller); + Controller.releaseInputController(wrists[h].controller); + for (i = 0; i < NUM_FINGERS; i += 1) { + for (j = 0; j < NUM_FINGER_JOINTS; j += 1) { + if (fingers[h][i][j].controller !== null) { + Controller.releaseInputController(fingers[h][i][j].controller); + } + } + } + } + } + + return { + printSkeletonJointNames: printSkeletonJointNames, + setUp : setUp, + moveHands : moveHands, + tearDown : tearDown + }; +}()); + + +//leapHands.printSkeletonJointNames(); + +leapHands.setUp(); +Script.update.connect(leapHands.moveHands); +Script.scriptEnding.connect(leapHands.tearDown); From 151ddab118c4a95b437711f78a83dbe862cdf27c Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Thu, 18 Dec 2014 00:16:51 +0100 Subject: [PATCH 05/93] make stuff build without RealSense --- interface/src/devices/RealSense.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/interface/src/devices/RealSense.cpp b/interface/src/devices/RealSense.cpp index 2c041a33c9..b09c165e44 100644 --- a/interface/src/devices/RealSense.cpp +++ b/interface/src/devices/RealSense.cpp @@ -23,7 +23,7 @@ const DeviceTracker::Name RealSense::NAME = "RealSense"; // finger in [0..4] : bone in [0..3] a finger phalange // [-1] up the hand branch : bone in [0..1] <=> [ hand, forearm] MotionTracker::Index evalRealSenseJointIndex(bool isRightSide, int finger, int bone) { - +#ifdef HAVE_RSSDK MotionTracker::Index offset = 1 // start after root + (int(isRightSide) * PXCHandData::NUMBER_OF_JOINTS) // then offset for side + PALMROOT_NUM_JOINTS; // then add the arm/forearm/hand chain @@ -34,6 +34,9 @@ MotionTracker::Index evalRealSenseJointIndex(bool isRightSide, int finger, int b // or go back up for the correct root bone return offset - 1 - bone; } +#else + return -1; +#endif // HAVE_RSSDK } // static @@ -62,6 +65,7 @@ RealSense::RealSense() : _active(false), _handData(NULL) { +#ifdef HAVE_RSSDK _session = PXCSession_Create(); initSession(false, NULL); @@ -103,13 +107,17 @@ RealSense::RealSense() : } } } +#endif // HAVE_RSSDK } RealSense::~RealSense() { +#ifdef HAVE_RSSDK _manager->Release(); +#endif // HAVE_RSSDK } void RealSense::initSession(bool playback, QString filename) { +#ifdef HAVE_RSSDK _active = false; _properlyInitialized = false; if (_handData != NULL) { @@ -145,6 +153,7 @@ void RealSense::initSession(bool playback, QString filename) { _config->EnableStabilizer(true); _config->SetTrackingMode(PXCHandData::TRACKING_MODE_FULL_HAND); _config->ApplyChanges(); +#endif // HAVE_RSSDK } #ifdef HAVE_RSSDK @@ -155,7 +164,7 @@ glm::quat quatFromPXCPoint4DF32(const PXCPoint4DF32& basis) { glm::vec3 vec3FromPXCPoint3DF32(const PXCPoint3DF32& vec) { return glm::vec3(-vec.x, vec.y, -vec.z); } -#endif +#endif // HAVE_RSSDK void RealSense::update() { #ifdef HAVE_RSSDK From 8a1618c26934af2645fb3d178e2e42d09d769426 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Thu, 18 Dec 2014 00:22:59 +0100 Subject: [PATCH 06/93] missed one. --- interface/src/devices/RealSense.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/devices/RealSense.cpp b/interface/src/devices/RealSense.cpp index b09c165e44..5edb3aacee 100644 --- a/interface/src/devices/RealSense.cpp +++ b/interface/src/devices/RealSense.cpp @@ -62,10 +62,10 @@ RealSense* RealSense::getInstance() { RealSense::RealSense() : MotionTracker(), - _active(false), - _handData(NULL) + _active(false) { #ifdef HAVE_RSSDK + _handData = NULL; _session = PXCSession_Create(); initSession(false, NULL); From 95b0f2515b327e38cbd6d0dcb18b0b8a77d8b635 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Thu, 18 Dec 2014 00:32:11 +0100 Subject: [PATCH 07/93] this doesn't make `real sense` to me, perhaps this helps --- interface/src/devices/RealSense.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/devices/RealSense.cpp b/interface/src/devices/RealSense.cpp index 5edb3aacee..c2591772d0 100644 --- a/interface/src/devices/RealSense.cpp +++ b/interface/src/devices/RealSense.cpp @@ -239,7 +239,7 @@ void RealSense::update() { } void RealSense::loadRSSDKFile() { - QString fileNameString = QFileDialog::getOpenFileName(Application::getInstance()->getGLWidget(), tr("Open RSSDK clip"), + QString fileNameString = QFileDialog::getOpenFileName(Application::getInstance()->getWindow(), tr("Open RSSDK clip"), NULL, tr("RSSDK Recordings (*.rssdk)")); if (!fileNameString.isEmpty()) { From 835e14a7b2190c807b95782939cf642378e91434 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Thu, 18 Dec 2014 00:52:31 +0100 Subject: [PATCH 08/93] This might solve it? --- interface/src/devices/RealSense.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/devices/RealSense.cpp b/interface/src/devices/RealSense.cpp index c2591772d0..aea7a50779 100644 --- a/interface/src/devices/RealSense.cpp +++ b/interface/src/devices/RealSense.cpp @@ -239,8 +239,9 @@ void RealSense::update() { } void RealSense::loadRSSDKFile() { + QString locationDir(QStandardPaths::displayName(QStandardPaths::DesktopLocation)); QString fileNameString = QFileDialog::getOpenFileName(Application::getInstance()->getWindow(), tr("Open RSSDK clip"), - NULL, + locationDir, tr("RSSDK Recordings (*.rssdk)")); if (!fileNameString.isEmpty()) { initSession(true, fileNameString); From 2884de1fe4f6493a888ce7601e7f97994fbe8b0d Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Thu, 18 Dec 2014 01:18:05 +0100 Subject: [PATCH 09/93] include fix --- interface/src/devices/RealSense.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/devices/RealSense.cpp b/interface/src/devices/RealSense.cpp index aea7a50779..f082f96949 100644 --- a/interface/src/devices/RealSense.cpp +++ b/interface/src/devices/RealSense.cpp @@ -9,6 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "RealSense.h" +#include "MainWindow.h" #include "Menu.h" #include "SharedUtil.h" From f67df35f03f5597146da55d06ae917c7bdc9216c Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Fri, 19 Dec 2014 16:36:06 +0100 Subject: [PATCH 10/93] rssdk instructions --- interface/external/rssdk/readme.txt | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 interface/external/rssdk/readme.txt diff --git a/interface/external/rssdk/readme.txt b/interface/external/rssdk/readme.txt new file mode 100644 index 0000000000..fe2246e32a --- /dev/null +++ b/interface/external/rssdk/readme.txt @@ -0,0 +1,9 @@ + +Instructions for adding the Intel Realsense (RSSDK) to Interface +Thijs Wenker, December 19, 2014 + +This is Windows only for now. + +1. Download the SDK at https://software.intel.com/en-us/intel-realsense-sdk/download + +2. Copy the `lib` and `include` folder inside this directory \ No newline at end of file From d84a65a5f9a0bc2f373e047e6956dc7f7cf48ee1 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Sat, 10 Jan 2015 01:29:06 +0100 Subject: [PATCH 11/93] running scripts list -> treeview initial --- interface/src/ScriptsModel.cpp | 113 +++++++++++++++++----- interface/src/ScriptsModel.h | 51 ++++++++-- interface/src/ui/RunningScriptsWidget.cpp | 10 +- interface/ui/runningScriptsWidget.ui | 31 +++++- 4 files changed, 164 insertions(+), 41 deletions(-) diff --git a/interface/src/ScriptsModel.cpp b/interface/src/ScriptsModel.cpp index 41ce16c229..d178397fc2 100644 --- a/interface/src/ScriptsModel.cpp +++ b/interface/src/ScriptsModel.cpp @@ -11,6 +11,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include #include #include #include @@ -31,18 +32,30 @@ static const QString IS_TRUNCATED_NAME = "IsTruncated"; static const QString CONTAINER_NAME = "Contents"; static const QString KEY_NAME = "Key"; -ScriptItem::ScriptItem(const QString& filename, const QString& fullPath) : +TreeNodeBase::TreeNodeBase(TreeNodeFolder* parent, TreeNodeType type) : + _parent(parent), + _type(type) { +}; + +TreeNodeScript::TreeNodeScript(const QString& filename, const QString& fullPath, ScriptOrigin origin) : + TreeNodeBase(NULL, TREE_NODE_TYPE_SCRIPT), _filename(filename), - _fullPath(fullPath) { + _fullPath(fullPath), + _origin(origin) +{ +}; + +TreeNodeFolder::TreeNodeFolder(const QString& foldername, TreeNodeFolder* parent) : + TreeNodeBase(parent, TREE_NODE_TYPE_FOLDER), + _foldername(foldername) { }; ScriptsModel::ScriptsModel(QObject* parent) : - QAbstractListModel(parent), + QAbstractItemModel(parent), _loadingScripts(false), _localDirectory(), _fsWatcher(), - _localFiles(), - _remoteFiles() + _treeNodes() { _localDirectory.setFilter(QDir::Files | QDir::Readable); @@ -57,23 +70,31 @@ ScriptsModel::ScriptsModel(QObject* parent) : reloadRemoteFiles(); } +QModelIndex ScriptsModel::index(int row, int column, const QModelIndex& parent) const { + return QModelIndex(); +} + +QModelIndex ScriptsModel::parent(const QModelIndex& child) const { + return QModelIndex(); +} + QVariant ScriptsModel::data(const QModelIndex& index, int role) const { - const QList* files = NULL; + /*const QList* files = NULL; int row = 0; bool isLocal = index.row() < _localFiles.size(); - if (isLocal) { - files = &_localFiles; - row = index.row(); - } else { - files = &_remoteFiles; - row = index.row() - _localFiles.size(); - } + if (isLocal) { + files = &_localFiles; + row = index.row(); + } else { + files = &_remoteFiles; + row = index.row() - _localFiles.size(); + } if (role == Qt::DisplayRole) { return QVariant((*files)[row]->getFilename() + (isLocal ? " (local)" : "")); } else if (role == ScriptPath) { return QVariant((*files)[row]->getFullPath()); - } + }*/ return QVariant(); } @@ -81,9 +102,14 @@ int ScriptsModel::rowCount(const QModelIndex& parent) const { if (parent.isValid()) { return 0; } - return _localFiles.length() + _remoteFiles.length(); + return 0;// _localFiles.length() + _remoteFiles.length(); } +int ScriptsModel::columnCount(const QModelIndex& parent) const { + return 1; +} + + void ScriptsModel::updateScriptsLocation(const QString& newPath) { _fsWatcher.removePath(_localDirectory.absolutePath()); @@ -93,7 +119,7 @@ void ScriptsModel::updateScriptsLocation(const QString& newPath) { if (!_localDirectory.absolutePath().isEmpty()) { _fsWatcher.addPath(_localDirectory.absolutePath()); } - } + } reloadLocalFiles(); } @@ -101,8 +127,12 @@ void ScriptsModel::updateScriptsLocation(const QString& newPath) { void ScriptsModel::reloadRemoteFiles() { if (!_loadingScripts) { _loadingScripts = true; - while (!_remoteFiles.isEmpty()) { - delete _remoteFiles.takeFirst(); + for (int i = _treeNodes.size() - 1; i >= 0; i--) { + TreeNodeBase* node = _treeNodes.at(i); + if (typeid(*node) == typeid(TreeNodeScript) && static_cast(node)->getOrigin() == SCRIPT_ORIGIN_REMOTE) { + delete node; + _treeNodes.removeAt(i); + } } requestRemoteFiles(); } @@ -121,7 +151,6 @@ void ScriptsModel::requestRemoteFiles(QString marker) { QNetworkRequest request(url); QNetworkReply* reply = networkAccessManager.get(request); connect(reply, SIGNAL(finished()), SLOT(downloadFinished())); - } void ScriptsModel::downloadFinished() { @@ -170,7 +199,7 @@ bool ScriptsModel::parseXML(QByteArray xmlFile) { xml.readNext(); lastKey = xml.text().toString(); if (jsRegex.exactMatch(xml.text().toString())) { - _remoteFiles.append(new ScriptItem(lastKey.mid(MODELS_LOCATION.length()), S3_URL + "/" + lastKey)); + _treeNodes.append(new TreeNodeScript(lastKey.mid(MODELS_LOCATION.length()), S3_URL + "/" + lastKey, SCRIPT_ORIGIN_REMOTE)); } } xml.readNext(); @@ -178,7 +207,7 @@ bool ScriptsModel::parseXML(QByteArray xmlFile) { } xml.readNext(); } - + rebuildTree(); endResetModel(); // Error handling @@ -198,8 +227,15 @@ bool ScriptsModel::parseXML(QByteArray xmlFile) { void ScriptsModel::reloadLocalFiles() { beginResetModel(); - while (!_localFiles.isEmpty()) { - delete _localFiles.takeFirst(); + for (int i = _treeNodes.size() - 1; i >= 0; i--) { + TreeNodeBase* node = _treeNodes.at(i); + qDebug() << "deleting local " << i << " " << typeid(*node).name(); + if (node->getType() == TREE_NODE_TYPE_SCRIPT && + static_cast(node)->getOrigin() == SCRIPT_ORIGIN_LOCAL) + { + delete node; + _treeNodes.removeAt(i); + } } _localDirectory.refresh(); @@ -207,8 +243,35 @@ void ScriptsModel::reloadLocalFiles() { const QFileInfoList localFiles = _localDirectory.entryInfoList(); for (int i = 0; i < localFiles.size(); i++) { QFileInfo file = localFiles[i]; - _localFiles.append(new ScriptItem(file.fileName(), file.absoluteFilePath())); + _treeNodes.append(new TreeNodeScript(file.fileName(), file.absoluteFilePath(), SCRIPT_ORIGIN_LOCAL)); } - + rebuildTree(); endResetModel(); } + +void ScriptsModel::rebuildTree() { + for (int i = _treeNodes.size() - 1; i >= 0; i--) { + + if (_treeNodes.at(i)->getType() == TREE_NODE_TYPE_FOLDER) { + delete _treeNodes.at(i); + _treeNodes.removeAt(i); + } + } + QHash folders; + for (int i = 0; i < _treeNodes.size(); i++) { + TreeNodeBase* node = _treeNodes.at(i); + qDebug() << "blup" << i << typeid(*node).name(); + if (typeid(*node) == typeid(TreeNodeScript)) { + TreeNodeScript* script = static_cast(node); + TreeNodeFolder* parent = NULL; + QString hash; + QStringList pathList = script->getFilename().split(tr("/")); + QStringList::const_iterator pathIterator; + for (pathIterator = pathList.constBegin(); pathIterator != pathList.constEnd(); ++pathIterator) { + hash.append("/" + *pathIterator); + qDebug() << hash; + } + } + } + folders.clear(); +} diff --git a/interface/src/ScriptsModel.h b/interface/src/ScriptsModel.h index ca72a8d8f4..bb4883e399 100644 --- a/interface/src/ScriptsModel.h +++ b/interface/src/ScriptsModel.h @@ -12,30 +12,67 @@ #ifndef hifi_ScriptsModel_h #define hifi_ScriptsModel_h -#include +#include #include #include #include -class ScriptItem { +class TreeNodeFolder; + +enum ScriptOrigin { + SCRIPT_ORIGIN_LOCAL, + SCRIPT_ORIGIN_REMOTE +}; + +enum TreeNodeType { + TREE_NODE_TYPE_SCRIPT, + TREE_NODE_TYPE_FOLDER +}; + +class TreeNodeBase { public: - ScriptItem(const QString& filename, const QString& fullPath); + const TreeNodeFolder* getParent() { return _parent; } + void setParent(TreeNodeFolder* parent) { _parent = parent; } + TreeNodeType getType() { return _type; } + +private: + TreeNodeFolder* _parent; + TreeNodeType _type; + +protected: + TreeNodeBase(TreeNodeFolder* parent, TreeNodeType type); +}; + +class TreeNodeScript : public TreeNodeBase { +public: + TreeNodeScript(const QString& filename, const QString& fullPath, ScriptOrigin origin); const QString& getFilename() { return _filename; }; const QString& getFullPath() { return _fullPath; }; + const ScriptOrigin getOrigin() { return _origin; }; private: QString _filename; QString _fullPath; + ScriptOrigin _origin; }; -class ScriptsModel : public QAbstractListModel { +class TreeNodeFolder : public TreeNodeBase { +public: + TreeNodeFolder(const QString& foldername, TreeNodeFolder* parent); +private: + QString _foldername; +}; + +class ScriptsModel : public QAbstractItemModel { Q_OBJECT public: ScriptsModel(QObject* parent = NULL); - + QModelIndex index(int row, int column, const QModelIndex& parent) const; + QModelIndex parent(const QModelIndex& child) const; virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; virtual int rowCount(const QModelIndex& parent = QModelIndex()) const; + virtual int columnCount(const QModelIndex& parent = QModelIndex()) const; enum Role { ScriptPath = Qt::UserRole, @@ -50,13 +87,13 @@ protected slots: protected: void requestRemoteFiles(QString marker = QString()); bool parseXML(QByteArray xmlFile); + void rebuildTree(); private: bool _loadingScripts; QDir _localDirectory; QFileSystemWatcher _fsWatcher; - QList _localFiles; - QList _remoteFiles; + QList _treeNodes; }; #endif // hifi_ScriptsModel_h diff --git a/interface/src/ui/RunningScriptsWidget.cpp b/interface/src/ui/RunningScriptsWidget.cpp index 57c0532777..f56c6e32af 100644 --- a/interface/src/ui/RunningScriptsWidget.cpp +++ b/interface/src/ui/RunningScriptsWidget.cpp @@ -50,10 +50,10 @@ RunningScriptsWidget::RunningScriptsWidget(QWidget* parent) : _proxyModel.setSourceModel(&_scriptsModel); _proxyModel.sort(0, Qt::AscendingOrder); _proxyModel.setDynamicSortFilter(true); - ui->scriptListView->setModel(&_proxyModel); + ui->scriptTreeView->setModel(&_proxyModel); connect(ui->filterLineEdit, &QLineEdit::textChanged, this, &RunningScriptsWidget::updateFileFilter); - connect(ui->scriptListView, &QListView::doubleClicked, this, &RunningScriptsWidget::loadScriptFromList); + connect(ui->scriptTreeView, &QTreeView::doubleClicked, this, &RunningScriptsWidget::loadScriptFromList); connect(ui->reloadAllButton, &QPushButton::clicked, Application::getInstance(), &Application::reloadAllScripts); @@ -80,7 +80,7 @@ void RunningScriptsWidget::loadScriptFromList(const QModelIndex& index) { } void RunningScriptsWidget::loadSelectedScript() { - QModelIndex selectedIndex = ui->scriptListView->currentIndex(); + QModelIndex selectedIndex = ui->scriptTreeView->currentIndex(); if (selectedIndex.isValid()) { loadScriptFromList(selectedIndex); } @@ -166,7 +166,7 @@ void RunningScriptsWidget::showEvent(QShowEvent* event) { void RunningScriptsWidget::selectFirstInList() { if (_proxyModel.rowCount() > 0) { - ui->scriptListView->setCurrentIndex(_proxyModel.index(0, 0)); + ui->scriptTreeView->setCurrentIndex(_proxyModel.index(0, 0)); } } @@ -177,7 +177,7 @@ bool RunningScriptsWidget::eventFilter(QObject* sender, QEvent* event) { } QKeyEvent* keyEvent = static_cast(event); if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) { - QModelIndex selectedIndex = ui->scriptListView->currentIndex(); + QModelIndex selectedIndex = ui->scriptTreeView->currentIndex(); if (selectedIndex.isValid()) { loadScriptFromList(selectedIndex); } diff --git a/interface/ui/runningScriptsWidget.ui b/interface/ui/runningScriptsWidget.ui index b70200e9f2..203db35d2d 100644 --- a/interface/ui/runningScriptsWidget.ui +++ b/interface/ui/runningScriptsWidget.ui @@ -245,8 +245,8 @@ font: bold 16px; 0 0 - 328 - 18 + 334 + 20 @@ -390,10 +390,27 @@ font: bold 16px; + + + + color: #0e7077; font: bold 14px; + + + Load script + + + + + + + from URL + + + - Load script + from Disk @@ -429,7 +446,7 @@ font: bold 16px; - + 0 @@ -442,6 +459,12 @@ font: bold 16px; Qt::ScrollBarAlwaysOff + + true + + + true + From 8feb51013ba266fec4b80e10b4dcfded6ff84845 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Mon, 12 Jan 2015 00:41:38 +0100 Subject: [PATCH 12/93] running script window treeview fully works --- interface/src/ScriptsModel.cpp | 106 ++++++++++++++-------- interface/src/ScriptsModel.h | 23 ++--- interface/src/ScriptsModelFilter.cpp | 44 +++++++++ interface/src/ScriptsModelFilter.h | 27 ++++++ interface/src/ui/RunningScriptsWidget.cpp | 20 ++-- interface/src/ui/RunningScriptsWidget.h | 3 +- 6 files changed, 161 insertions(+), 62 deletions(-) create mode 100644 interface/src/ScriptsModelFilter.cpp create mode 100644 interface/src/ScriptsModelFilter.h diff --git a/interface/src/ScriptsModel.cpp b/interface/src/ScriptsModel.cpp index d178397fc2..0c711cd940 100644 --- a/interface/src/ScriptsModel.cpp +++ b/interface/src/ScriptsModel.cpp @@ -11,7 +11,6 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#include #include #include #include @@ -32,22 +31,21 @@ static const QString IS_TRUNCATED_NAME = "IsTruncated"; static const QString CONTAINER_NAME = "Contents"; static const QString KEY_NAME = "Key"; -TreeNodeBase::TreeNodeBase(TreeNodeFolder* parent, TreeNodeType type) : +TreeNodeBase::TreeNodeBase(TreeNodeFolder* parent, const QString& name, TreeNodeType type) : _parent(parent), + _name(name), _type(type) { }; -TreeNodeScript::TreeNodeScript(const QString& filename, const QString& fullPath, ScriptOrigin origin) : - TreeNodeBase(NULL, TREE_NODE_TYPE_SCRIPT), - _filename(filename), +TreeNodeScript::TreeNodeScript(const QString& localPath, const QString& fullPath, ScriptOrigin origin) : + TreeNodeBase(NULL, localPath.split("/").last(), TREE_NODE_TYPE_SCRIPT), + _localPath(localPath), _fullPath(fullPath), - _origin(origin) -{ + _origin(origin) { }; TreeNodeFolder::TreeNodeFolder(const QString& foldername, TreeNodeFolder* parent) : - TreeNodeBase(parent, TREE_NODE_TYPE_FOLDER), - _foldername(foldername) { + TreeNodeBase(parent, foldername, TREE_NODE_TYPE_FOLDER) { }; ScriptsModel::ScriptsModel(QObject* parent) : @@ -57,7 +55,6 @@ ScriptsModel::ScriptsModel(QObject* parent) : _fsWatcher(), _treeNodes() { - _localDirectory.setFilter(QDir::Files | QDir::Readable); _localDirectory.setNameFilters(QStringList("*.js")); @@ -70,46 +67,56 @@ ScriptsModel::ScriptsModel(QObject* parent) : reloadRemoteFiles(); } +TreeNodeBase* ScriptsModel::getTreeNodeFromIndex(const QModelIndex& index) const { + if (index.isValid()) { + return static_cast(index.internalPointer()); + } + return NULL; +} + QModelIndex ScriptsModel::index(int row, int column, const QModelIndex& parent) const { - return QModelIndex(); + if (row < 0 || column < 0) { + return QModelIndex(); + } + return createIndex(row, column, getFolderNodes(static_cast(getTreeNodeFromIndex(parent))).at(row)); } QModelIndex ScriptsModel::parent(const QModelIndex& child) const { - return QModelIndex(); + TreeNodeFolder* parent = (static_cast(child.internalPointer()))->getParent(); + if (!parent) { + return QModelIndex(); + } + TreeNodeFolder* grandParent = parent->getParent(); + int row = getFolderNodes(grandParent).indexOf(parent); + return createIndex(row, 0, parent); } QVariant ScriptsModel::data(const QModelIndex& index, int role) const { - /*const QList* files = NULL; - int row = 0; - bool isLocal = index.row() < _localFiles.size(); - if (isLocal) { - files = &_localFiles; - row = index.row(); - } else { - files = &_remoteFiles; - row = index.row() - _localFiles.size(); + TreeNodeBase* node = getTreeNodeFromIndex(index); + if (node->getType() == TREE_NODE_TYPE_SCRIPT) { + TreeNodeScript* script = static_cast(node); + if (role == Qt::DisplayRole) { + return QVariant(script->getName() + (script->getOrigin() == SCRIPT_ORIGIN_LOCAL ? " (local)" : "")); + } else if (role == ScriptPath) { + return QVariant(script->getFullPath()); + } + } else if (node->getType() == TREE_NODE_TYPE_FOLDER) { + TreeNodeFolder* folder = static_cast(node); + if (role == Qt::DisplayRole) { + return QVariant(folder->getName()); + } } - - if (role == Qt::DisplayRole) { - return QVariant((*files)[row]->getFilename() + (isLocal ? " (local)" : "")); - } else if (role == ScriptPath) { - return QVariant((*files)[row]->getFullPath()); - }*/ return QVariant(); } int ScriptsModel::rowCount(const QModelIndex& parent) const { - if (parent.isValid()) { - return 0; - } - return 0;// _localFiles.length() + _remoteFiles.length(); + return getFolderNodes(static_cast(getTreeNodeFromIndex(parent))).count(); } int ScriptsModel::columnCount(const QModelIndex& parent) const { return 1; } - void ScriptsModel::updateScriptsLocation(const QString& newPath) { _fsWatcher.removePath(_localDirectory.absolutePath()); @@ -129,7 +136,9 @@ void ScriptsModel::reloadRemoteFiles() { _loadingScripts = true; for (int i = _treeNodes.size() - 1; i >= 0; i--) { TreeNodeBase* node = _treeNodes.at(i); - if (typeid(*node) == typeid(TreeNodeScript) && static_cast(node)->getOrigin() == SCRIPT_ORIGIN_REMOTE) { + if (node->getType() == TREE_NODE_TYPE_SCRIPT && + static_cast(node)->getOrigin() == SCRIPT_ORIGIN_REMOTE) + { delete node; _treeNodes.removeAt(i); } @@ -229,7 +238,6 @@ void ScriptsModel::reloadLocalFiles() { for (int i = _treeNodes.size() - 1; i >= 0; i--) { TreeNodeBase* node = _treeNodes.at(i); - qDebug() << "deleting local " << i << " " << typeid(*node).name(); if (node->getType() == TREE_NODE_TYPE_SCRIPT && static_cast(node)->getOrigin() == SCRIPT_ORIGIN_LOCAL) { @@ -251,7 +259,6 @@ void ScriptsModel::reloadLocalFiles() { void ScriptsModel::rebuildTree() { for (int i = _treeNodes.size() - 1; i >= 0; i--) { - if (_treeNodes.at(i)->getType() == TREE_NODE_TYPE_FOLDER) { delete _treeNodes.at(i); _treeNodes.removeAt(i); @@ -260,18 +267,37 @@ void ScriptsModel::rebuildTree() { QHash folders; for (int i = 0; i < _treeNodes.size(); i++) { TreeNodeBase* node = _treeNodes.at(i); - qDebug() << "blup" << i << typeid(*node).name(); - if (typeid(*node) == typeid(TreeNodeScript)) { + if (node->getType() == TREE_NODE_TYPE_SCRIPT) { TreeNodeScript* script = static_cast(node); TreeNodeFolder* parent = NULL; QString hash; - QStringList pathList = script->getFilename().split(tr("/")); + QStringList pathList = script->getLocalPath().split(tr("/")); + pathList.removeLast(); QStringList::const_iterator pathIterator; for (pathIterator = pathList.constBegin(); pathIterator != pathList.constEnd(); ++pathIterator) { - hash.append("/" + *pathIterator); - qDebug() << hash; + hash.append(*pathIterator + "/"); + if (!folders.contains(hash)) { + folders[hash] = new TreeNodeFolder(*pathIterator, parent); + } + parent = folders[hash]; } + script->setParent(parent); } } + QHash::const_iterator folderIterator; + for (folderIterator = folders.constBegin(); folderIterator != folders.constEnd(); ++folderIterator) { + _treeNodes.append(*folderIterator); + } folders.clear(); } + +QList ScriptsModel::getFolderNodes(TreeNodeFolder* parent) const { + QList result; + for (int i = 0; i < _treeNodes.size(); i++) { + TreeNodeBase* node = _treeNodes.at(i); + if (node->getParent() == parent) { + result.append(node); + } + } + return result; +} diff --git a/interface/src/ScriptsModel.h b/interface/src/ScriptsModel.h index bb4883e399..549f87c0d7 100644 --- a/interface/src/ScriptsModel.h +++ b/interface/src/ScriptsModel.h @@ -31,28 +31,29 @@ enum TreeNodeType { class TreeNodeBase { public: - const TreeNodeFolder* getParent() { return _parent; } + TreeNodeFolder* getParent() const { return _parent; } void setParent(TreeNodeFolder* parent) { _parent = parent; } TreeNodeType getType() { return _type; } + const QString& getName() { return _name; }; private: TreeNodeFolder* _parent; TreeNodeType _type; protected: - TreeNodeBase(TreeNodeFolder* parent, TreeNodeType type); + QString _name; + TreeNodeBase(TreeNodeFolder* parent, const QString& name, TreeNodeType type); }; class TreeNodeScript : public TreeNodeBase { public: - TreeNodeScript(const QString& filename, const QString& fullPath, ScriptOrigin origin); - - const QString& getFilename() { return _filename; }; + TreeNodeScript(const QString& localPath, const QString& fullPath, ScriptOrigin origin); + const QString& getLocalPath() { return _localPath; } const QString& getFullPath() { return _fullPath; }; const ScriptOrigin getOrigin() { return _origin; }; private: - QString _filename; + QString _localPath; QString _fullPath; ScriptOrigin _origin; }; @@ -60,8 +61,6 @@ private: class TreeNodeFolder : public TreeNodeBase { public: TreeNodeFolder(const QString& foldername, TreeNodeFolder* parent); -private: - QString _foldername; }; class ScriptsModel : public QAbstractItemModel { @@ -70,9 +69,11 @@ public: ScriptsModel(QObject* parent = NULL); QModelIndex index(int row, int column, const QModelIndex& parent) const; QModelIndex parent(const QModelIndex& child) const; - virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; - virtual int rowCount(const QModelIndex& parent = QModelIndex()) const; - virtual int columnCount(const QModelIndex& parent = QModelIndex()) const; + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; + int rowCount(const QModelIndex& parent = QModelIndex()) const; + int columnCount(const QModelIndex& parent = QModelIndex()) const; + TreeNodeBase* getTreeNodeFromIndex(const QModelIndex& index) const; + QList getFolderNodes(TreeNodeFolder* parent) const; enum Role { ScriptPath = Qt::UserRole, diff --git a/interface/src/ScriptsModelFilter.cpp b/interface/src/ScriptsModelFilter.cpp new file mode 100644 index 0000000000..1879e547c0 --- /dev/null +++ b/interface/src/ScriptsModelFilter.cpp @@ -0,0 +1,44 @@ +// +// ScriptsModelFilter.cpp +// interface/src +// +// Created by Thijs Wenker on 01/11/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 "ScriptsModelFilter.h" + +ScriptsModelFilter::ScriptsModelFilter(QObject *parent) : + QSortFilterProxyModel(parent) { +} + +bool ScriptsModelFilter::lessThan(const QModelIndex& left, const QModelIndex& right) const { + ScriptsModel* scriptsModel = static_cast(sourceModel()); + TreeNodeBase* leftNode = scriptsModel->getTreeNodeFromIndex(left); + TreeNodeBase* rightNode = scriptsModel->getTreeNodeFromIndex(right); + if (leftNode->getType() != rightNode->getType()) { + return leftNode->getType() == TREE_NODE_TYPE_FOLDER; + } + return leftNode->getName() < rightNode->getName(); +} + +bool ScriptsModelFilter::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const { + if (!filterRegExp().isEmpty()) { + ScriptsModel* scriptsModel = static_cast(sourceModel()); + TreeNodeBase* node = scriptsModel->getFolderNodes( + static_cast(scriptsModel->getTreeNodeFromIndex(sourceParent))).at(sourceRow); + QModelIndex sourceIndex = sourceModel()->index(sourceRow, this->filterKeyColumn(), sourceParent); + if (node->getType() == TREE_NODE_TYPE_FOLDER) { + int rows = scriptsModel->rowCount(sourceIndex); + for (int i = 0; i < rows; i++) { + if (filterAcceptsRow(i, sourceIndex)) { + return true; + } + } + } + } + return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent); +} diff --git a/interface/src/ScriptsModelFilter.h b/interface/src/ScriptsModelFilter.h new file mode 100644 index 0000000000..7b7cdd974e --- /dev/null +++ b/interface/src/ScriptsModelFilter.h @@ -0,0 +1,27 @@ +// +// ScriptsModelFilter.h +// interface/src +// +// Created by Thijs Wenker on 01/11/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_ScriptsModelFilter_h +#define hifi_ScriptsModelFilter_h + +#include "ScriptsModel.h" +#include + +class ScriptsModelFilter : public QSortFilterProxyModel { + Q_OBJECT +public: + ScriptsModelFilter(QObject *parent = NULL); +protected: + bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const; + bool lessThan(const QModelIndex& left, const QModelIndex& right) const; +}; + +#endif // hifi_ScriptsModelFilter_h diff --git a/interface/src/ui/RunningScriptsWidget.cpp b/interface/src/ui/RunningScriptsWidget.cpp index f56c6e32af..d577859ebf 100644 --- a/interface/src/ui/RunningScriptsWidget.cpp +++ b/interface/src/ui/RunningScriptsWidget.cpp @@ -33,7 +33,7 @@ RunningScriptsWidget::RunningScriptsWidget(QWidget* parent) : Qt::WindowCloseButtonHint), ui(new Ui::RunningScriptsWidget), _signalMapper(this), - _proxyModel(this), + _scriptsModelFilter(this), _scriptsModel(this) { ui->setupUi(this); @@ -41,16 +41,16 @@ RunningScriptsWidget::RunningScriptsWidget(QWidget* parent) : ui->filterLineEdit->installEventFilter(this); - connect(&_proxyModel, &QSortFilterProxyModel::modelReset, + connect(&_scriptsModelFilter, &QSortFilterProxyModel::modelReset, this, &RunningScriptsWidget::selectFirstInList); QString shortcutText = Menu::getInstance()->getActionForOption(MenuOption::ReloadAllScripts)->shortcut().toString(QKeySequence::NativeText); ui->tipLabel->setText("Tip: Use " + shortcutText + " to reload all scripts."); - _proxyModel.setSourceModel(&_scriptsModel); - _proxyModel.sort(0, Qt::AscendingOrder); - _proxyModel.setDynamicSortFilter(true); - ui->scriptTreeView->setModel(&_proxyModel); + _scriptsModelFilter.setSourceModel(&_scriptsModel); + _scriptsModelFilter.sort(0, Qt::AscendingOrder); + _scriptsModelFilter.setDynamicSortFilter(true); + ui->scriptTreeView->setModel(&_scriptsModelFilter); connect(ui->filterLineEdit, &QLineEdit::textChanged, this, &RunningScriptsWidget::updateFileFilter); connect(ui->scriptTreeView, &QTreeView::doubleClicked, this, &RunningScriptsWidget::loadScriptFromList); @@ -70,12 +70,12 @@ RunningScriptsWidget::~RunningScriptsWidget() { void RunningScriptsWidget::updateFileFilter(const QString& filter) { QRegExp regex("^.*" + QRegExp::escape(filter) + ".*$", Qt::CaseInsensitive); - _proxyModel.setFilterRegExp(regex); + _scriptsModelFilter.setFilterRegExp(regex); selectFirstInList(); } void RunningScriptsWidget::loadScriptFromList(const QModelIndex& index) { - QVariant scriptFile = _proxyModel.data(index, ScriptsModel::ScriptPath); + QVariant scriptFile = _scriptsModelFilter.data(index, ScriptsModel::ScriptPath); Application::getInstance()->loadScript(scriptFile.toString()); } @@ -165,8 +165,8 @@ void RunningScriptsWidget::showEvent(QShowEvent* event) { } void RunningScriptsWidget::selectFirstInList() { - if (_proxyModel.rowCount() > 0) { - ui->scriptTreeView->setCurrentIndex(_proxyModel.index(0, 0)); + if (_scriptsModelFilter.rowCount() > 0) { + ui->scriptTreeView->setCurrentIndex(_scriptsModelFilter.index(0, 0)); } } diff --git a/interface/src/ui/RunningScriptsWidget.h b/interface/src/ui/RunningScriptsWidget.h index 69833a890b..3ec5590dee 100644 --- a/interface/src/ui/RunningScriptsWidget.h +++ b/interface/src/ui/RunningScriptsWidget.h @@ -18,6 +18,7 @@ #include #include "ScriptsModel.h" +#include "ScriptsModelFilter.h" #include "ScriptsTableWidget.h" namespace Ui { @@ -54,7 +55,7 @@ private slots: private: Ui::RunningScriptsWidget* ui; QSignalMapper _signalMapper; - QSortFilterProxyModel _proxyModel; + ScriptsModelFilter _scriptsModelFilter; ScriptsModel _scriptsModel; ScriptsTableWidget* _recentlyLoadedScriptsTable; QStringList _recentlyLoadedScripts; From e4fd027d15426ac01bf82b4467231a03daf765bf Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Mon, 12 Jan 2015 00:49:41 +0100 Subject: [PATCH 13/93] "load script from URL" button in Running scripts window --- interface/src/ui/RunningScriptsWidget.cpp | 4 +++- interface/ui/runningScriptsWidget.ui | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/interface/src/ui/RunningScriptsWidget.cpp b/interface/src/ui/RunningScriptsWidget.cpp index d577859ebf..46c8f90ff6 100644 --- a/interface/src/ui/RunningScriptsWidget.cpp +++ b/interface/src/ui/RunningScriptsWidget.cpp @@ -59,8 +59,10 @@ RunningScriptsWidget::RunningScriptsWidget(QWidget* parent) : Application::getInstance(), &Application::reloadAllScripts); connect(ui->stopAllButton, &QPushButton::clicked, this, &RunningScriptsWidget::allScriptsStopped); - connect(ui->loadScriptButton, &QPushButton::clicked, + connect(ui->loadScriptFromDiskButton, &QPushButton::clicked, Application::getInstance(), &Application::loadDialog); + connect(ui->loadScriptFromURLButton, &QPushButton::clicked, + Application::getInstance(), &Application::loadScriptURLDialog); connect(&_signalMapper, SIGNAL(mapped(QString)), Application::getInstance(), SLOT(stopScript(const QString&))); } diff --git a/interface/ui/runningScriptsWidget.ui b/interface/ui/runningScriptsWidget.ui index 203db35d2d..ea53e72e15 100644 --- a/interface/ui/runningScriptsWidget.ui +++ b/interface/ui/runningScriptsWidget.ui @@ -401,14 +401,14 @@ font: bold 16px; - + from URL - + from Disk @@ -463,7 +463,7 @@ font: bold 16px; true - true + false From 8c7099a0bb44abbac5cf9e5aad20a1260353ee66 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Tue, 13 Jan 2015 01:09:28 +0100 Subject: [PATCH 14/93] changed "Load Scripts" label to be better understandable --- interface/ui/runningScriptsWidget.ui | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/interface/ui/runningScriptsWidget.ui b/interface/ui/runningScriptsWidget.ui index ea53e72e15..3d7db5064a 100644 --- a/interface/ui/runningScriptsWidget.ui +++ b/interface/ui/runningScriptsWidget.ui @@ -373,7 +373,7 @@ font: bold 16px; font: bold 16px; - Scripts + Load Scripts @@ -390,16 +390,6 @@ font: bold 16px; - - - - color: #0e7077; font: bold 14px; - - - Load script - - - From fc698a8525a35f9059023d8fcad66f2d4f0a6c12 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 12 Jan 2015 18:51:26 -0800 Subject: [PATCH 15/93] first step factorizing the packDeferredFragment --- libraries/render-utils/src/DeferredBuffer.slh | 1 - .../render-utils/src/DeferredBufferWrite.slh | 28 +++++++++++++++++++ libraries/render-utils/src/model.slf | 11 ++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100755 libraries/render-utils/src/DeferredBufferWrite.slh diff --git a/libraries/render-utils/src/DeferredBuffer.slh b/libraries/render-utils/src/DeferredBuffer.slh index c5630c3564..da02ef750e 100755 --- a/libraries/render-utils/src/DeferredBuffer.slh +++ b/libraries/render-utils/src/DeferredBuffer.slh @@ -11,7 +11,6 @@ <@if not DEFERRED_BUFFER_SLH@> <@def DEFERRED_BUFFER_SLH@> - // the diffuse texture uniform sampler2D diffuseMap; diff --git a/libraries/render-utils/src/DeferredBufferWrite.slh b/libraries/render-utils/src/DeferredBufferWrite.slh new file mode 100755 index 0000000000..32822af2cb --- /dev/null +++ b/libraries/render-utils/src/DeferredBufferWrite.slh @@ -0,0 +1,28 @@ + +<@if not DEFERRED_BUFFER_WRITE_SLH@> +<@def DEFERRED_BUFFER_WRITE_SLH@> +/* +// the glow intensity +uniform float glowIntensity; + +// the alpha threshold +uniform float alphaThreshold; +*/ + +void packFragment(vec3 normal, float alpha, vec3 diffuse, vec3 specular, float shininess) { + // gl_FragData[0] = vec4(diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); + gl_FragData[0] = vec4(diffuse.rgb, alpha); + gl_FragData[1] = vec4(normal, 0.0) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); + gl_FragData[2] = vec4(specular, shininess / 128.0); +} + +<@endif@> diff --git a/libraries/render-utils/src/model.slf b/libraries/render-utils/src/model.slf index 42421c71a2..9c263869f0 100755 --- a/libraries/render-utils/src/model.slf +++ b/libraries/render-utils/src/model.slf @@ -11,6 +11,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +<@include DeferredBufferWrite.slh@> + // the diffuse texture uniform sampler2D diffuseMap; @@ -23,7 +25,16 @@ varying vec4 normal; void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); + + packDeferredFragment( + normalize(normal.xyz), + mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold)), + gl_Color.rgb * diffuse.rgb, + gl_FrontMaterial.specular.rgb, + gl_FrontMaterial.shininess); +/* gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 128.0); +*/ } From 522e7698a558845b3290076d10367fc06baea705 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 13 Jan 2015 10:23:00 -0800 Subject: [PATCH 16/93] first step factorizing the packDeferredFragment --- libraries/render-utils/src/DeferredBufferWrite.slh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/render-utils/src/DeferredBufferWrite.slh b/libraries/render-utils/src/DeferredBufferWrite.slh index 32822af2cb..8a547315cd 100755 --- a/libraries/render-utils/src/DeferredBufferWrite.slh +++ b/libraries/render-utils/src/DeferredBufferWrite.slh @@ -18,7 +18,7 @@ uniform float glowIntensity; uniform float alphaThreshold; */ -void packFragment(vec3 normal, float alpha, vec3 diffuse, vec3 specular, float shininess) { +void packDeferredFragment(vec3 normal, float alpha, vec3 diffuse, vec3 specular, float shininess) { // gl_FragData[0] = vec4(diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); gl_FragData[0] = vec4(diffuse.rgb, alpha); gl_FragData[1] = vec4(normal, 0.0) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); From d9efafac7ee593404224a5ccb454b0d05cc16816 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 13 Jan 2015 14:11:38 -0800 Subject: [PATCH 17/93] updating the model fragment shaders to use DeferredBUfferWrite --- .../render-utils/src/DeferredBufferWrite.slh | 15 ++++++++++++--- libraries/render-utils/src/Model.cpp | 6 +++++- libraries/render-utils/src/Model.h | 1 + libraries/render-utils/src/model.slf | 10 +--------- libraries/render-utils/src/model_lightmap.slf | 16 ++++++++++------ .../src/model_lightmap_normal_map.slf | 17 +++++++++++------ .../src/model_lightmap_normal_specular_map.slf | 16 +++++++++++++--- .../src/model_lightmap_specular_map.slf | 16 +++++++++++++--- libraries/render-utils/src/model_normal_map.slf | 15 +++++++++++---- .../src/model_normal_specular_map.slf | 15 +++++++++++---- .../render-utils/src/model_specular_map.slf | 14 +++++++++++--- libraries/render-utils/src/simple.slf | 14 ++++++++++++-- 12 files changed, 111 insertions(+), 44 deletions(-) diff --git a/libraries/render-utils/src/DeferredBufferWrite.slh b/libraries/render-utils/src/DeferredBufferWrite.slh index 8a547315cd..7b4ca7ba3b 100755 --- a/libraries/render-utils/src/DeferredBufferWrite.slh +++ b/libraries/render-utils/src/DeferredBufferWrite.slh @@ -10,19 +10,28 @@ !> <@if not DEFERRED_BUFFER_WRITE_SLH@> <@def DEFERRED_BUFFER_WRITE_SLH@> -/* + // the glow intensity uniform float glowIntensity; // the alpha threshold uniform float alphaThreshold; -*/ + +float evalOpaqueFinalAlpha(float alpha, float mapAlpha) { + return mix(alpha * glowIntensity, 1.0 - alpha * glowIntensity, step(mapAlpha, alphaThreshold)); +} void packDeferredFragment(vec3 normal, float alpha, vec3 diffuse, vec3 specular, float shininess) { - // gl_FragData[0] = vec4(diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); gl_FragData[0] = vec4(diffuse.rgb, alpha); gl_FragData[1] = vec4(normal, 0.0) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[2] = vec4(specular, shininess / 128.0); } +void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 diffuse, vec3 specular, float shininess, vec3 emissive) { + gl_FragData[0] = vec4(diffuse.rgb, alpha); + //gl_FragData[1] = vec4(normal, 0.0) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); + gl_FragData[1] = vec4(normal, 0.0) * 0.5 + vec4(0.5, 0.5, 0.5, 0.5); + gl_FragData[2] = vec4(emissive, shininess / 128.0); +} + <@endif@> diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 46fc6a6e4d..6cfad9931d 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -178,7 +178,7 @@ void Model::initProgram(ProgramObject& program, Model::Locations& locations, boo locations.alphaThreshold = program.uniformLocation("alphaThreshold"); locations.texcoordMatrices = program.uniformLocation("texcoordMatrices"); locations.emissiveParams = program.uniformLocation("emissiveParams"); - + locations.glowIntensity = program.uniformLocation("glowIntensity"); program.setUniformValue("diffuseMap", 0); program.setUniformValue("normalMap", 1); @@ -2367,6 +2367,10 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod } glm::vec4 diffuse = glm::vec4(part.diffuseColor, part.opacity); + + if (locations->glowIntensity >= 0) { + GLBATCH(glUniform1f)(locations->glowIntensity, glowEffect->getIntensity()); + } if (!(translucent && alphaThreshold == 0.0f)) { GLBATCH(glAlphaFunc)(GL_EQUAL, diffuse.a = glowEffect->getIntensity()); } diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index 83ceab109f..ef97e7dfd8 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -338,6 +338,7 @@ private: int specularTextureUnit; int emissiveTextureUnit; int emissiveParams; + int glowIntensity; }; static Locations _locations; diff --git a/libraries/render-utils/src/model.slf b/libraries/render-utils/src/model.slf index 9c263869f0..bbff368c2d 100755 --- a/libraries/render-utils/src/model.slf +++ b/libraries/render-utils/src/model.slf @@ -16,9 +16,6 @@ // the diffuse texture uniform sampler2D diffuseMap; -// the alpha threshold -uniform float alphaThreshold; - // the interpolated normal varying vec4 normal; @@ -28,13 +25,8 @@ void main(void) { packDeferredFragment( normalize(normal.xyz), - mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold)), + evalOpaqueFinalAlpha(gl_Color.a, diffuse.a), gl_Color.rgb * diffuse.rgb, gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess); -/* - gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); - gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); - gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 128.0); -*/ } diff --git a/libraries/render-utils/src/model_lightmap.slf b/libraries/render-utils/src/model_lightmap.slf index 9feacbe057..6b25921318 100755 --- a/libraries/render-utils/src/model_lightmap.slf +++ b/libraries/render-utils/src/model_lightmap.slf @@ -12,6 +12,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +<@include DeferredBufferWrite.slh@> + // the diffuse texture uniform sampler2D diffuseMap; @@ -19,9 +21,6 @@ uniform sampler2D diffuseMap; uniform sampler2D emissiveMap; uniform vec2 emissiveParams; -// the alpha threshold -uniform float alphaThreshold; - // the interpolated normal varying vec4 normal; @@ -32,7 +31,12 @@ void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); vec4 emissive = texture2D(emissiveMap, interpolatedTexcoord1.st); - gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); - gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 0.5); - gl_FragData[2] = vec4((vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb), gl_FrontMaterial.shininess / 128.0); + + packDeferredFragmentLightmap( + normalize(normal.xyz), + evalOpaqueFinalAlpha(gl_Color.a, diffuse.a), + gl_Color.rgb * diffuse.rgb, + gl_FrontMaterial.specular.rgb, + gl_FrontMaterial.shininess, + (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); } diff --git a/libraries/render-utils/src/model_lightmap_normal_map.slf b/libraries/render-utils/src/model_lightmap_normal_map.slf index 5bebbee3f6..9ef75802a8 100755 --- a/libraries/render-utils/src/model_lightmap_normal_map.slf +++ b/libraries/render-utils/src/model_lightmap_normal_map.slf @@ -12,6 +12,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +<@include DeferredBufferWrite.slh@> + // the diffuse texture uniform sampler2D diffuseMap; @@ -22,9 +24,6 @@ uniform sampler2D normalMap; uniform sampler2D emissiveMap; uniform vec2 emissiveParams; -// the alpha threshold -uniform float alphaThreshold; - // the interpolated normal varying vec4 interpolatedNormal; @@ -45,7 +44,13 @@ void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); vec4 emissive = texture2D(emissiveMap, interpolatedTexcoord1.st); - gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb * (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb), mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); - gl_FragData[1] = viewNormal + vec4(0.5, 0.5, 0.5, 1.0); - gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 128.0); + + packDeferredFragmentLightmap( + normalize(viewNormal.xyz), + evalOpaqueFinalAlpha(gl_Color.a, diffuse.a), + //gl_Color.rgb * diffuse.rgb, + vec3(1.0, 0.0, 0.0), + gl_FrontMaterial.specular.rgb, + gl_FrontMaterial.shininess, + (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); } diff --git a/libraries/render-utils/src/model_lightmap_normal_specular_map.slf b/libraries/render-utils/src/model_lightmap_normal_specular_map.slf index d2f76e4ef3..3bc72384f7 100755 --- a/libraries/render-utils/src/model_lightmap_normal_specular_map.slf +++ b/libraries/render-utils/src/model_lightmap_normal_specular_map.slf @@ -12,6 +12,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +<@include DeferredBufferWrite.slh@> + // the diffuse texture uniform sampler2D diffuseMap; @@ -25,9 +27,6 @@ uniform sampler2D normalMap; // the specular map texture uniform sampler2D specularMap; -// the alpha threshold -uniform float alphaThreshold; - // the interpolated normal varying vec4 interpolatedNormal; @@ -47,9 +46,20 @@ void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); + vec3 specular = texture2D(specularMap, gl_TexCoord[0].st).rgb; vec4 emissive = texture2D(emissiveMap, interpolatedTexcoord1.st); + + packDeferredFragmentLightmap( + normalize(viewNormal.xyz), + evalOpaqueFinalAlpha(gl_Color.a, diffuse.a), + gl_Color.rgb * diffuse.rgb, + specular, + gl_FrontMaterial.shininess, + (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); +/* gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb * (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb), mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); gl_FragData[1] = viewNormal + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, gl_FrontMaterial.shininess / 128.0); +*/ } diff --git a/libraries/render-utils/src/model_lightmap_specular_map.slf b/libraries/render-utils/src/model_lightmap_specular_map.slf index 40879a8fc3..7322da6b3a 100755 --- a/libraries/render-utils/src/model_lightmap_specular_map.slf +++ b/libraries/render-utils/src/model_lightmap_specular_map.slf @@ -12,6 +12,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +<@include DeferredBufferWrite.slh@> + // the diffuse texture uniform sampler2D diffuseMap; @@ -22,9 +24,6 @@ uniform vec2 emissiveParams; // the specular texture uniform sampler2D specularMap; -// the alpha threshold -uniform float alphaThreshold; - // the interpolated normal varying vec4 normal; @@ -33,9 +32,20 @@ varying vec2 interpolatedTexcoord1; void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); + vec3 specular = texture2D(specularMap, gl_TexCoord[0].st).rgb; vec4 emissive = texture2D(emissiveMap, interpolatedTexcoord1.st); + + packDeferredFragmentLightmap( + normalize(normal.xyz), + evalOpaqueFinalAlpha(gl_Color.a, diffuse.a), + gl_Color.rgb * diffuse.rgb, + specular, + gl_FrontMaterial.shininess, + (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); +/* gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb * (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb), mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, gl_FrontMaterial.shininess / 128.0); +*/ } diff --git a/libraries/render-utils/src/model_normal_map.slf b/libraries/render-utils/src/model_normal_map.slf index b625b346ed..74da394850 100755 --- a/libraries/render-utils/src/model_normal_map.slf +++ b/libraries/render-utils/src/model_normal_map.slf @@ -12,15 +12,14 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +<@include DeferredBufferWrite.slh@> + // the diffuse texture uniform sampler2D diffuseMap; // the normal map texture uniform sampler2D normalMap; -// the alpha threshold -uniform float alphaThreshold; - // the interpolated normal varying vec4 interpolatedNormal; @@ -38,7 +37,15 @@ void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); - gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); +/* gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); gl_FragData[1] = viewNormal + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 128.0); + */ + + packDeferredFragment( + normalize(viewNormal.xyz), + evalOpaqueFinalAlpha(gl_Color.a, diffuse.a), + gl_Color.rgb * diffuse.rgb, + gl_FrontMaterial.specular.rgb, + gl_FrontMaterial.shininess); } diff --git a/libraries/render-utils/src/model_normal_specular_map.slf b/libraries/render-utils/src/model_normal_specular_map.slf index fd288f0867..4248edfc90 100755 --- a/libraries/render-utils/src/model_normal_specular_map.slf +++ b/libraries/render-utils/src/model_normal_specular_map.slf @@ -12,6 +12,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +<@include DeferredBufferWrite.slh@> + // the diffuse texture uniform sampler2D diffuseMap; @@ -21,9 +23,6 @@ uniform sampler2D normalMap; // the specular map texture uniform sampler2D specularMap; -// the alpha threshold -uniform float alphaThreshold; - // the interpolated normal varying vec4 interpolatedNormal; @@ -41,8 +40,16 @@ void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); - gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); + vec3 specular = texture2D(specularMap, gl_TexCoord[0].st).rgb; +/* gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); gl_FragData[1] = viewNormal + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, gl_FrontMaterial.shininess / 128.0); + */ + packDeferredFragment( + normalize(viewNormal.xyz), + evalOpaqueFinalAlpha(gl_Color.a, diffuse.a), + gl_Color.rgb * diffuse.rgb, + specular, + gl_FrontMaterial.shininess); } diff --git a/libraries/render-utils/src/model_specular_map.slf b/libraries/render-utils/src/model_specular_map.slf index 4428173562..db1c2df9c5 100755 --- a/libraries/render-utils/src/model_specular_map.slf +++ b/libraries/render-utils/src/model_specular_map.slf @@ -12,23 +12,31 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +<@include DeferredBufferWrite.slh@> + // the diffuse texture uniform sampler2D diffuseMap; // the specular texture uniform sampler2D specularMap; -// the alpha threshold -uniform float alphaThreshold; - // the interpolated normal varying vec4 normal; void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); + vec3 specular = texture2D(specularMap, gl_TexCoord[0].st).rgb; +/* gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, gl_FrontMaterial.shininess / 128.0); + */ + packDeferredFragment( + normalize(normal.xyz), + evalOpaqueFinalAlpha(gl_Color.a, diffuse.a), + gl_Color.rgb * diffuse.rgb, + specular, + gl_FrontMaterial.shininess); } diff --git a/libraries/render-utils/src/simple.slf b/libraries/render-utils/src/simple.slf index 50e584669d..faa4af4573 100644 --- a/libraries/render-utils/src/simple.slf +++ b/libraries/render-utils/src/simple.slf @@ -12,15 +12,25 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +<@include DeferredBufferWrite.slh@> + // the interpolated normal varying vec4 normal; // the glow intensity -uniform float glowIntensity; +//uniform float glowIntensity; void main(void) { - // set the diffuse, normal, specular data + /* // set the diffuse, normal, specular data gl_FragData[0] = vec4(gl_Color.rgb, glowIntensity); gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 128.0); + */ + + packDeferredFragment( + normalize(normal.xyz), + glowIntensity, + gl_Color.rgb, + gl_FrontMaterial.specular.rgb, + gl_FrontMaterial.shininess); } From 1af87e57dadca6eb3283ff52354a382283e658ce Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 13 Jan 2015 14:21:07 -0800 Subject: [PATCH 18/93] handle new places API format in AddressManager --- libraries/networking/src/AddressManager.cpp | 39 ++++++++++++--------- libraries/networking/src/AddressManager.h | 3 +- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 23aa8dad72..e6ad3220c2 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -22,7 +22,8 @@ #include "AddressManager.h" AddressManager::AddressManager() : - _currentDomain(), + _rootPlaceName(), + _rootPlaceID(), _positionGetter(NULL), _orientationGetter(NULL) { @@ -37,7 +38,7 @@ const QUrl AddressManager::currentAddress() const { QUrl hifiURL; hifiURL.setScheme(HIFI_URL_SCHEME); - hifiURL.setHost(_currentDomain); + hifiURL.setHost(_rootPlaceName); hifiURL.setPath(currentPath()); return hifiURL; @@ -174,15 +175,21 @@ void AddressManager::handleAPIResponse(QNetworkReply& requestReply) { } void AddressManager::goToAddressFromObject(const QVariantMap& addressMap) { + const QString ADDRESS_API_ROOT_KEY = "root"; const QString ADDRESS_API_DOMAIN_KEY = "domain"; const QString ADDRESS_API_ONLINE_KEY = "online"; if (!addressMap.contains(ADDRESS_API_ONLINE_KEY) || addressMap[ADDRESS_API_ONLINE_KEY].toBool()) { - if (addressMap.contains(ADDRESS_API_DOMAIN_KEY)) { - QVariantMap domainObject = addressMap[ADDRESS_API_DOMAIN_KEY].toMap(); - + QVariantMap rootMap = addressMap[ADDRESS_API_ROOT_KEY].toMap(); + if (rootMap.isEmpty()) { + rootMap = addressMap; + } + + QVariantMap domainObject = rootMap[ADDRESS_API_DOMAIN_KEY].toMap(); + + if (!domainObject.isEmpty()) { const QString DOMAIN_NETWORK_ADDRESS_KEY = "network_address"; const QString DOMAIN_ICE_SERVER_ADDRESS_KEY = "ice_server_address"; @@ -200,22 +207,22 @@ void AddressManager::goToAddressFromObject(const QVariantMap& addressMap) { emit possibleDomainChangeRequiredViaICEForID(iceServerAddress, domainID); } - // set our current domain to the name that came back - const QString DOMAIN_NAME_KEY = "name"; + // set our current root place id to the ID that came back + const QString PLACE_ID_KEY = "id"; + _rootPlaceID = rootMap[PLACE_ID_KEY].toUuid(); - _currentDomain = domainObject[DOMAIN_NAME_KEY].toString(); + // set our current root place name to the name that came back + const QString PLACE_NAME_KEY = "name"; + _rootPlaceName = rootMap[PLACE_NAME_KEY].toString(); // take the path that came back - const QString LOCATION_KEY = "location"; - const QString LOCATION_PATH_KEY = "path"; + const QString PLACE_PATH_KEY = "path"; QString returnedPath; - if (domainObject.contains(LOCATION_PATH_KEY)) { - returnedPath = domainObject[LOCATION_PATH_KEY].toString(); - } else if (domainObject.contains(LOCATION_KEY)) { - returnedPath = domainObject[LOCATION_KEY].toMap()[LOCATION_PATH_KEY].toString(); - } else if (addressMap.contains(LOCATION_PATH_KEY)) { - returnedPath = addressMap[LOCATION_PATH_KEY].toString(); + if (addressMap.contains(PLACE_PATH_KEY) && !addressMap[PLACE_PATH_KEY].toString().isEmpty()) { + returnedPath = addressMap[PLACE_PATH_KEY].toString(); + } else if (rootMap.contains(PLACE_PATH_KEY) && !rootMap[PLACE_PATH_KEY].toString().isEmpty()) { + returnedPath = rootMap[PLACE_PATH_KEY].toString(); } bool shouldFaceViewpoint = addressMap.contains(ADDRESS_API_ONLINE_KEY); diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index dee070740f..ac4200d675 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -85,7 +85,8 @@ private: bool handleRelativeViewpoint(const QString& pathSubsection, bool shouldFace = false); bool handleUsername(const QString& lookupString); - QString _currentDomain; + QString _rootPlaceName; + QUuid _rootPlaceID; PositionGetter _positionGetter; OrientationGetter _orientationGetter; }; From 16261a5fc1ba0be82f4d81c563a4338310b88259 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 13 Jan 2015 14:49:24 -0800 Subject: [PATCH 19/93] more updates for new place/location APIs --- interface/src/Application.cpp | 2 +- libraries/networking/src/AddressManager.cpp | 140 +++++++++++--------- libraries/networking/src/AddressManager.h | 8 +- 3 files changed, 81 insertions(+), 69 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 22a2b6bc22..6960f2d025 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3112,7 +3112,7 @@ void Application::updateWindowTitle(){ QString connectionStatus = nodeList->getDomainHandler().isConnected() ? "" : " (NOT CONNECTED) "; QString username = AccountManager::getInstance().getAccountInfo().getUsername(); QString title = QString() + (!username.isEmpty() ? username + " @ " : QString()) - + DependencyManager::get()->getCurrentDomain() + connectionStatus + buildVersion; + + DependencyManager::get()->getRootPlaceName() + connectionStatus + buildVersion; #ifndef WIN32 // crashes with vs2013/win32 diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index e6ad3220c2..8ca0226a34 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -89,11 +89,6 @@ const QString AddressManager::currentPath(bool withOrientation) const { } } -QString AddressManager::getDomainID() const { - const QUuid& domainID = NodeList::getInstance()->getDomainHandler().getUUID(); - return domainID.isNull() ? "" : uuidStringWithoutCurlyBraces(domainID); -} - const JSONCallbackParameters& AddressManager::apiCallbackParameters() { static bool hasSetupParameters = false; static JSONCallbackParameters callbackParams; @@ -174,73 +169,90 @@ void AddressManager::handleAPIResponse(QNetworkReply& requestReply) { emit lookupResultsFinished(); } -void AddressManager::goToAddressFromObject(const QVariantMap& addressMap) { - const QString ADDRESS_API_ROOT_KEY = "root"; - const QString ADDRESS_API_DOMAIN_KEY = "domain"; - const QString ADDRESS_API_ONLINE_KEY = "online"; +void AddressManager::goToAddressFromObject(const QVariantMap& dataObject) { - if (!addressMap.contains(ADDRESS_API_ONLINE_KEY) - || addressMap[ADDRESS_API_ONLINE_KEY].toBool()) { - - QVariantMap rootMap = addressMap[ADDRESS_API_ROOT_KEY].toMap(); - if (rootMap.isEmpty()) { - rootMap = addressMap; - } - - QVariantMap domainObject = rootMap[ADDRESS_API_DOMAIN_KEY].toMap(); + const QString DATA_OBJECT_PLACE_KEY = "place"; + const QString DATA_OBJECT_USER_LOCATION_KEY = "location"; - if (!domainObject.isEmpty()) { - const QString DOMAIN_NETWORK_ADDRESS_KEY = "network_address"; - const QString DOMAIN_ICE_SERVER_ADDRESS_KEY = "ice_server_address"; + QVariantMap locationMap; + if (dataObject.contains(DATA_OBJECT_PLACE_KEY)) { + locationMap = dataObject[DATA_OBJECT_PLACE_KEY].toMap(); + } else { + locationMap = dataObject[DATA_OBJECT_USER_LOCATION_KEY].toMap(); + } + + qDebug() << locationMap; + + if (!locationMap.isEmpty()) { + const QString LOCATION_API_ROOT_KEY = "root"; + const QString LOCATION_API_DOMAIN_KEY = "domain"; + const QString LOCATION_API_ONLINE_KEY = "online"; + + if (!locationMap.contains(LOCATION_API_ONLINE_KEY) + || locationMap[LOCATION_API_ONLINE_KEY].toBool()) { - if (domainObject.contains(DOMAIN_NETWORK_ADDRESS_KEY)) { - QString domainHostname = domainObject[DOMAIN_NETWORK_ADDRESS_KEY].toString(); - - emit possibleDomainChangeRequired(domainHostname, DEFAULT_DOMAIN_SERVER_PORT); - } else { - QString iceServerAddress = domainObject[DOMAIN_ICE_SERVER_ADDRESS_KEY].toString(); - - const QString DOMAIN_ID_KEY = "id"; - QString domainIDString = domainObject[DOMAIN_ID_KEY].toString(); - QUuid domainID(domainIDString); - - emit possibleDomainChangeRequiredViaICEForID(iceServerAddress, domainID); + QVariantMap rootMap = locationMap[LOCATION_API_ROOT_KEY].toMap(); + if (rootMap.isEmpty()) { + rootMap = locationMap; } - // set our current root place id to the ID that came back - const QString PLACE_ID_KEY = "id"; - _rootPlaceID = rootMap[PLACE_ID_KEY].toUuid(); + QVariantMap domainObject = rootMap[LOCATION_API_DOMAIN_KEY].toMap(); - // set our current root place name to the name that came back - const QString PLACE_NAME_KEY = "name"; - _rootPlaceName = rootMap[PLACE_NAME_KEY].toString(); - - // take the path that came back - const QString PLACE_PATH_KEY = "path"; - QString returnedPath; - - if (addressMap.contains(PLACE_PATH_KEY) && !addressMap[PLACE_PATH_KEY].toString().isEmpty()) { - returnedPath = addressMap[PLACE_PATH_KEY].toString(); - } else if (rootMap.contains(PLACE_PATH_KEY) && !rootMap[PLACE_PATH_KEY].toString().isEmpty()) { - returnedPath = rootMap[PLACE_PATH_KEY].toString(); - } - - bool shouldFaceViewpoint = addressMap.contains(ADDRESS_API_ONLINE_KEY); - - if (!returnedPath.isEmpty()) { - // try to parse this returned path as a viewpoint, that's the only thing it could be for now - if (!handleRelativeViewpoint(returnedPath, shouldFaceViewpoint)) { - qDebug() << "Received a location path that was could not be handled as a viewpoint -" << returnedPath; + if (!domainObject.isEmpty()) { + const QString DOMAIN_NETWORK_ADDRESS_KEY = "network_address"; + const QString DOMAIN_ICE_SERVER_ADDRESS_KEY = "ice_server_address"; + + if (domainObject.contains(DOMAIN_NETWORK_ADDRESS_KEY)) { + QString domainHostname = domainObject[DOMAIN_NETWORK_ADDRESS_KEY].toString(); + + emit possibleDomainChangeRequired(domainHostname, DEFAULT_DOMAIN_SERVER_PORT); + } else { + QString iceServerAddress = domainObject[DOMAIN_ICE_SERVER_ADDRESS_KEY].toString(); + + const QString DOMAIN_ID_KEY = "id"; + QString domainIDString = domainObject[DOMAIN_ID_KEY].toString(); + QUuid domainID(domainIDString); + + emit possibleDomainChangeRequiredViaICEForID(iceServerAddress, domainID); } + + // set our current root place id to the ID that came back + const QString PLACE_ID_KEY = "id"; + _rootPlaceID = rootMap[PLACE_ID_KEY].toUuid(); + + // set our current root place name to the name that came back + const QString PLACE_NAME_KEY = "name"; + _rootPlaceName = rootMap[PLACE_NAME_KEY].toString(); + + // take the path that came back + const QString PLACE_PATH_KEY = "path"; + QString returnedPath; + + if (locationMap.contains(PLACE_PATH_KEY) && !locationMap[PLACE_PATH_KEY].toString().isEmpty()) { + returnedPath = locationMap[PLACE_PATH_KEY].toString(); + } else if (rootMap.contains(PLACE_PATH_KEY) && !rootMap[PLACE_PATH_KEY].toString().isEmpty()) { + returnedPath = rootMap[PLACE_PATH_KEY].toString(); + } + + bool shouldFaceViewpoint = locationMap.contains(LOCATION_API_ONLINE_KEY); + + if (!returnedPath.isEmpty()) { + // try to parse this returned path as a viewpoint, that's the only thing it could be for now + if (!handleRelativeViewpoint(returnedPath, shouldFaceViewpoint)) { + qDebug() << "Received a location path that was could not be handled as a viewpoint -" << returnedPath; + } + } + } else { + qDebug() << "Received an address manager API response with no domain key. Cannot parse."; + qDebug() << locationMap; } - } else { - qDebug() << "Received an address manager API response with no domain key. Cannot parse."; - qDebug() << addressMap; + // we've been told that this result exists but is offline, emit our signal so the application can handle + emit lookupResultIsOffline(); } } else { - // we've been told that this result exists but is offline, emit our signal so the application can handle - emit lookupResultIsOffline(); + qDebug() << "Received an address manager API response with no location key or place key. Cannot parse."; + qDebug() << locationMap; } } @@ -373,8 +385,10 @@ bool AddressManager::handleUsername(const QString& lookupString) { } -void AddressManager::setDomainInfo(const QString& hostname, quint16 port, const QString& domainName) { - _currentDomain = domainName.isEmpty() ? hostname : domainName; +void AddressManager::setDomainInfo(const QString& hostname, quint16 port) { + _rootPlaceName = hostname; + _rootPlaceID = QUuid(); + emit possibleDomainChangeRequired(hostname, port); } diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index ac4200d675..e98526689b 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -33,9 +33,8 @@ class AddressManager : public QObject { Q_PROPERTY(bool isConnected READ isConnected) Q_PROPERTY(QUrl href READ currentAddress) Q_PROPERTY(QString protocol READ getProtocol) - Q_PROPERTY(QString hostname READ getCurrentDomain) + Q_PROPERTY(QString hostname READ getRootPlaceName) Q_PROPERTY(QString pathname READ currentPath) - Q_PROPERTY(QString domainID READ getDomainID) public: bool isConnected(); const QString& getProtocol() { return HIFI_URL_SCHEME; }; @@ -43,8 +42,7 @@ public: const QUrl currentAddress() const; const QString currentPath(bool withOrientation = true) const; - const QString& getCurrentDomain() const { return _currentDomain; } - QString getDomainID() const; + const QString& getRootPlaceName() const { return _rootPlaceName; } void attemptPlaceNameLookup(const QString& lookupString); @@ -75,7 +73,7 @@ private slots: void handleAPIResponse(QNetworkReply& requestReply); void handleAPIError(QNetworkReply& errorReply); private: - void setDomainInfo(const QString& hostname, quint16 port, const QString& domainName = QString()); + void setDomainInfo(const QString& hostname, quint16 port); const JSONCallbackParameters& apiCallbackParameters(); From 92b8cd2d1e888e23d66d10c54ff939c5ef56b817 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 13 Jan 2015 15:02:04 -0800 Subject: [PATCH 20/93] handle storage of user location in new format --- interface/src/Application.cpp | 19 ++++++++++++++----- libraries/networking/src/AddressManager.h | 1 + 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6960f2d025..c156de03ca 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3124,23 +3124,32 @@ void Application::updateWindowTitle(){ void Application::updateLocationInServer() { AccountManager& accountManager = AccountManager::getInstance(); + AddressManager::SharedPointer addressManager = DependencyManager::get(); DomainHandler& domainHandler = NodeList::getInstance()->getDomainHandler(); - if (accountManager.isLoggedIn() && domainHandler.isConnected() && !domainHandler.getUUID().isNull()) { + if (accountManager.isLoggedIn() && domainHandler.isConnected() + && (!addressManager->getRootPlaceID().isNull() || !domainHandler.getUUID().isNull())) { // construct a QJsonObject given the user's current address information QJsonObject rootObject; QJsonObject locationObject; - QString pathString = DependencyManager::get()->currentPath(); + QString pathString = addressManager->currentPath(); const QString LOCATION_KEY_IN_ROOT = "location"; - const QString PATH_KEY_IN_LOCATION = "path"; - const QString DOMAIN_ID_KEY_IN_LOCATION = "domain_id"; + const QString PATH_KEY_IN_LOCATION = "path"; locationObject.insert(PATH_KEY_IN_LOCATION, pathString); - locationObject.insert(DOMAIN_ID_KEY_IN_LOCATION, domainHandler.getUUID().toString()); + + if (!addressManager->getRootPlaceID().isNull()) { + const QString PLACE_ID_KEY_IN_LOCATION = "place_id"; + locationObject.insert(PLACE_ID_KEY_IN_LOCATION, addressManager->getRootPlaceID().toString()); + + } else { + const QString DOMAIN_ID_KEY_IN_LOCATION = "domain_id"; + locationObject.insert(DOMAIN_ID_KEY_IN_LOCATION, domainHandler.getUUID().toString()); + } rootObject.insert(LOCATION_KEY_IN_ROOT, locationObject); diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index e98526689b..a8adf57741 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -42,6 +42,7 @@ public: const QUrl currentAddress() const; const QString currentPath(bool withOrientation = true) const; + const QUuid& getRootPlaceID() const { return _rootPlaceID; } const QString& getRootPlaceName() const { return _rootPlaceName; } void attemptPlaceNameLookup(const QString& lookupString); From 6e1ba17c6eda08361d660596436eb2e3c7f79325 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 13 Jan 2015 15:07:45 -0800 Subject: [PATCH 21/93] handle application title change for place name change --- interface/src/Application.cpp | 2 ++ libraries/networking/src/AddressManager.cpp | 12 +++++++++--- libraries/networking/src/AddressManager.h | 3 +++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c156de03ca..ecc36d7f05 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -306,6 +306,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : // use our MyAvatar position and quat for address manager path addressManager->setPositionGetter(getPositionForPath); addressManager->setOrientationGetter(getOrientationForPath); + + connect(addressManager.data(), &AddressManager::rootPlaceNameChanged, this, &Application::updateWindowTitle); _settings = new QSettings(this); _numChangedSettings = 0; diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 8ca0226a34..4802f3ca15 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -181,8 +181,6 @@ void AddressManager::goToAddressFromObject(const QVariantMap& dataObject) { locationMap = dataObject[DATA_OBJECT_USER_LOCATION_KEY].toMap(); } - qDebug() << locationMap; - if (!locationMap.isEmpty()) { const QString LOCATION_API_ROOT_KEY = "root"; const QString LOCATION_API_DOMAIN_KEY = "domain"; @@ -222,7 +220,8 @@ void AddressManager::goToAddressFromObject(const QVariantMap& dataObject) { // set our current root place name to the name that came back const QString PLACE_NAME_KEY = "name"; - _rootPlaceName = rootMap[PLACE_NAME_KEY].toString(); + QString newRootPlaceName = rootMap[PLACE_NAME_KEY].toString(); + setRootPlaceName(newRootPlaceName); // take the path that came back const QString PLACE_PATH_KEY = "path"; @@ -384,6 +383,13 @@ bool AddressManager::handleUsername(const QString& lookupString) { return false; } +void AddressManager::setRootPlaceName(const QString& rootPlaceName) { + if (rootPlaceName != _rootPlaceName) { + _rootPlaceName = rootPlaceName; + emit rootPlaceNameChanged(_rootPlaceName); + } +} + void AddressManager::setDomainInfo(const QString& hostname, quint16 port) { _rootPlaceName = hostname; diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index a8adf57741..6cb5cdbf60 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -43,7 +43,9 @@ public: const QString currentPath(bool withOrientation = true) const; const QUuid& getRootPlaceID() const { return _rootPlaceID; } + const QString& getRootPlaceName() const { return _rootPlaceName; } + void setRootPlaceName(const QString& rootPlaceName); void attemptPlaceNameLookup(const QString& lookupString); @@ -68,6 +70,7 @@ signals: void locationChangeRequired(const glm::vec3& newPosition, bool hasOrientationChange, const glm::quat& newOrientation, bool shouldFaceLocation); + void rootPlaceNameChanged(const QString& newRootPlaceName); protected: AddressManager(); private slots: From 6d2c87c7a3faf7f4deca34c2cb17a266c10a8e14 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 13 Jan 2015 15:15:39 -0800 Subject: [PATCH 22/93] put current domain hostname if no place name present --- interface/src/Application.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ecc36d7f05..8c82281007 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3113,8 +3113,14 @@ void Application::updateWindowTitle(){ QString connectionStatus = nodeList->getDomainHandler().isConnected() ? "" : " (NOT CONNECTED) "; QString username = AccountManager::getInstance().getAccountInfo().getUsername(); + QString currentPlaceName = DependencyManager::get()->getRootPlaceName(); + + if (currentPlaceName.isEmpty()) { + currentPlaceName = nodeList->getDomainHandler().getHostname(); + } + QString title = QString() + (!username.isEmpty() ? username + " @ " : QString()) - + DependencyManager::get()->getRootPlaceName() + connectionStatus + buildVersion; + + currentPlaceName + connectionStatus + buildVersion; #ifndef WIN32 // crashes with vs2013/win32 From 9c083ce86e6e9ed7e5235f40e90c1592c3168a95 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 13 Jan 2015 15:51:18 -0800 Subject: [PATCH 23/93] Using the model::Material for rendering and in shaders --- libraries/render-utils/src/Material.slh | 59 +++++++++++++++++++++++++ libraries/render-utils/src/Model.cpp | 42 +++++++++++++++--- libraries/render-utils/src/Model.h | 1 + libraries/render-utils/src/model.slf | 14 +++--- 4 files changed, 105 insertions(+), 11 deletions(-) create mode 100755 libraries/render-utils/src/Material.slh diff --git a/libraries/render-utils/src/Material.slh b/libraries/render-utils/src/Material.slh new file mode 100755 index 0000000000..4720b19d00 --- /dev/null +++ b/libraries/render-utils/src/Material.slh @@ -0,0 +1,59 @@ + +<@if not MATERIAL_SLH@> +<@def MATERIAL_SLH@> + +struct Material { + vec4 _diffuse; + vec4 _specular; + + float getOpacity() { return _diffuse.a; } + vec3 getDiffuse() { return _diffuse.rgb; } + vec3 getSpecular() { return _specular.rgb; } + float getShininess() { return _specular.a; } +}; + +<@if GLPROFILE == PC_GL@> +uniform materialBuffer { + Material mat; +}; +Material getMaterial() { + return mat; +} +<@elif GLPROFILE == MAC_GL@> +uniform vec4 materialBuffer[2]; +Material getMaterial() { + Material mat; + mat._diffuse = materialBuffer[0]; + mat._specular = materialBuffer[1]; + return mat; +} +<@else@> +uniform vec4 materialBuffer[2]; +Material getMaterial() { + Material mat; + mat._diffuse = materialBuffer[0]; + mat._specular = materialBuffer[1]; + return mat; +} +<@endif@> + + + +<@endif@> \ No newline at end of file diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 6cfad9931d..2b9418b82f 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -198,6 +198,28 @@ void Model::initProgram(ProgramObject& program, Model::Locations& locations, boo locations.emissiveTextureUnit = -1; } + // bindable uniform version +#if defined(Q_OS_MAC) + loc = program.uniformLocation("materialBuffer"); + if (loc >= 0) { + locations.materialBufferUnit = loc; + } else { + locations.materialBufferUnit = -1; + } +#else + loc = glGetUniformBlockIndex(program.programId(), "materialBuffer"); + if (loc >= 0) { + glUniformBlockBinding(program.programId(), loc, 1); + locations.materialBufferUnit = 1; + } else { + locations.materialBufferUnit = -1; + } +#endif + + if (!program.isLinked()) { + program.release(); + } + program.release(); } @@ -2348,6 +2370,7 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod for (int j = 0; j < networkMesh.parts.size(); j++) { const NetworkMeshPart& networkPart = networkMesh.parts.at(j); const FBXMeshPart& part = mesh.parts.at(j); + model::MaterialPointer material = part._material; if ((networkPart.isTranslucent() || part.opacity != 1.0f) != translucent) { offset += (part.quadIndices.size() + part.triangleIndices.size()) * sizeof(int); continue; @@ -2366,7 +2389,7 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod qDebug() << "NEW part.materialID:" << part.materialID; } - glm::vec4 diffuse = glm::vec4(part.diffuseColor, part.opacity); + glm::vec4 diffuse = glm::vec4(material->getDiffuse(), material->getOpacity()); if (locations->glowIntensity >= 0) { GLBATCH(glUniform1f)(locations->glowIntensity, glowEffect->getIntensity()); @@ -2374,11 +2397,18 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod if (!(translucent && alphaThreshold == 0.0f)) { GLBATCH(glAlphaFunc)(GL_EQUAL, diffuse.a = glowEffect->getIntensity()); } - glm::vec4 specular = glm::vec4(part.specularColor, 1.0f); - GLBATCH(glMaterialfv)(GL_FRONT, GL_AMBIENT, (const float*)&diffuse); - GLBATCH(glMaterialfv)(GL_FRONT, GL_DIFFUSE, (const float*)&diffuse); - GLBATCH(glMaterialfv)(GL_FRONT, GL_SPECULAR, (const float*)&specular); - GLBATCH(glMaterialf)(GL_FRONT, GL_SHININESS, (part.shininess > 128.0f ? 128.0f: part.shininess)); + glm::vec4 specular = glm::vec4(material->getSpecular(), 1.0f); + float shininess = material->getShininess(); + shininess = (shininess > 128.0f ? 128.0f: shininess); + + if (locations->materialBufferUnit >= 0) { + batch.setUniformBuffer(locations->materialBufferUnit, material->getSchemaBuffer()); + } else { + GLBATCH(glMaterialfv)(GL_FRONT, GL_AMBIENT, (const float*)&diffuse); + GLBATCH(glMaterialfv)(GL_FRONT, GL_DIFFUSE, (const float*)&diffuse); + GLBATCH(glMaterialfv)(GL_FRONT, GL_SPECULAR, (const float*)&specular); + GLBATCH(glMaterialf)(GL_FRONT, GL_SHININESS, shininess); + } Texture* diffuseMap = networkPart.diffuseTexture.data(); if (mesh.isEye && diffuseMap) { diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index ef97e7dfd8..e10f218563 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -339,6 +339,7 @@ private: int emissiveTextureUnit; int emissiveParams; int glowIntensity; + int materialBufferUnit; }; static Locations _locations; diff --git a/libraries/render-utils/src/model.slf b/libraries/render-utils/src/model.slf index bbff368c2d..396935b4b8 100755 --- a/libraries/render-utils/src/model.slf +++ b/libraries/render-utils/src/model.slf @@ -13,6 +13,8 @@ <@include DeferredBufferWrite.slh@> +<@include Material.slh@> + // the diffuse texture uniform sampler2D diffuseMap; @@ -20,13 +22,15 @@ uniform sampler2D diffuseMap; varying vec4 normal; void main(void) { - // set the diffuse, normal, specular data + // Fetch diffuse map vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); + Material mat = getMaterial(); + packDeferredFragment( normalize(normal.xyz), - evalOpaqueFinalAlpha(gl_Color.a, diffuse.a), - gl_Color.rgb * diffuse.rgb, - gl_FrontMaterial.specular.rgb, - gl_FrontMaterial.shininess); + evalOpaqueFinalAlpha(mat.getOpacity(), diffuse.a), + mat.getDiffuse()/* * diffuse.rgb*/, + mat.getSpecular(), + mat.getShininess()); } From d3edd14638d0be8233ca7970d67beb7bd8ac0064 Mon Sep 17 00:00:00 2001 From: dev Date: Tue, 13 Jan 2015 16:53:22 -0800 Subject: [PATCH 24/93] fixes for glsl mac --- libraries/render-utils/src/Material.slh | 10 ++++++---- libraries/render-utils/src/model.slf | 8 ++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/libraries/render-utils/src/Material.slh b/libraries/render-utils/src/Material.slh index 4720b19d00..2ea7b2a12c 100755 --- a/libraries/render-utils/src/Material.slh +++ b/libraries/render-utils/src/Material.slh @@ -15,12 +15,14 @@ struct Material { vec4 _diffuse; vec4 _specular; - float getOpacity() { return _diffuse.a; } - vec3 getDiffuse() { return _diffuse.rgb; } - vec3 getSpecular() { return _specular.rgb; } - float getShininess() { return _specular.a; } }; +float getMaterialOpacity(Material m) { return m._diffuse.a; } +vec3 getMaterialDiffuse(Material m) { return m._diffuse.rgb; } +vec3 getMaterialSpecular(Material m) { return m._specular.rgb; } +float getMaterialShininess(Material m) { return m._specular.a; } + + <@if GLPROFILE == PC_GL@> uniform materialBuffer { Material mat; diff --git a/libraries/render-utils/src/model.slf b/libraries/render-utils/src/model.slf index 396935b4b8..bc6f127a77 100755 --- a/libraries/render-utils/src/model.slf +++ b/libraries/render-utils/src/model.slf @@ -29,8 +29,8 @@ void main(void) { packDeferredFragment( normalize(normal.xyz), - evalOpaqueFinalAlpha(mat.getOpacity(), diffuse.a), - mat.getDiffuse()/* * diffuse.rgb*/, - mat.getSpecular(), - mat.getShininess()); + evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a), + getMaterialDiffuse(mat) * diffuse.rgb, + getMaterialSpecular(mat), + getMaterialShininess(mat)); } From d7ad5a35d69072d773feccc875d9528e112b6283 Mon Sep 17 00:00:00 2001 From: dev Date: Tue, 13 Jan 2015 18:24:32 -0800 Subject: [PATCH 25/93] fixes for glsl mac --- libraries/gpu/src/gpu/GLBackend.cpp | 8 ++++---- libraries/render-utils/src/Material.slh | 19 ++++++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index f5f998d0d9..ed1b97a58f 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -494,13 +494,13 @@ void GLBackend::do_setUniformBuffer(Batch& batch, uint32 paramOffset) { #if defined(Q_OS_MAC) GLfloat* data = (GLfloat*) (uniformBuffer->getData() + rangeStart); glUniform4fv(slot, rangeSize / sizeof(GLfloat[4]), data); + + // NOT working so we ll stick to the uniform float array until we move to core profile + // GLuint bo = getBufferID(*uniformBuffer); + //glUniformBufferEXT(_shader._program, slot, bo); #else GLuint bo = getBufferID(*uniformBuffer); glBindBufferRange(GL_UNIFORM_BUFFER, slot, bo, rangeStart, rangeSize); - - // glUniformBufferEXT(_shader._program, slot, bo); - - //glBindBufferBase(GL_UNIFORM_BUFFER, slot, bo); #endif CHECK_GL_ERROR(); } diff --git a/libraries/render-utils/src/Material.slh b/libraries/render-utils/src/Material.slh index 2ea7b2a12c..e77b664ee1 100755 --- a/libraries/render-utils/src/Material.slh +++ b/libraries/render-utils/src/Material.slh @@ -36,8 +36,17 @@ Material getMaterial() { Material mat; mat._diffuse = materialBuffer[0]; mat._specular = materialBuffer[1]; - return mat; + return mat; } + <@else@> uniform vec4 materialBuffer[2]; Material getMaterial() { @@ -48,14 +57,6 @@ Material getMaterial() { } <@endif@> - <@endif@> \ No newline at end of file From 7130c579f5c8214d1ba8f13f0795867ae888de54 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 13 Jan 2015 17:56:34 -0800 Subject: [PATCH 26/93] First pass at Bookmarks class In-memory for starters. --- interface/src/Bookmarks.cpp | 54 +++++++++++++++++++++++++++++++++++++ interface/src/Bookmarks.h | 39 +++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 interface/src/Bookmarks.cpp create mode 100644 interface/src/Bookmarks.h diff --git a/interface/src/Bookmarks.cpp b/interface/src/Bookmarks.cpp new file mode 100644 index 0000000000..c8879e1a8f --- /dev/null +++ b/interface/src/Bookmarks.cpp @@ -0,0 +1,54 @@ +// +// Bookmarks.cpp +// interface/src +// +// Created by David Rowe on 13 Jan 2015. +// 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 "Bookmarks.h" + +Bookmarks::Bookmarks() { +} + +void Bookmarks::insert(QString name, QString address) { + QString key = name.toLower(); + + if (isValidName(name)) { + QJsonObject bookmark; + bookmark.insert("name", name); + bookmark.insert("address", address); + _bookmarks.insert(key, bookmark); + + if (contains(key)) { + qDebug() << "Added bookmark: " << name << ", " << address; + } else { + qDebug() << "Couldn't add bookmark: " << name << ", " << address; + } + } else { + qDebug() << "Invalid bookmark: " << name << ", " << address; + } +} + +void Bookmarks::remove(QString name) { + QString key = name.toLower(); + + _bookmarks.remove(key); + + if (!contains(key)) { + qDebug() << "Removed bookmark: " << name; + } else { + qDebug() << "Couldn't remove bookmark: " << name; + } +} + +bool Bookmarks::contains(QString name) { + return _bookmarks.contains(name.toLower()); +} + +bool Bookmarks::isValidName(QString name) { + return _nameRegExp.exactMatch(name); +} diff --git a/interface/src/Bookmarks.h b/interface/src/Bookmarks.h new file mode 100644 index 0000000000..a2def873b0 --- /dev/null +++ b/interface/src/Bookmarks.h @@ -0,0 +1,39 @@ +// +// Bookmarks.h +// interface/src +// +// Created by David Rowe on 13 Jan 2015. +// 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_Bookmarks_h +#define hifi_Bookmarks_h + +#include +#include +#include +#include +#include + +class Bookmarks: public QObject { + Q_OBJECT + +public: + Bookmarks(); + + void insert(QString name, QString address); // Overwrites any existing entry with same name. + void remove(QString name); + + bool contains(QString name); + bool isValidName(QString name); + +private: + QMap _bookmarks; // key: { name: string, address: string } + // key is a lowercase copy of name, used to make the bookmarks case insensitive. + const QRegExp _nameRegExp = QRegExp("^[\\w\\-]+$"); +}; + +#endif // hifi_Bookmarks_h \ No newline at end of file From fa6faa771a70eb405784bfe4a9e608564015c931 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 13 Jan 2015 22:39:16 -0800 Subject: [PATCH 27/93] Add bookmarks with Bookmark Location menu item The menu of bookmarks is kept sorted. --- interface/src/Application.cpp | 2 ++ interface/src/Application.h | 5 ++++ interface/src/Bookmarks.cpp | 28 +++++++------------ interface/src/Bookmarks.h | 10 +++---- interface/src/Menu.cpp | 51 +++++++++++++++++++++++++++++++++++ interface/src/Menu.h | 5 ++++ 6 files changed, 76 insertions(+), 25 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c8f93b0fa6..717ebdd749 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -310,6 +310,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _settings = new QSettings(this); _numChangedSettings = 0; + _bookmarks = new Bookmarks(); + #ifdef _WIN32 WSADATA WsaData; int wsaresult = WSAStartup(MAKEWORD(2,2), &WsaData); diff --git a/interface/src/Application.h b/interface/src/Application.h index d9ec5a1eae..70f7811555 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -38,6 +38,7 @@ #include #include "Audio.h" +#include "Bookmarks.h" #include "Camera.h" #include "DatagramProcessor.h" #include "Environment.h" @@ -296,6 +297,8 @@ public: QRect getDesirableApplicationGeometry(); RunningScriptsWidget* getRunningScriptsWidget() { return _runningScriptsWidget; } + Bookmarks* getBookmarks() const { return _bookmarks; } + signals: /// Fired when we're simulating; allows external parties to hook in. @@ -569,6 +572,8 @@ private: bool _isVSyncOn; bool _aboutToQuit; + + Bookmarks* _bookmarks; }; #endif // hifi_Application_h diff --git a/interface/src/Bookmarks.cpp b/interface/src/Bookmarks.cpp index c8879e1a8f..36f489fa6a 100644 --- a/interface/src/Bookmarks.cpp +++ b/interface/src/Bookmarks.cpp @@ -14,26 +14,22 @@ Bookmarks::Bookmarks() { } -void Bookmarks::insert(QString name, QString address) { +void Bookmarks::insert(const QString& name, const QString& address) { QString key = name.toLower(); - if (isValidName(name)) { - QJsonObject bookmark; - bookmark.insert("name", name); - bookmark.insert("address", address); - _bookmarks.insert(key, bookmark); + QJsonObject bookmark; + bookmark.insert("name", name); + bookmark.insert("address", address); + _bookmarks.insert(key, bookmark); - if (contains(key)) { - qDebug() << "Added bookmark: " << name << ", " << address; - } else { - qDebug() << "Couldn't add bookmark: " << name << ", " << address; - } + if (contains(key)) { + qDebug() << "Added bookmark: " << name << ", " << address; } else { - qDebug() << "Invalid bookmark: " << name << ", " << address; + qDebug() << "Couldn't add bookmark: " << name << ", " << address; } } -void Bookmarks::remove(QString name) { +void Bookmarks::remove(const QString& name) { QString key = name.toLower(); _bookmarks.remove(key); @@ -45,10 +41,6 @@ void Bookmarks::remove(QString name) { } } -bool Bookmarks::contains(QString name) { +bool Bookmarks::contains(const QString& name) const { return _bookmarks.contains(name.toLower()); } - -bool Bookmarks::isValidName(QString name) { - return _nameRegExp.exactMatch(name); -} diff --git a/interface/src/Bookmarks.h b/interface/src/Bookmarks.h index a2def873b0..f9c40d7523 100644 --- a/interface/src/Bookmarks.h +++ b/interface/src/Bookmarks.h @@ -16,7 +16,6 @@ #include #include #include -#include class Bookmarks: public QObject { Q_OBJECT @@ -24,16 +23,13 @@ class Bookmarks: public QObject { public: Bookmarks(); - void insert(QString name, QString address); // Overwrites any existing entry with same name. - void remove(QString name); - - bool contains(QString name); - bool isValidName(QString name); + void insert(const QString& name, const QString& address); // Overwrites any existing entry with same name. + void remove(const QString& name); + bool contains(const QString& name) const; private: QMap _bookmarks; // key: { name: string, address: string } // key is a lowercase copy of name, used to make the bookmarks case insensitive. - const QRegExp _nameRegExp = QRegExp("^[\\w\\-]+$"); }; #endif // hifi_Bookmarks_h \ No newline at end of file diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 996bb6a641..fa93778085 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -123,6 +123,10 @@ Menu::Menu() : appInstance, SLOT(toggleRunningScriptsWidget())); addDisabledActionAndSeparator(fileMenu, "Go"); + addActionToQMenuAndActionHash(fileMenu, MenuOption::BookmarkLocation, 0, + this, SLOT(bookmarkLocation())); + _bookmarksMenu = fileMenu->addMenu(MenuOption::Bookmarks); + _bookmarksMenu->setEnabled(false); addActionToQMenuAndActionHash(fileMenu, MenuOption::NameLocation, Qt::CTRL | Qt::Key_N, @@ -1010,6 +1014,53 @@ void Menu::changeVSync() { Application::getInstance()->setVSyncEnabled(isOptionChecked(MenuOption::RenderTargetFramerateVSyncOn)); } +void Menu::bookmarkLocation() { + + QInputDialog bookmarkLocationDialog(Application::getInstance()->getWindow()); + bookmarkLocationDialog.setWindowTitle("Bookmark Location"); + bookmarkLocationDialog.setLabelText("Name:"); + bookmarkLocationDialog.setInputMode(QInputDialog::TextInput); + bookmarkLocationDialog.resize(400, 200); + + if (bookmarkLocationDialog.exec() == QDialog::Rejected) { + return; + } + + QString bookmarkName = bookmarkLocationDialog.textValue().trimmed(); + if (bookmarkName.length() == 0) { + return; + } + + AddressManager::SharedPointer addressManager = DependencyManager::get(); + QString bookmarkAddress = addressManager->currentAddress().toString(); + + Bookmarks* bookmarks = Application::getInstance()->getBookmarks(); + if (bookmarks->contains(bookmarkName)) { + QMessageBox duplicateBookmarkMessage; + duplicateBookmarkMessage.setIcon(QMessageBox::Warning); + duplicateBookmarkMessage.setText("The bookmark name you entered already exists in your list."); + duplicateBookmarkMessage.setInformativeText("Would you like to overwrite it?"); + duplicateBookmarkMessage.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + duplicateBookmarkMessage.setDefaultButton(QMessageBox::Yes); + if (duplicateBookmarkMessage.exec() == QMessageBox::No) { + return; + } + removeAction(_bookmarksMenu, bookmarkName); + } + + bookmarks->insert(bookmarkName, bookmarkAddress); + + QList menuItems = _bookmarksMenu->actions(); + int position = 0; + while (position < menuItems.count() && bookmarkName > menuItems[position]->text()) { + position += 1; + } + addActionToQMenuAndActionHash(_bookmarksMenu, bookmarkName, 0, + this, NULL, QAction::NoRole, position); + + _bookmarksMenu->setEnabled(true); +} + void Menu::displayNameLocationResponse(const QString& errorString) { if (!errorString.isEmpty()) { diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 6f30ca983b..52a785860e 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -200,6 +200,7 @@ private slots: void editAttachments(); void editAnimations(); void changePrivateKey(); + void bookmarkLocation(); void nameLocation(); void toggleLocationList(); void hmdToolsClosed(); @@ -307,6 +308,8 @@ private: bool _shouldRenderTableNeedsRebuilding = true; QMap _shouldRenderTable; + + QMenu* _bookmarksMenu; }; namespace MenuOption { @@ -334,6 +337,8 @@ namespace MenuOption { const QString Bandwidth = "Bandwidth Display"; const QString BandwidthDetails = "Bandwidth Details"; const QString BlueSpeechSphere = "Blue Sphere While Speaking"; + const QString BookmarkLocation = "Bookmark Location"; + const QString Bookmarks = "Bookmarks"; const QString CascadedShadows = "Cascaded"; const QString CachesSize = "Caches Size"; const QString Chat = "Chat..."; From 01f7efe76757f4ad7c31a1d3ee8e3c30bb035e7c Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 13 Jan 2015 22:48:05 -0800 Subject: [PATCH 28/93] Remove ellipsis from Collide With menu item Noticed in passing. --- interface/src/Menu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index fa93778085..7fc3c9bfd1 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -265,7 +265,7 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(avatarMenu, MenuOption::ShiftHipsForIdleAnimations, 0, false, avatar, SLOT(updateMotionBehavior())); - QMenu* collisionsMenu = avatarMenu->addMenu("Collide With..."); + QMenu* collisionsMenu = avatarMenu->addMenu("Collide With"); addCheckableActionToQMenuAndActionHash(collisionsMenu, MenuOption::CollideAsRagdoll, 0, false, avatar, SLOT(onToggleRagdoll())); addCheckableActionToQMenuAndActionHash(collisionsMenu, MenuOption::CollideWithAvatars, From a78ab5a5b3e706c2ba9e35f09ec9cc91646e6a53 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 14 Jan 2015 10:14:56 -0800 Subject: [PATCH 29/93] Teleport to selected bookmark --- interface/src/Menu.cpp | 15 +++++++++++++-- interface/src/Menu.h | 1 + 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 7fc3c9bfd1..c8c08e4828 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -1050,17 +1050,28 @@ void Menu::bookmarkLocation() { bookmarks->insert(bookmarkName, bookmarkAddress); + QAction* teleportAction = new QAction(getMenu(MenuOption::Bookmarks)); + teleportAction->setData(bookmarkAddress); + connect(teleportAction, SIGNAL(triggered()), this, SLOT(teleportToBookmark())); + QList menuItems = _bookmarksMenu->actions(); int position = 0; while (position < menuItems.count() && bookmarkName > menuItems[position]->text()) { position += 1; } - addActionToQMenuAndActionHash(_bookmarksMenu, bookmarkName, 0, - this, NULL, QAction::NoRole, position); + + addActionToQMenuAndActionHash(_bookmarksMenu, teleportAction, bookmarkName, 0, + QAction::NoRole, position); _bookmarksMenu->setEnabled(true); } +void Menu::teleportToBookmark() { + QAction *action = qobject_cast(sender()); + QString url = action->data().toString(); + DependencyManager::get()->handleLookupString(url); +} + void Menu::displayNameLocationResponse(const QString& errorString) { if (!errorString.isEmpty()) { diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 52a785860e..4f79125819 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -201,6 +201,7 @@ private slots: void editAnimations(); void changePrivateKey(); void bookmarkLocation(); + void teleportToBookmark(); void nameLocation(); void toggleLocationList(); void hmdToolsClosed(); From 7be1f41659ca01574e103d8551eee7e8fd28e7ba Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 14 Jan 2015 10:22:27 -0800 Subject: [PATCH 30/93] using the Material class --- libraries/render-utils/src/model_lightmap.slf | 12 ++++++++---- .../src/model_lightmap_normal_map.slf | 13 ++++++++----- .../model_lightmap_normal_specular_map.slf | 18 ++++++++---------- .../src/model_lightmap_specular_map.slf | 18 ++++++++---------- .../render-utils/src/model_normal_map.slf | 19 +++++++++---------- .../src/model_normal_specular_map.slf | 18 +++++++++--------- .../render-utils/src/model_specular_map.slf | 19 +++++++++---------- 7 files changed, 59 insertions(+), 58 deletions(-) diff --git a/libraries/render-utils/src/model_lightmap.slf b/libraries/render-utils/src/model_lightmap.slf index 6b25921318..59836e9737 100755 --- a/libraries/render-utils/src/model_lightmap.slf +++ b/libraries/render-utils/src/model_lightmap.slf @@ -14,6 +14,8 @@ <@include DeferredBufferWrite.slh@> +<@include Material.slh@> + // the diffuse texture uniform sampler2D diffuseMap; @@ -32,11 +34,13 @@ void main(void) { vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); vec4 emissive = texture2D(emissiveMap, interpolatedTexcoord1.st); + Material mat = getMaterial(); + packDeferredFragmentLightmap( normalize(normal.xyz), - evalOpaqueFinalAlpha(gl_Color.a, diffuse.a), - gl_Color.rgb * diffuse.rgb, - gl_FrontMaterial.specular.rgb, - gl_FrontMaterial.shininess, + evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a), + getMaterialDiffuse(mat) * diffuse.rgb, + getMaterialSpecular(mat), + getMaterialShininess(mat), (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); } diff --git a/libraries/render-utils/src/model_lightmap_normal_map.slf b/libraries/render-utils/src/model_lightmap_normal_map.slf index 9ef75802a8..6310ab0086 100755 --- a/libraries/render-utils/src/model_lightmap_normal_map.slf +++ b/libraries/render-utils/src/model_lightmap_normal_map.slf @@ -14,6 +14,8 @@ <@include DeferredBufferWrite.slh@> +<@include Material.slh@> + // the diffuse texture uniform sampler2D diffuseMap; @@ -45,12 +47,13 @@ void main(void) { vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); vec4 emissive = texture2D(emissiveMap, interpolatedTexcoord1.st); + Material mat = getMaterial(); + packDeferredFragmentLightmap( normalize(viewNormal.xyz), - evalOpaqueFinalAlpha(gl_Color.a, diffuse.a), - //gl_Color.rgb * diffuse.rgb, - vec3(1.0, 0.0, 0.0), - gl_FrontMaterial.specular.rgb, - gl_FrontMaterial.shininess, + evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a), + getMaterialDiffuse(mat) * diffuse.rgb, + getMaterialSpecular(mat), + getMaterialShininess(mat), (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); } diff --git a/libraries/render-utils/src/model_lightmap_normal_specular_map.slf b/libraries/render-utils/src/model_lightmap_normal_specular_map.slf index 3bc72384f7..ab555ea0c0 100755 --- a/libraries/render-utils/src/model_lightmap_normal_specular_map.slf +++ b/libraries/render-utils/src/model_lightmap_normal_specular_map.slf @@ -14,6 +14,8 @@ <@include DeferredBufferWrite.slh@> +<@include Material.slh@> + // the diffuse texture uniform sampler2D diffuseMap; @@ -49,17 +51,13 @@ void main(void) { vec3 specular = texture2D(specularMap, gl_TexCoord[0].st).rgb; vec4 emissive = texture2D(emissiveMap, interpolatedTexcoord1.st); + Material mat = getMaterial(); + packDeferredFragmentLightmap( normalize(viewNormal.xyz), - evalOpaqueFinalAlpha(gl_Color.a, diffuse.a), - gl_Color.rgb * diffuse.rgb, - specular, - gl_FrontMaterial.shininess, + evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a), + getMaterialDiffuse(mat) * diffuse.rgb, + specular, // no use of getMaterialSpecular(mat) + getMaterialShininess(mat), (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); -/* - gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb * (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb), mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); - gl_FragData[1] = viewNormal + vec4(0.5, 0.5, 0.5, 1.0); - gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, - gl_FrontMaterial.shininess / 128.0); -*/ } diff --git a/libraries/render-utils/src/model_lightmap_specular_map.slf b/libraries/render-utils/src/model_lightmap_specular_map.slf index 7322da6b3a..2973882e8a 100755 --- a/libraries/render-utils/src/model_lightmap_specular_map.slf +++ b/libraries/render-utils/src/model_lightmap_specular_map.slf @@ -14,6 +14,8 @@ <@include DeferredBufferWrite.slh@> +<@include Material.slh@> + // the diffuse texture uniform sampler2D diffuseMap; @@ -35,17 +37,13 @@ void main(void) { vec3 specular = texture2D(specularMap, gl_TexCoord[0].st).rgb; vec4 emissive = texture2D(emissiveMap, interpolatedTexcoord1.st); + Material mat = getMaterial(); + packDeferredFragmentLightmap( normalize(normal.xyz), - evalOpaqueFinalAlpha(gl_Color.a, diffuse.a), - gl_Color.rgb * diffuse.rgb, - specular, - gl_FrontMaterial.shininess, + evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a), + getMaterialDiffuse(mat) * diffuse.rgb, + specular, // no use of getMaterialSpecular(mat) + getMaterialShininess(mat), (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb)); -/* - gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb * (vec3(emissiveParams.x) + emissiveParams.y * emissive.rgb), mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); - gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); - gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, - gl_FrontMaterial.shininess / 128.0); -*/ } diff --git a/libraries/render-utils/src/model_normal_map.slf b/libraries/render-utils/src/model_normal_map.slf index 74da394850..c6baa6f797 100755 --- a/libraries/render-utils/src/model_normal_map.slf +++ b/libraries/render-utils/src/model_normal_map.slf @@ -14,6 +14,8 @@ <@include DeferredBufferWrite.slh@> +<@include Material.slh@> + // the diffuse texture uniform sampler2D diffuseMap; @@ -34,18 +36,15 @@ void main(void) { vec3 localNormal = vec3(texture2D(normalMap, gl_TexCoord[0].st)) - vec3(0.5, 0.5, 0.5); vec4 viewNormal = vec4(normalizedTangent * localNormal.x + normalizedBitangent * localNormal.y + normalizedNormal * localNormal.z, 0.0); - - // set the diffuse, normal, specular data + vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); -/* gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); - gl_FragData[1] = viewNormal + vec4(0.5, 0.5, 0.5, 1.0); - gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb, gl_FrontMaterial.shininess / 128.0); - */ + + Material mat = getMaterial(); packDeferredFragment( normalize(viewNormal.xyz), - evalOpaqueFinalAlpha(gl_Color.a, diffuse.a), - gl_Color.rgb * diffuse.rgb, - gl_FrontMaterial.specular.rgb, - gl_FrontMaterial.shininess); + evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a), + getMaterialDiffuse(mat) * diffuse.rgb, + getMaterialSpecular(mat), + getMaterialShininess(mat)); } diff --git a/libraries/render-utils/src/model_normal_specular_map.slf b/libraries/render-utils/src/model_normal_specular_map.slf index 4248edfc90..8e7c9d3293 100755 --- a/libraries/render-utils/src/model_normal_specular_map.slf +++ b/libraries/render-utils/src/model_normal_specular_map.slf @@ -14,6 +14,8 @@ <@include DeferredBufferWrite.slh@> +<@include Material.slh@> + // the diffuse texture uniform sampler2D diffuseMap; @@ -41,15 +43,13 @@ void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); vec3 specular = texture2D(specularMap, gl_TexCoord[0].st).rgb; -/* gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); - gl_FragData[1] = viewNormal + vec4(0.5, 0.5, 0.5, 1.0); - gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, - gl_FrontMaterial.shininess / 128.0); - */ + + Material mat = getMaterial(); + packDeferredFragment( normalize(viewNormal.xyz), - evalOpaqueFinalAlpha(gl_Color.a, diffuse.a), - gl_Color.rgb * diffuse.rgb, - specular, - gl_FrontMaterial.shininess); + evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a), + getMaterialDiffuse(mat) * diffuse.rgb, + specular, //getMaterialSpecular(mat), + getMaterialShininess(mat)); } diff --git a/libraries/render-utils/src/model_specular_map.slf b/libraries/render-utils/src/model_specular_map.slf index db1c2df9c5..bfcc69287d 100755 --- a/libraries/render-utils/src/model_specular_map.slf +++ b/libraries/render-utils/src/model_specular_map.slf @@ -14,6 +14,8 @@ <@include DeferredBufferWrite.slh@> +<@include Material.slh@> + // the diffuse texture uniform sampler2D diffuseMap; @@ -27,16 +29,13 @@ void main(void) { // set the diffuse, normal, specular data vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); vec3 specular = texture2D(specularMap, gl_TexCoord[0].st).rgb; -/* - gl_FragData[0] = vec4(gl_Color.rgb * diffuse.rgb, mix(gl_Color.a, 1.0 - gl_Color.a, step(diffuse.a, alphaThreshold))); - gl_FragData[1] = normalize(normal) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); - gl_FragData[2] = vec4(gl_FrontMaterial.specular.rgb * texture2D(specularMap, gl_TexCoord[0].st).rgb, - gl_FrontMaterial.shininess / 128.0); - */ + + Material mat = getMaterial(); + packDeferredFragment( normalize(normal.xyz), - evalOpaqueFinalAlpha(gl_Color.a, diffuse.a), - gl_Color.rgb * diffuse.rgb, - specular, - gl_FrontMaterial.shininess); + evalOpaqueFinalAlpha(getMaterialOpacity(mat), diffuse.a), + getMaterialDiffuse(mat) * diffuse.rgb, + specular, //getMaterialSpecular(mat), + getMaterialShininess(mat)); } From 10f8e54903f7f7422b4be2ac0819d1d7d9bceb50 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 14 Jan 2015 15:50:42 -0800 Subject: [PATCH 31/93] Update style of properties windows --- examples/html/entityProperties.html | 468 +++++++++++++--------------- examples/html/style.css | 24 +- 2 files changed, 226 insertions(+), 266 deletions(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index c23a3cd5ab..2df5524795 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -181,10 +181,10 @@ elLocked.checked = properties.locked; if (properties.locked) { - disableChildren(document.getElementById("properties-table"), 'input'); + disableChildren(document.getElementById("properties-list"), 'input'); elLocked.removeAttribute('disabled'); } else { - enableChildren(document.getElementById("properties-table"), 'input'); + enableChildren(document.getElementById("properties-list"), 'input'); } elVisible.checked = properties.visible; @@ -231,7 +231,7 @@ } } else { for (var i = 0; i < elBoxSections.length; i++) { - elBoxSections[i].style.display = 'table-row'; + elBoxSections[i].style.display = 'block'; } elBoxColorRed.value = properties.color.red; @@ -245,7 +245,7 @@ } } else { for (var i = 0; i < elModelSections.length; i++) { - elModelSections[i].style.display = 'table-row'; + elModelSections[i].style.display = 'block'; } elModelURL.value = properties.modelURL; @@ -264,7 +264,7 @@ } } else { for (var i = 0; i < elTextSections.length; i++) { - elTextSections[i].style.display = 'table-row'; + elTextSections[i].style.display = 'block'; } elTextText.value = properties.text; @@ -283,7 +283,7 @@ } } else { for (var i = 0; i < elLightSections.length; i++) { - elLightSections[i].style.display = 'table-row'; + elLightSections[i].style.display = 'block'; } elLightDiffuseRed.value = properties.diffuseColor.red; @@ -442,50 +442,6 @@ percentage: parseInt(elRescaleDimensionsPct.value), })); }); - - var resizing = false; - var startX = 0; - var originalWidth = 0; - var resizeHandleWidth = 10; - - var col1 = document.querySelector("#col-label"); - - document.body.addEventListener('mousemove', function(event) { - if (resizing) { - var dX = event.x - startX; - col1.style.width = (originalWidth + dX) + "px"; - } - }); - document.body.addEventListener('mouseup', function(event) { - resizing = false; - }); - document.body.addEventListener('mouseleave', function(event) { - resizing = false; - }); - var els = document.querySelectorAll("#properties-table td"); - for (var i = 0; i < els.length; i++) { - var el = els[i]; - el.addEventListener('mousemove', function(event) { - if (!resizing) { - var distance = this.offsetWidth - event.offsetX; - if (distance < resizeHandleWidth) { - document.body.style.cursor = "ew-resize"; - } else { - document.body.style.cursor = "initial"; - } - } - }); - el.addEventListener('mousedown', function(event) { - var distance = this.offsetWidth - event.offsetX; - if (distance < resizeHandleWidth) { - startX = event.x; - originalWidth = this.offsetWidth; - resizing = true; - target = this; - } - }); - } - } @@ -493,44 +449,40 @@
- - - - - - - - - - - - - - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - - - - - - - - - - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+
+
ID -
+ +
-
+ + +
+
Type -
+ +
-
Locked + + +
+
Locked
+
-
Visible +
+
Visible
+
-
Position +
+
Position
+
X
Y
Z
@@ -538,21 +490,21 @@
-
Registration +
+
Registration
+
X
Y
Z
-
Dimensions +
+
Dimensions
+
X
Y
Z
@@ -565,243 +517,243 @@ -
Rotation +
+
Rotation
+
Pitch
Yaw
Roll
-
Linear Velocity +
+
Linear Velocity
+
X
Y
Z
-
Linear Damping + + +
+
Linear Damping
+
-
Angular Velocity + + +
+
Angular Velocity
+
Pitch
Yaw
Roll
-
Angular Damping + + +
+
Angular Damping
+
-
Gravity +
+
Gravity
+
X
Y
Z
-
Mass +
+
Mass
+
-
Ignore For Collisions +
+
Ignore For Collisions
+
-
Collisions Will Move +
+
Collisions Will Move
+
-
Lifetime +
+
Lifetime
+
-
Script URL +
+
Script URL
+
-
Color +
+
Color
+
R
G
B
-
Model URL +
+
Model URL
+
-
Animation URL + + +
+
Animation URL
+
-
Animation Playing + + +
+
Animation Playing
+
-
Animation FPS + + +
+
Animation FPS
+
-
Animation Frame + + +
+
Animation Frame
+
-
Animation Settings + + +
+
Animation Settings
+
-
Textures + + +
+
Textures
+
-
Original Textures + + +
+
Original Textures
+
-
Text +
+
Text
+
-
Line Height + + +
+
Line Height
+
-
Text Color + + +
+
Text Color
+
R
G
B
-
Background Color + + +
+
Background Color
+
R
G
B
-
Spot Light +
+
Spot Light
+
-
Diffuse + + +
+
Diffuse
+
R
G
B
-
Ambient + + +
+
Ambient
+
R
G
B
-
Specular + + +
+
Specular
+
R
G
B
-
Constant Attenuation + + +
+
Constant Attenuation
+
-
Linear Attenuation + + +
+
Linear Attenuation
+
-
Quadratic Attenuation + + +
+
Quadratic Attenuation
+
-
Exponent + + +
+
Exponent
+
-
Cutoff (degrees) + + +
+
Cutoff (degrees)
+
-
+ + + diff --git a/examples/html/style.css b/examples/html/style.css index 7ffbacb15e..20baaca915 100644 --- a/examples/html/style.css +++ b/examples/html/style.css @@ -152,7 +152,7 @@ input { -table#properties-table { +table#properties-list { border: none; border-collapse: collapse; width: 100%; @@ -162,14 +162,11 @@ table#properties-table { table-layout: fixed; } -#properties-table tr { +#properties-list { border-bottom: 1px solid #e5e5e5; } -#properties-table td.label { - padding-right: 10px; - border-right: 1px solid #999; - text-align: right; +#properties-list .label { font-weight: bold; white-space: nowrap; overflow: hidden; @@ -177,10 +174,21 @@ table#properties-table { vertical-align: middle; height: 1.2em; + background-color: #ccc; + border-bottom: 1px solid #e5e5e5; } -#properties-table td { - padding: 5px; +#properties-list .value { + min-height: 1em; +} + +#properties-list .value > div{ + padding: 4px; +} + +#properties-list > div > div{ + padding: 3px; + border-bottom: 1px solid black; } col#col-label { From 614e1aa6ae3e7e31b59a17da95bce01f574cabb2 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 14 Jan 2015 16:44:44 -0800 Subject: [PATCH 32/93] Cleaning the Model rendering path from any use of glMaterial --- .../render-utils/src/DeferredBufferWrite.slh | 6 ++++++ .../src/DeferredLightingEffect.cpp | 4 +++- libraries/render-utils/src/Material.slh | 1 + libraries/render-utils/src/model.slv | 2 +- libraries/render-utils/src/model_lightmap.slv | 2 +- .../src/model_lightmap_normal_map.slv | 2 +- .../render-utils/src/model_normal_map.slv | 2 +- .../render-utils/src/model_translucent.slf | 21 ++++++++++++++++++- libraries/render-utils/src/skin_model.slv | 4 ++-- .../src/skin_model_normal_map.slv | 4 ++-- 10 files changed, 38 insertions(+), 10 deletions(-) diff --git a/libraries/render-utils/src/DeferredBufferWrite.slh b/libraries/render-utils/src/DeferredBufferWrite.slh index 7b4ca7ba3b..066e0198b1 100755 --- a/libraries/render-utils/src/DeferredBufferWrite.slh +++ b/libraries/render-utils/src/DeferredBufferWrite.slh @@ -34,4 +34,10 @@ void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 diffuse, vec3 s gl_FragData[2] = vec4(emissive, shininess / 128.0); } +void packDeferredFragmentTranslucent(vec3 normal, float alpha, vec3 diffuse, vec3 specular, float shininess) { + gl_FragData[0] = vec4(diffuse.rgb, alpha); + // gl_FragData[1] = vec4(normal, 0.0) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0); + // gl_FragData[2] = vec4(specular, shininess / 128.0); +} + <@endif@> diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index fc84489a2f..8200595ec2 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -169,7 +169,8 @@ void DeferredLightingEffect::render() { QOpenGLFramebufferObject* freeFBO = DependencyManager::get()->getFreeFramebufferObject(); freeFBO->bind(); glClear(GL_COLOR_BUFFER_BIT); - + glEnable(GL_FRAMEBUFFER_SRGB); + glBindTexture(GL_TEXTURE_2D, primaryFBO->texture()); glActiveTexture(GL_TEXTURE1); @@ -371,6 +372,7 @@ void DeferredLightingEffect::render() { glBindTexture(GL_TEXTURE_2D, 0); freeFBO->release(); + glDisable(GL_FRAMEBUFFER_SRGB); glDisable(GL_CULL_FACE); diff --git a/libraries/render-utils/src/Material.slh b/libraries/render-utils/src/Material.slh index e77b664ee1..923158af19 100755 --- a/libraries/render-utils/src/Material.slh +++ b/libraries/render-utils/src/Material.slh @@ -23,6 +23,7 @@ vec3 getMaterialSpecular(Material m) { return m._specular.rgb; } float getMaterialShininess(Material m) { return m._specular.a; } + <@if GLPROFILE == PC_GL@> uniform materialBuffer { Material mat; diff --git a/libraries/render-utils/src/model.slv b/libraries/render-utils/src/model.slv index 496667a062..1c3b03a304 100755 --- a/libraries/render-utils/src/model.slv +++ b/libraries/render-utils/src/model.slv @@ -23,7 +23,7 @@ void main(void) { normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0)); // pass along the diffuse color - gl_FrontColor = gl_Color * gl_FrontMaterial.diffuse; + gl_FrontColor = gl_Color; // and the texture coordinates gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0); diff --git a/libraries/render-utils/src/model_lightmap.slv b/libraries/render-utils/src/model_lightmap.slv index 9f19ae8de2..23d99b399a 100755 --- a/libraries/render-utils/src/model_lightmap.slv +++ b/libraries/render-utils/src/model_lightmap.slv @@ -29,7 +29,7 @@ void main(void) { normal = normalize(gl_ModelViewMatrix * vec4(gl_Normal, 0.0)); // pass along the diffuse color - gl_FrontColor = gl_Color * gl_FrontMaterial.diffuse; + gl_FrontColor = gl_Color; // and the texture coordinates gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0); diff --git a/libraries/render-utils/src/model_lightmap_normal_map.slv b/libraries/render-utils/src/model_lightmap_normal_map.slv index c19336ddae..14e1d52779 100755 --- a/libraries/render-utils/src/model_lightmap_normal_map.slv +++ b/libraries/render-utils/src/model_lightmap_normal_map.slv @@ -36,7 +36,7 @@ void main(void) { interpolatedTangent = gl_ModelViewMatrix * vec4(tangent, 0.0); // pass along the diffuse color - gl_FrontColor = gl_Color * gl_FrontMaterial.diffuse; + gl_FrontColor = gl_Color; // and the texture coordinates gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0); diff --git a/libraries/render-utils/src/model_normal_map.slv b/libraries/render-utils/src/model_normal_map.slv index 0eb974912f..a27cd49171 100755 --- a/libraries/render-utils/src/model_normal_map.slv +++ b/libraries/render-utils/src/model_normal_map.slv @@ -31,7 +31,7 @@ void main(void) { interpolatedTangent = gl_ModelViewMatrix * vec4(tangent, 0.0); // pass along the diffuse color - gl_FrontColor = gl_Color * gl_FrontMaterial.diffuse; + gl_FrontColor = gl_Color; // and the texture coordinates gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0); diff --git a/libraries/render-utils/src/model_translucent.slf b/libraries/render-utils/src/model_translucent.slf index 497f5962bc..4d1bf7bdec 100755 --- a/libraries/render-utils/src/model_translucent.slf +++ b/libraries/render-utils/src/model_translucent.slf @@ -12,10 +12,29 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +<@include DeferredBufferWrite.slh@> + +<@include Material.slh@> + // the diffuse texture uniform sampler2D diffuseMap; +varying vec4 normal; + void main(void) { + + // Fetch diffuse map + vec4 diffuse = texture2D(diffuseMap, gl_TexCoord[0].st); + + Material mat = getMaterial(); + + packDeferredFragmentTranslucent( + normalize(normal.xyz), + getMaterialOpacity(mat) * diffuse.a, + getMaterialDiffuse(mat) * diffuse.rgb, + getMaterialSpecular(mat), + getMaterialShininess(mat)); + // set the diffuse data - gl_FragData[0] = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].st); + // gl_FragData[0] = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].st); } diff --git a/libraries/render-utils/src/skin_model.slv b/libraries/render-utils/src/skin_model.slv index 4144198969..4cef8fddab 100755 --- a/libraries/render-utils/src/skin_model.slv +++ b/libraries/render-utils/src/skin_model.slv @@ -38,8 +38,8 @@ void main(void) { normal = normalize(gl_ModelViewMatrix * normal); // pass along the diffuse color - gl_FrontColor = gl_FrontMaterial.diffuse; - + gl_FrontColor = gl_Color; + // and the texture coordinates gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0); diff --git a/libraries/render-utils/src/skin_model_normal_map.slv b/libraries/render-utils/src/skin_model_normal_map.slv index b021184591..c39f9cc0dd 100755 --- a/libraries/render-utils/src/skin_model_normal_map.slv +++ b/libraries/render-utils/src/skin_model_normal_map.slv @@ -46,8 +46,8 @@ void main(void) { interpolatedTangent = gl_ModelViewMatrix * interpolatedTangent; // pass along the diffuse color - gl_FrontColor = gl_FrontMaterial.diffuse; - + gl_FrontColor = gl_Color; + // and the texture coordinates gl_TexCoord[0] = texcoordMatrices[0] * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0); From b8b5b2b6ecd3d815092d4932a19404843f9c13ae Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 14 Jan 2015 16:56:49 -0800 Subject: [PATCH 33/93] don't check the root object for path --- libraries/networking/src/AddressManager.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 4802f3ca15..76a974c7ef 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -225,13 +225,7 @@ void AddressManager::goToAddressFromObject(const QVariantMap& dataObject) { // take the path that came back const QString PLACE_PATH_KEY = "path"; - QString returnedPath; - - if (locationMap.contains(PLACE_PATH_KEY) && !locationMap[PLACE_PATH_KEY].toString().isEmpty()) { - returnedPath = locationMap[PLACE_PATH_KEY].toString(); - } else if (rootMap.contains(PLACE_PATH_KEY) && !rootMap[PLACE_PATH_KEY].toString().isEmpty()) { - returnedPath = rootMap[PLACE_PATH_KEY].toString(); - } + QString returnedPath = locationMap[PLACE_PATH_KEY].toString(); bool shouldFaceViewpoint = locationMap.contains(LOCATION_API_ONLINE_KEY); From e5fe24e088166ab167af7b3a0254fa79a3369fc5 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 14 Jan 2015 16:58:15 -0800 Subject: [PATCH 34/93] remove My Locations and Name This Location --- interface/src/Menu.cpp | 70 ------------------------------------------ interface/src/Menu.h | 4 --- 2 files changed, 74 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 996bb6a641..2079805379 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -123,16 +123,6 @@ Menu::Menu() : appInstance, SLOT(toggleRunningScriptsWidget())); addDisabledActionAndSeparator(fileMenu, "Go"); - addActionToQMenuAndActionHash(fileMenu, - MenuOption::NameLocation, - Qt::CTRL | Qt::Key_N, - this, - SLOT(nameLocation())); - addActionToQMenuAndActionHash(fileMenu, - MenuOption::MyLocations, - Qt::CTRL | Qt::Key_K, - this, - SLOT(toggleLocationList())); addActionToQMenuAndActionHash(fileMenu, MenuOption::AddressBar, Qt::Key_Enter, @@ -1019,66 +1009,6 @@ void Menu::displayNameLocationResponse(const QString& errorString) { } } -void Menu::toggleLocationList() { - if (!_userLocationsDialog) { - JavascriptObjectMap locationObjectMap; - locationObjectMap.insert("InterfaceLocation", DependencyManager::get().data()); - _userLocationsDialog = DataWebDialog::dialogForPath("/user/locations", locationObjectMap); - } - - if (!_userLocationsDialog->isVisible()) { - _userLocationsDialog->show(); - } - - _userLocationsDialog->raise(); - _userLocationsDialog->activateWindow(); - _userLocationsDialog->showNormal(); - -} - -void Menu::nameLocation() { - // check if user is logged in or show login dialog if not - - AccountManager& accountManager = AccountManager::getInstance(); - - if (!accountManager.isLoggedIn()) { - QMessageBox msgBox; - msgBox.setText("We need to tie this location to your username."); - msgBox.setInformativeText("Please login first, then try naming the location again."); - msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); - msgBox.button(QMessageBox::Ok)->setText("Login"); - - if (msgBox.exec() == QMessageBox::Ok) { - loginForCurrentDomain(); - } - - return; - } - - DomainHandler& domainHandler = NodeList::getInstance()->getDomainHandler(); - if (domainHandler.getUUID().isNull()) { - const QString UNREGISTERED_DOMAIN_MESSAGE = "This domain is not registered with High Fidelity." - "\n\nYou cannot create a global location in an unregistered domain."; - QMessageBox::critical(this, "Unregistered Domain", UNREGISTERED_DOMAIN_MESSAGE); - - return; - } - - if (!_newLocationDialog) { - JavascriptObjectMap locationObjectMap; - locationObjectMap.insert("InterfaceLocation", DependencyManager::get().data()); - _newLocationDialog = DataWebDialog::dialogForPath("/user/locations/new", locationObjectMap); - } - - if (!_newLocationDialog->isVisible()) { - _newLocationDialog->show(); - } - - _newLocationDialog->raise(); - _newLocationDialog->activateWindow(); - _newLocationDialog->showNormal(); -} - void Menu::toggleLoginMenuItem() { AccountManager& accountManager = AccountManager::getInstance(); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 6f30ca983b..6f4af7f7cf 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -286,8 +286,6 @@ private: QPointer _attachmentsDialog; QPointer _bandwidthDialog; QPointer _cachesSizeDialog; - QPointer _newLocationDialog; - QPointer _userLocationsDialog; QPointer _hmdToolsDialog; QPointer _lodToolsDialog; QPointer _loginDialog; @@ -397,8 +395,6 @@ namespace MenuOption { const QString Mirror = "Mirror"; const QString MuteAudio = "Mute Microphone"; const QString MuteEnvironment = "Mute Environment"; - const QString MyLocations = "My Locations..."; - const QString NameLocation = "Name this location"; const QString NetworkSimulator = "Network Simulator..."; const QString NewVoxelCullingMode = "New Voxel Culling Mode"; const QString ObeyEnvironmentalGravity = "Obey Environmental Gravity"; From 69869a696beab33aee60ef58c3fd6cc0785308dc Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 14 Jan 2015 17:00:21 -0800 Subject: [PATCH 35/93] remove name this location call from application --- interface/src/Application.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c24dd69649..9ad4fe96cb 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -884,13 +884,6 @@ void Application::keyPressEvent(QKeyEvent* event) { Menu::getInstance()->triggerOption(MenuOption::Chat); break; - case Qt::Key_N: - if (isMeta) { - Menu::getInstance()->triggerOption(MenuOption::NameLocation); - } - - break; - case Qt::Key_Up: if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { if (!isShifted) { From ef87b59a0c2b854fcc2c91c180796a494b6fb782 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 14 Jan 2015 17:02:18 -0800 Subject: [PATCH 36/93] remove method declarations for location changes --- interface/src/Menu.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 6f4af7f7cf..3ac47f752a 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -200,8 +200,6 @@ private slots: void editAttachments(); void editAnimations(); void changePrivateKey(); - void nameLocation(); - void toggleLocationList(); void hmdToolsClosed(); void runTests(); void showMetavoxelEditor(); From 8ffea45736c3b7cbc2abed12e4473f4ab5a35ae4 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Thu, 15 Jan 2015 02:59:37 +0100 Subject: [PATCH 37/93] QFileDialog include --- interface/src/devices/RealSense.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/devices/RealSense.h b/interface/src/devices/RealSense.h index 015f1e7ce6..4a43a1e117 100644 --- a/interface/src/devices/RealSense.h +++ b/interface/src/devices/RealSense.h @@ -12,7 +12,7 @@ #ifndef hifi_RealSense_h #define hifi_RealSense_h -#include +#include #include "MotionTracker.h" From da58d5a38150e5e8125f0388f622faf289806f61 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 14 Jan 2015 18:15:39 -0800 Subject: [PATCH 38/93] Delete Bookmark menu item and dialog box --- interface/src/Menu.cpp | 45 ++++++++++++++++++++++++++++++++++++++++-- interface/src/Menu.h | 3 +++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index c8c08e4828..d45880a0b2 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -127,6 +127,10 @@ Menu::Menu() : this, SLOT(bookmarkLocation())); _bookmarksMenu = fileMenu->addMenu(MenuOption::Bookmarks); _bookmarksMenu->setEnabled(false); + _deleteBookmarksMenu = addActionToQMenuAndActionHash(fileMenu, + MenuOption::DeleteBookmark, 0, + this, SLOT(deleteBookmark())); + _deleteBookmarksMenu->setEnabled(false); addActionToQMenuAndActionHash(fileMenu, MenuOption::NameLocation, Qt::CTRL | Qt::Key_N, @@ -1048,8 +1052,6 @@ void Menu::bookmarkLocation() { removeAction(_bookmarksMenu, bookmarkName); } - bookmarks->insert(bookmarkName, bookmarkAddress); - QAction* teleportAction = new QAction(getMenu(MenuOption::Bookmarks)); teleportAction->setData(bookmarkAddress); connect(teleportAction, SIGNAL(triggered()), this, SLOT(teleportToBookmark())); @@ -1063,7 +1065,10 @@ void Menu::bookmarkLocation() { addActionToQMenuAndActionHash(_bookmarksMenu, teleportAction, bookmarkName, 0, QAction::NoRole, position); + bookmarks->insert(bookmarkName, bookmarkAddress); + _bookmarksMenu->setEnabled(true); + _deleteBookmarksMenu->setEnabled(true); } void Menu::teleportToBookmark() { @@ -1072,6 +1077,42 @@ void Menu::teleportToBookmark() { DependencyManager::get()->handleLookupString(url); } +void Menu::deleteBookmark() { + + QStringList bookmarkList; + QList menuItems = _bookmarksMenu->actions(); + for (int i = 0; i < menuItems.count(); i += 1) { + bookmarkList.append(menuItems[i]->text()); + } + + QInputDialog deleteBookmarkDialog(Application::getInstance()->getWindow()); + deleteBookmarkDialog.setWindowTitle("Delete Bookmark"); + deleteBookmarkDialog.setLabelText("Select the bookmark to delete"); + deleteBookmarkDialog.resize(400, 400); + deleteBookmarkDialog.setOption(QInputDialog::UseListViewForComboBoxItems); + deleteBookmarkDialog.setComboBoxItems(bookmarkList); + deleteBookmarkDialog.setOkButtonText("Delete"); + + if (deleteBookmarkDialog.exec() == QDialog::Rejected) { + return; + } + + QString bookmarkName = deleteBookmarkDialog.textValue().trimmed(); + if (bookmarkName.length() == 0) { + return; + } + + removeAction(_bookmarksMenu, bookmarkName); + + Bookmarks* bookmarks = Application::getInstance()->getBookmarks(); + bookmarks->remove(bookmarkName); + + if (_bookmarksMenu->actions().count() == 0) { + _bookmarksMenu->setEnabled(false); + _deleteBookmarksMenu->setEnabled(false); + } +} + void Menu::displayNameLocationResponse(const QString& errorString) { if (!errorString.isEmpty()) { diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 4f79125819..67d55b79b1 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -202,6 +202,7 @@ private slots: void changePrivateKey(); void bookmarkLocation(); void teleportToBookmark(); + void deleteBookmark(); void nameLocation(); void toggleLocationList(); void hmdToolsClosed(); @@ -311,6 +312,7 @@ private: QMap _shouldRenderTable; QMenu* _bookmarksMenu; + QAction* _deleteBookmarksMenu; }; namespace MenuOption { @@ -350,6 +352,7 @@ namespace MenuOption { const QString Collisions = "Collisions"; const QString Console = "Console..."; const QString ControlWithSpeech = "Control With Speech"; + const QString DeleteBookmark = "Delete Bookmark..."; const QString DontRenderEntitiesAsScene = "Don't Render Entities as Scene"; const QString DontDoPrecisionPicking = "Don't Do Precision Picking"; const QString DecreaseAvatarSize = "Decrease Avatar Size"; From 79d214619deb343d66a6ee02c530474045f01080 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 14 Jan 2015 18:18:26 -0800 Subject: [PATCH 39/93] update lobby for new places API --- examples/lobby.js | 52 +++++++++---------- .../scripting/LocationScriptingInterface.cpp | 13 ++--- 2 files changed, 29 insertions(+), 36 deletions(-) diff --git a/examples/lobby.js b/examples/lobby.js index 15a8aca328..829f399e06 100644 --- a/examples/lobby.js +++ b/examples/lobby.js @@ -66,20 +66,20 @@ function textOverlayPosition() { Vec3.multiply(Quat.getUp(Camera.orientation), TEXT_DISTANCE_DOWN)); } -var panelLocationOrder = [ +var panelPlaceOrder = [ 7, 8, 9, 10, 11, 12, 13, 0, 1, 2, 3, 4, 5, 6, 14, 15, 16, 17, 18, 19, 20 ]; -// Location index is 0-based -function locationIndexToPanelIndex(locationIndex) { - return panelLocationOrder.indexOf(locationIndex) + 1; +// place index is 0-based +function placeIndexToPanelIndex(placeIndex) { + return panelPlaceOrder.indexOf(placeIndex) + 1; } // Panel index is 1-based -function panelIndexToLocationIndex(panelIndex) { - return panelLocationOrder[panelIndex - 1]; +function panelIndexToPlaceIndex(panelIndex) { + return panelPlaceOrder[panelIndex - 1]; } var MAX_NUM_PANELS = 21; @@ -148,25 +148,25 @@ function drawLobby() { } } -var locations = {}; +var places = {}; function changeLobbyTextures() { var req = new XMLHttpRequest(); - req.open("GET", "https://data.highfidelity.io/api/v1/locations?limit=21", false); + req.open("GET", "https://data.highfidelity.io/api/v1/places?limit=21", false); req.send(); - locations = JSON.parse(req.responseText).data.locations; + places = JSON.parse(req.responseText).data.places; - var NUM_PANELS = locations.length; + var NUM_PANELS = places.length; var textureProp = { textures: {} }; for (var j = 0; j < NUM_PANELS; j++) { - var panelIndex = locationIndexToPanelIndex(j); - textureProp["textures"]["file" + panelIndex] = HIFI_PUBLIC_BUCKET + "images/locations/" - + locations[j].id + "/hifi-location-" + locations[j].id + "_640x360.jpg"; + var panelIndex = placeIndexToPanelIndex(j); + textureProp["textures"]["file" + panelIndex] = HIFI_PUBLIC_BUCKET + "images/places/" + + place[j].id + "/hifi-place-" + place[j].id + "_640x360.jpg"; }; Overlays.editOverlay(panelWall, textureProp); @@ -234,7 +234,7 @@ function cleanupLobby() { Audio.stopInjector(currentMuzakInjector); currentMuzakInjector = null; - locations = {}; + places = {}; toggleEnvironmentRendering(true); MyAvatar.detachOne(HELMET_ATTACHMENT_URL); @@ -252,14 +252,14 @@ function actionStartEvent(event) { var panelStringIndex = panelName.indexOf("Panel"); if (panelStringIndex != -1) { var panelIndex = parseInt(panelName.slice(5)); - var locationIndex = panelIndexToLocationIndex(panelIndex); - if (locationIndex < locations.length) { - var actionLocation = locations[locationIndex]; + var placeIndex = panelIndexToPlaceIndex(panelIndex); + if (placeIndex < place.length) { + var actionPlace = places[placeIndex]; - print("Jumping to " + actionLocation.name + " at " + actionLocation.path - + " in " + actionLocation.domain.name + " after click on panel " + panelIndex + " with location index " + locationIndex); + print("Jumping to " + actionPlace.name + " at " + actionPlace.address + + " after click on panel " + panelIndex + " with place index " + placeIndex); - Window.location = actionLocation; + Window.location = actionPlace.address; maybeCleanupLobby(); } } @@ -302,15 +302,15 @@ function handleLookAt(pickRay) { var panelStringIndex = panelName.indexOf("Panel"); if (panelStringIndex != -1) { var panelIndex = parseInt(panelName.slice(5)); - var locationIndex = panelIndexToLocationIndex(panelIndex); - if (locationIndex < locations.length) { - var actionLocation = locations[locationIndex]; + var placeIndex = panelIndexToPlaceIndex(panelIndex); + if (placeIndex < places.length) { + var actionPlace = places[placeIndex]; - if (actionLocation.description == "") { - Overlays.editOverlay(descriptionText, { text: actionLocation.name, visible: showText }); + if (actionPlace.description == "") { + Overlays.editOverlay(descriptionText, { text: actionPlace.name, visible: showText }); } else { // handle line wrapping - var allWords = actionLocation.description.split(" "); + var allWords = actionPlace.description.split(" "); var currentGoodLine = ""; var currentTestLine = ""; var formatedDescription = ""; diff --git a/interface/src/scripting/LocationScriptingInterface.cpp b/interface/src/scripting/LocationScriptingInterface.cpp index fda9875837..c0a9a62ff3 100644 --- a/interface/src/scripting/LocationScriptingInterface.cpp +++ b/interface/src/scripting/LocationScriptingInterface.cpp @@ -25,16 +25,9 @@ QScriptValue LocationScriptingInterface::locationGetter(QScriptContext* context, QScriptValue LocationScriptingInterface::locationSetter(QScriptContext* context, QScriptEngine* engine) { const QVariant& argumentVariant = context->argument(0).toVariant(); - - if (argumentVariant.canConvert(QMetaType::QVariantMap)) { - // this argument is a variant map, so we'll assume it's an address map - QMetaObject::invokeMethod(DependencyManager::get().data(), "goToAddressFromObject", - Q_ARG(const QVariantMap&, argumentVariant.toMap())); - } else { - // just try and convert the argument to a string, should be a hifi:// address - QMetaObject::invokeMethod(DependencyManager::get().data(), "handleLookupString", - Q_ARG(const QString&, argumentVariant.toString())); - } + // just try and convert the argument to a string, should be a hifi:// address + QMetaObject::invokeMethod(DependencyManager::get().data(), "handleLookupString", + Q_ARG(const QString&, argumentVariant.toString())); return QScriptValue::UndefinedValue; } From 1ffe22d5e9470662cba632a78dda54cf677f69e6 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 14 Jan 2015 18:31:54 -0800 Subject: [PATCH 40/93] Sanitize bookmark names --- interface/src/Menu.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index d45880a0b2..24e5935887 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -1031,6 +1031,10 @@ void Menu::bookmarkLocation() { } QString bookmarkName = bookmarkLocationDialog.textValue().trimmed(); + bookmarkName = bookmarkName.replace("\r\n", " "); + bookmarkName = bookmarkName.replace("\n", " "); + bookmarkName = bookmarkName.replace("\r", " "); + bookmarkName = bookmarkName.replace("\t", " "); if (bookmarkName.length() == 0) { return; } From d9bd7f019fe31dda672df552faf065a12c1fbcf5 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 14 Jan 2015 22:20:45 -0800 Subject: [PATCH 41/93] Simplify bookmark handling --- interface/src/Bookmarks.cpp | 17 +++++------------ interface/src/Bookmarks.h | 3 +-- interface/src/Menu.cpp | 2 +- 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/interface/src/Bookmarks.cpp b/interface/src/Bookmarks.cpp index 36f489fa6a..23a637c1d9 100644 --- a/interface/src/Bookmarks.cpp +++ b/interface/src/Bookmarks.cpp @@ -15,14 +15,9 @@ Bookmarks::Bookmarks() { } void Bookmarks::insert(const QString& name, const QString& address) { - QString key = name.toLower(); + _bookmarks.insert(name, address); - QJsonObject bookmark; - bookmark.insert("name", name); - bookmark.insert("address", address); - _bookmarks.insert(key, bookmark); - - if (contains(key)) { + if (contains(name)) { qDebug() << "Added bookmark: " << name << ", " << address; } else { qDebug() << "Couldn't add bookmark: " << name << ", " << address; @@ -30,11 +25,9 @@ void Bookmarks::insert(const QString& name, const QString& address) { } void Bookmarks::remove(const QString& name) { - QString key = name.toLower(); + _bookmarks.remove(name); - _bookmarks.remove(key); - - if (!contains(key)) { + if (!contains(name)) { qDebug() << "Removed bookmark: " << name; } else { qDebug() << "Couldn't remove bookmark: " << name; @@ -42,5 +35,5 @@ void Bookmarks::remove(const QString& name) { } bool Bookmarks::contains(const QString& name) const { - return _bookmarks.contains(name.toLower()); + return _bookmarks.contains(name); } diff --git a/interface/src/Bookmarks.h b/interface/src/Bookmarks.h index f9c40d7523..3a3f7f74d1 100644 --- a/interface/src/Bookmarks.h +++ b/interface/src/Bookmarks.h @@ -28,8 +28,7 @@ public: bool contains(const QString& name) const; private: - QMap _bookmarks; // key: { name: string, address: string } - // key is a lowercase copy of name, used to make the bookmarks case insensitive. + QVariantMap _bookmarks; // { name: address, ... } }; #endif // hifi_Bookmarks_h \ No newline at end of file diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 24e5935887..2f477d9711 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -1069,7 +1069,7 @@ void Menu::bookmarkLocation() { addActionToQMenuAndActionHash(_bookmarksMenu, teleportAction, bookmarkName, 0, QAction::NoRole, position); - bookmarks->insert(bookmarkName, bookmarkAddress); + bookmarks->insert(bookmarkName, bookmarkAddress); // Overwrites any item with the same bookmarkName. _bookmarksMenu->setEnabled(true); _deleteBookmarksMenu->setEnabled(true); From 426cd71fc67f8b816111265221a43c8d654b3ac9 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 14 Jan 2015 22:58:13 -0800 Subject: [PATCH 42/93] Persist bookmarks to file --- interface/src/Application.cpp | 4 ++-- interface/src/Bookmarks.cpp | 34 ++++++++++++++++++++++++++++++++++ interface/src/Bookmarks.h | 7 +++++++ interface/src/Menu.cpp | 24 ++++++++++++++++++++++++ interface/src/Menu.h | 1 + 5 files changed, 68 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 717ebdd749..253a613f33 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -218,6 +218,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : qDebug() << "[VERSION] Build sequence: " << qPrintable(applicationVersion()); + _bookmarks = new Bookmarks(); // Before setting up the menu + // call Menu getInstance static method to set up the menu _window->setMenuBar(Menu::getInstance()); @@ -310,8 +312,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _settings = new QSettings(this); _numChangedSettings = 0; - _bookmarks = new Bookmarks(); - #ifdef _WIN32 WSADATA WsaData; int wsaresult = WSAStartup(MAKEWORD(2,2), &WsaData); diff --git a/interface/src/Bookmarks.cpp b/interface/src/Bookmarks.cpp index 23a637c1d9..aa76914e8a 100644 --- a/interface/src/Bookmarks.cpp +++ b/interface/src/Bookmarks.cpp @@ -9,9 +9,15 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include +#include +#include + #include "Bookmarks.h" Bookmarks::Bookmarks() { + _bookmarksFilename = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + BOOKMARKS_FILENAME; + readFromFile(); } void Bookmarks::insert(const QString& name, const QString& address) { @@ -19,6 +25,7 @@ void Bookmarks::insert(const QString& name, const QString& address) { if (contains(name)) { qDebug() << "Added bookmark: " << name << ", " << address; + persistToFile(); } else { qDebug() << "Couldn't add bookmark: " << name << ", " << address; } @@ -29,6 +36,7 @@ void Bookmarks::remove(const QString& name) { if (!contains(name)) { qDebug() << "Removed bookmark: " << name; + persistToFile(); } else { qDebug() << "Couldn't remove bookmark: " << name; } @@ -37,3 +45,29 @@ void Bookmarks::remove(const QString& name) { bool Bookmarks::contains(const QString& name) const { return _bookmarks.contains(name); } + +void Bookmarks::readFromFile() { + QFile loadFile(_bookmarksFilename); + + if (!loadFile.open(QIODevice::ReadOnly)) { + qWarning("Couldn't open bookmarks file for reading"); + return; + } + + QByteArray data = loadFile.readAll(); + QJsonDocument json(QJsonDocument::fromJson(data)); + _bookmarks = json.object().toVariantMap(); +} + +void Bookmarks::persistToFile() { + QFile saveFile(_bookmarksFilename); + + if (!saveFile.open(QIODevice::WriteOnly)) { + qWarning("Couldn't open bookmarks file for writing"); + return; + } + + QJsonDocument json(QJsonObject::fromVariantMap(_bookmarks)); + QByteArray data = json.toJson(); + saveFile.write(data); +} diff --git a/interface/src/Bookmarks.h b/interface/src/Bookmarks.h index 3a3f7f74d1..2f054bcdbc 100644 --- a/interface/src/Bookmarks.h +++ b/interface/src/Bookmarks.h @@ -27,8 +27,15 @@ public: void remove(const QString& name); bool contains(const QString& name) const; + QVariantMap* getBookmarks() { return &_bookmarks; }; + private: QVariantMap _bookmarks; // { name: address, ... } + + const QString BOOKMARKS_FILENAME = "bookmarks.json"; + QString _bookmarksFilename; + void readFromFile(); + void persistToFile(); }; #endif // hifi_Bookmarks_h \ No newline at end of file diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 2f477d9711..d849dab125 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -131,6 +131,7 @@ Menu::Menu() : MenuOption::DeleteBookmark, 0, this, SLOT(deleteBookmark())); _deleteBookmarksMenu->setEnabled(false); + loadBookmarks(); addActionToQMenuAndActionHash(fileMenu, MenuOption::NameLocation, Qt::CTRL | Qt::Key_N, @@ -1018,6 +1019,29 @@ void Menu::changeVSync() { Application::getInstance()->setVSyncEnabled(isOptionChecked(MenuOption::RenderTargetFramerateVSyncOn)); } +void Menu::loadBookmarks() { + QVariantMap* bookmarks = Application::getInstance()->getBookmarks()->getBookmarks(); + if (bookmarks->count() > 0) { + + QMapIterator i(*bookmarks); + while (i.hasNext()) { + i.next(); + + QString bookmarkName = i.key(); + QString bookmarkAddress = i.value().toString(); + + QAction* teleportAction = new QAction(getMenu(MenuOption::Bookmarks)); + teleportAction->setData(bookmarkAddress); + connect(teleportAction, SIGNAL(triggered()), this, SLOT(teleportToBookmark())); + + addActionToQMenuAndActionHash(_bookmarksMenu, teleportAction, bookmarkName, 0, QAction::NoRole); + } + + _bookmarksMenu->setEnabled(true); + _deleteBookmarksMenu->setEnabled(true); + } +} + void Menu::bookmarkLocation() { QInputDialog bookmarkLocationDialog(Application::getInstance()->getWindow()); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 67d55b79b1..cbdb4d751a 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -311,6 +311,7 @@ private: bool _shouldRenderTableNeedsRebuilding = true; QMap _shouldRenderTable; + void loadBookmarks(); QMenu* _bookmarksMenu; QAction* _deleteBookmarksMenu; }; From ebe80075dc7fae970bd51c4ea92a72af9b6c7c1c Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 14 Jan 2015 23:20:47 -0800 Subject: [PATCH 43/93] Tidy --- interface/src/Bookmarks.cpp | 8 ++++---- interface/src/Menu.cpp | 9 +++------ 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/interface/src/Bookmarks.cpp b/interface/src/Bookmarks.cpp index aa76914e8a..d3ecf4097e 100644 --- a/interface/src/Bookmarks.cpp +++ b/interface/src/Bookmarks.cpp @@ -24,10 +24,10 @@ void Bookmarks::insert(const QString& name, const QString& address) { _bookmarks.insert(name, address); if (contains(name)) { - qDebug() << "Added bookmark: " << name << ", " << address; + qDebug() << "Added bookmark:" << name << "," << address; persistToFile(); } else { - qDebug() << "Couldn't add bookmark: " << name << ", " << address; + qWarning() << "Couldn't add bookmark: " << name << "," << address; } } @@ -35,10 +35,10 @@ void Bookmarks::remove(const QString& name) { _bookmarks.remove(name); if (!contains(name)) { - qDebug() << "Removed bookmark: " << name; + qDebug() << "Deleted bookmark:" << name; persistToFile(); } else { - qDebug() << "Couldn't remove bookmark: " << name; + qWarning() << "Couldn't delete bookmark:" << name; } } diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index d849dab125..665c68396c 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -1055,10 +1055,7 @@ void Menu::bookmarkLocation() { } QString bookmarkName = bookmarkLocationDialog.textValue().trimmed(); - bookmarkName = bookmarkName.replace("\r\n", " "); - bookmarkName = bookmarkName.replace("\n", " "); - bookmarkName = bookmarkName.replace("\r", " "); - bookmarkName = bookmarkName.replace("\t", " "); + bookmarkName = bookmarkName.replace(QRegExp("(\r\n|[\r\n\t\v ])+"), " "); if (bookmarkName.length() == 0) { return; } @@ -1101,8 +1098,8 @@ void Menu::bookmarkLocation() { void Menu::teleportToBookmark() { QAction *action = qobject_cast(sender()); - QString url = action->data().toString(); - DependencyManager::get()->handleLookupString(url); + QString address = action->data().toString(); + DependencyManager::get()->handleLookupString(address); } void Menu::deleteBookmark() { From 544d4121228059730f9ebe872232572752ae684c Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 15 Jan 2015 09:33:35 -0800 Subject: [PATCH 44/93] Add menu items that copy location address and location path And Rename File > Go to File > Location --- interface/src/Menu.cpp | 21 ++++++++++++++++++++- interface/src/Menu.h | 4 ++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 1219fc3486..01f41dd931 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -122,7 +123,7 @@ Menu::Menu() : addActionToQMenuAndActionHash(fileMenu, MenuOption::RunningScripts, Qt::CTRL | Qt::Key_J, appInstance, SLOT(toggleRunningScriptsWidget())); - addDisabledActionAndSeparator(fileMenu, "Go"); + addDisabledActionAndSeparator(fileMenu, "Location"); addActionToQMenuAndActionHash(fileMenu, MenuOption::NameLocation, Qt::CTRL | Qt::Key_N, @@ -138,6 +139,10 @@ Menu::Menu() : Qt::Key_Enter, this, SLOT(toggleAddressBar())); + addActionToQMenuAndActionHash(fileMenu, MenuOption::CopyAddress, 0, + this, SLOT(copyAddress())); + addActionToQMenuAndActionHash(fileMenu, MenuOption::CopyPath, 0, + this, SLOT(copyPath())); addDisabledActionAndSeparator(fileMenu, "Upload Avatar Model"); addActionToQMenuAndActionHash(fileMenu, MenuOption::UploadHead, 0, @@ -1006,6 +1011,20 @@ void Menu::toggleAddressBar() { } } +void Menu::copyAddress() { + auto addressManager = DependencyManager::get(); + QString address = addressManager->currentAddress().toString(); + QClipboard* clipboard = QApplication::clipboard(); + clipboard->setText(address); +} + +void Menu::copyPath() { + auto addressManager = DependencyManager::get(); + QString path = addressManager->currentPath(); + QClipboard* clipboard = QApplication::clipboard(); + clipboard->setText(path); +} + void Menu::changeVSync() { Application::getInstance()->setVSyncEnabled(isOptionChecked(MenuOption::RenderTargetFramerateVSyncOn)); } diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 6f30ca983b..79dd0799a9 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -177,6 +177,8 @@ public slots: void importSettings(); void exportSettings(); void toggleAddressBar(); + void copyAddress(); + void copyPath(); void toggleLoginMenuItem(); void toggleSixense(bool shouldEnable); @@ -343,6 +345,8 @@ namespace MenuOption { const QString CollideWithEnvironment = "Collide With World Boundaries"; const QString Collisions = "Collisions"; const QString Console = "Console..."; + const QString CopyAddress = "Copy Address"; + const QString CopyPath = "Copy Path"; const QString ControlWithSpeech = "Control With Speech"; const QString DontRenderEntitiesAsScene = "Don't Render Entities as Scene"; const QString DontDoPrecisionPicking = "Don't Do Precision Picking"; From 8455258fd4c94e21b1cf78c3ef88dc239901377b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 15 Jan 2015 09:44:02 -0800 Subject: [PATCH 45/93] update BUILD_WIN.md to support VS2013 Express --- BUILD_WIN.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/BUILD_WIN.md b/BUILD_WIN.md index ad143ef56a..cf8308c552 100644 --- a/BUILD_WIN.md +++ b/BUILD_WIN.md @@ -9,8 +9,7 @@ Please read the [general build guide](BUILD.md) for information on dependencies Currently building on Windows has been tested using the following compilers: * Visual Studio 2013 - -(If anyone can test using Visual Studio 2013 Express then please update this document) +* Visual Studio 2013 Express ####Visual Studio 2013 From 00487fb175651069acb43cc6580b573adbb1b5fc Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 15 Jan 2015 09:45:51 -0800 Subject: [PATCH 46/93] Fix issue with avatar data being sent too often --- interface/src/Application.cpp | 7 ++++++- interface/src/Application.h | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index af29aff5ef..a431bbb404 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2135,12 +2135,17 @@ void Application::updateMyAvatar(float deltaTime) { _myAvatar->update(deltaTime); - { + quint64 now = usecTimestampNow(); + quint64 dt = now - _lastSendAvatarDataTime; + + if (dt > MIN_TIME_BETWEEN_MY_AVATAR_DATA_SENDS) { // send head/hand data to the avatar mixer and voxel server PerformanceTimer perfTimer("send"); QByteArray packet = byteArrayWithPopulatedHeader(PacketTypeAvatarData); packet.append(_myAvatar->toByteArray()); controlledBroadcastToNodes(packet, NodeSet() << NodeType::AvatarMixer); + + _lastSendAvatarDataTime = now; } } diff --git a/interface/src/Application.h b/interface/src/Application.h index 451bfdc5e1..d7a826d9ea 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -111,6 +111,10 @@ static const float MIRROR_REARVIEW_DISTANCE = 0.722f; static const float MIRROR_REARVIEW_BODY_DISTANCE = 2.56f; static const float MIRROR_FIELD_OF_VIEW = 30.0f; +// 70 times per second - target is 60hz, but this helps account for any small deviations +// in the update loop +static const quint64 MIN_TIME_BETWEEN_MY_AVATAR_DATA_SENDS = (1000 * 1000) / 70; + static const quint64 TOO_LONG_SINCE_LAST_SEND_DOWNSTREAM_AUDIO_STATS = 1 * USECS_PER_SECOND; static const QString INFO_HELP_PATH = "html/interface-welcome-allsvg.html"; @@ -567,6 +571,8 @@ private: quint64 _lastNackTime; quint64 _lastSendDownstreamAudioStats; + quint64 _lastSendAvatarDataTime; + bool _isVSyncOn; bool _aboutToQuit; From 52876ecb1675560e473485500e337c39f6409ad7 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 15 Jan 2015 10:07:51 -0800 Subject: [PATCH 47/93] Fix merge --- interface/src/Menu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index df4014cd77..ac1aa5ed53 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -1060,7 +1060,7 @@ void Menu::bookmarkLocation() { return; } - AddressManager::SharedPointer addressManager = DependencyManager::get(); + auto addressManager = DependencyManager::get(); QString bookmarkAddress = addressManager->currentAddress().toString(); Bookmarks* bookmarks = Application::getInstance()->getBookmarks(); From dbb978e2786d43b35050f4cc46658c4b3922f6d9 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 15 Jan 2015 10:22:39 -0800 Subject: [PATCH 48/93] Update style and layout of entity properties window --- examples/html/entityProperties.html | 103 +++++++++++++--------------- examples/html/style.css | 70 ++++++++++++++----- 2 files changed, 98 insertions(+), 75 deletions(-) diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index 2df5524795..52b8001c9e 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -445,47 +445,38 @@ } - -
- -
+
-
+
- ID +
+
+
-
-
- Type -
-
- -
-
-
+
Locked
-
+
Visible
-
+
Position
-
X
-
Y
-
Z
+
X
+
Y
+
Z
@@ -493,7 +484,7 @@
-
+
Registration
X
@@ -502,7 +493,7 @@
-
+
Dimensions
X
@@ -512,7 +503,7 @@
- % + %
@@ -520,7 +511,7 @@
-
+
Rotation
Pitch
@@ -529,7 +520,7 @@
-
+
Linear Velocity
X
@@ -537,13 +528,13 @@
Z
-
+
Linear Damping
-
+
Angular Velocity
Pitch
@@ -551,14 +542,14 @@
Roll
-
+
Angular Damping
-
+
Gravity
X
@@ -567,35 +558,35 @@
-
+
Mass
-
+
Ignore For Collisions
-
+
Collisions Will Move
-
+
Lifetime
-
+
Script URL
@@ -603,7 +594,7 @@
-
+
Color
R
@@ -614,49 +605,49 @@ -
+
Model URL
-
+
Animation URL
-
+
Animation Playing
-
+
Animation FPS
-
+
Animation Frame
-
+
Animation Settings
-
+
Textures
-
+
Original Textures
@@ -664,19 +655,19 @@
-
+
Text
-
+
Line Height
-
+
Text Color
R
@@ -684,7 +675,7 @@
B
-
+
Background Color
R
@@ -693,13 +684,13 @@
-
+
Spot Light
-
+
Diffuse
R
@@ -707,7 +698,7 @@
B
-
+
Ambient
R
@@ -715,7 +706,7 @@
B
-
+
Specular
R
@@ -723,31 +714,31 @@
B
-
+
Constant Attenuation
-
+
Linear Attenuation
-
+
Quadratic Attenuation
-
+
Exponent
-
+
Cutoff (degrees)
diff --git a/examples/html/style.css b/examples/html/style.css index 20baaca915..5023bb4609 100644 --- a/examples/html/style.css +++ b/examples/html/style.css @@ -6,8 +6,8 @@ body { padding: 0; background-color: #efefef; - font-family: Sans-Serif; - font-size: 12px; + font-family: Arial; + font-size: 11.5px; -webkit-touch-callout: none; -webkit-user-select: none; @@ -17,6 +17,12 @@ body { user-select: none; } +body.properties { + background-color: rgb(76, 76, 76); + color: rgb(204, 204, 204); + font-size: 11px; +} + .selectable { -webkit-touch-callout: text; -webkit-user-select: text; @@ -85,12 +91,10 @@ input[type=button] { border: 0; color: #fff; font-weight: bold; - margin: 0 2px; - margin-top: 5px; - font-size: .9em; } textarea, input { + margin: 0; padding: 2px; border: 1px solid #999; background-color: #eee; @@ -105,10 +109,15 @@ input.url { width: 100%; } +input.coord { + width: 7em; + display: block; +} + table#entity-table { border-collapse: collapse; font-family: Sans-Serif; - font-size: 12px; + /* font-size: 12px; */ width: 100%; } @@ -145,11 +154,42 @@ th#entity-url { div.input-area { display: inline-block; + font-size: 10px; } input { } +#type { + font-size: 14px; +} + +#type label { + color: rgb(150, 150, 150); +} + +#properties-list input, #properties-list textarea { + background-color: rgb(102, 102, 102); + color: rgb(204, 204, 204); + border: none; + font-size: 10px; +} + +#properties-list input[type=button] { + cursor: pointer; + background-color: rgb(51, 102, 102); + border-color: #608e96; + border-radius: 5px; + padding: 5px 10px; + border: 0; + color: rgb(204, 204, 204); +} + +#properties-list .property { + padding: 8px 8px; + border-top: 1px solid rgb(63, 63, 63); + min-height: 1em; +} table#properties-list { @@ -158,10 +198,13 @@ table#properties-list { width: 100%; background-color: #efefef; font-family: Arial; - font-size: 12px; table-layout: fixed; } +#properties-list > div { + margin: 4px 0; +} + #properties-list { border-bottom: 1px solid #e5e5e5; } @@ -174,21 +217,10 @@ table#properties-list { vertical-align: middle; height: 1.2em; - background-color: #ccc; - border-bottom: 1px solid #e5e5e5; -} - -#properties-list .value { - min-height: 1em; } #properties-list .value > div{ - padding: 4px; -} - -#properties-list > div > div{ - padding: 3px; - border-bottom: 1px solid black; + padding: 4px 0; } col#col-label { From ff171a57824d37cf09954eab0d9e031c468e60d6 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 15 Jan 2015 10:27:43 -0800 Subject: [PATCH 49/93] Bullet is now required dependency --- cmake/macros/IncludeBullet.cmake | 9 ++----- interface/src/Application.cpp | 8 ------ interface/src/Application.h | 3 +-- libraries/entities/src/EntityItem.cpp | 25 ------------------- libraries/physics/src/BulletUtil.h | 3 --- libraries/physics/src/EntityMotionState.cpp | 10 -------- libraries/physics/src/EntityMotionState.h | 10 -------- libraries/physics/src/ObjectMotionState.cpp | 4 --- libraries/physics/src/ObjectMotionState.h | 13 ++++------ libraries/physics/src/PhysicsEngine.cpp | 3 --- libraries/physics/src/PhysicsEngine.h | 8 +----- libraries/physics/src/PhysicsEntity.h | 4 --- libraries/physics/src/ShapeInfoUtil.cpp | 5 ---- libraries/physics/src/ShapeInfoUtil.h | 3 --- libraries/physics/src/ShapeManager.cpp | 5 ---- libraries/physics/src/ShapeManager.h | 3 --- .../physics/src/ThreadSafeDynamicsWorld.cpp | 2 -- .../physics/src/ThreadSafeDynamicsWorld.h | 10 -------- tests/physics/src/BulletUtilTests.cpp | 12 --------- tests/physics/src/ShapeInfoTests.cpp | 12 --------- tests/physics/src/ShapeManagerTests.cpp | 12 --------- 21 files changed, 9 insertions(+), 155 deletions(-) diff --git a/cmake/macros/IncludeBullet.cmake b/cmake/macros/IncludeBullet.cmake index a238b33660..0c0c112736 100644 --- a/cmake/macros/IncludeBullet.cmake +++ b/cmake/macros/IncludeBullet.cmake @@ -8,11 +8,6 @@ # macro(INCLUDE_BULLET) - find_package(Bullet) - if (BULLET_FOUND) - include_directories("${BULLET_INCLUDE_DIRS}") - if (APPLE OR UNIX) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUSE_BULLET_PHYSICS -isystem ${BULLET_INCLUDE_DIRS}") - endif () - endif (BULLET_FOUND) + find_package(Bullet REQUIRED) + include_directories("${BULLET_INCLUDE_DIRS}") endmacro(INCLUDE_BULLET) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index af29aff5ef..8fb2f0a924 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -189,9 +189,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : _frameCount(0), _fps(60.0f), _justStarted(true), -#ifdef USE_BULLET_PHYSICS _physicsEngine(glm::vec3(0.0f)), -#endif // USE_BULLET_PHYSICS _entities(true, this, this), _entityCollisionSystem(), _entityClipboardRenderer(false, this, this), @@ -1726,12 +1724,10 @@ void Application::init() { // save settings when avatar changes connect(_myAvatar, &MyAvatar::transformChanged, this, &Application::bumpSettings); -#ifdef USE_BULLET_PHYSICS EntityTree* tree = _entities.getTree(); _physicsEngine.setEntityTree(tree); tree->setSimulation(&_physicsEngine); _physicsEngine.init(&_entityEditSender); -#endif // USE_BULLET_PHYSICS // make sure our texture cache knows about window size changes DependencyManager::get()->associateWithWidget(glCanvas.data()); @@ -2042,12 +2038,10 @@ void Application::update(float deltaTime) { updateDialogs(deltaTime); // update various stats dialogs if present updateCursor(deltaTime); // Handle cursor updates -#ifdef USE_BULLET_PHYSICS { PerformanceTimer perfTimer("physics"); _physicsEngine.stepSimulation(); } -#endif // USE_BULLET_PHYSICS if (!_aboutToQuit) { PerformanceTimer perfTimer("entities"); @@ -3659,7 +3653,6 @@ void Application::openUrl(const QUrl& url) { void Application::updateMyAvatarTransform() { bumpSettings(); -#ifdef USE_BULLET_PHYSICS const float SIMULATION_OFFSET_QUANTIZATION = 16.0f; // meters glm::vec3 avatarPosition = _myAvatar->getPosition(); glm::vec3 physicsWorldOffset = _physicsEngine.getOriginOffset(); @@ -3673,7 +3666,6 @@ void Application::updateMyAvatarTransform() { // TODO: Andrew to replace this with method that actually moves existing object positions in PhysicsEngine _physicsEngine.setOriginOffset(newOriginOffset); } -#endif // USE_BULLET_PHYSICS } void Application::domainSettingsReceived(const QJsonObject& domainSettingsObject) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 451bfdc5e1..923f4d6466 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -454,9 +455,7 @@ private: bool _justStarted; Stars _stars; -#ifdef USE_BULLET_PHYSICS PhysicsEngine _physicsEngine; -#endif // USE_BULLET_PHYSICS EntityTreeRenderer _entities; EntityCollisionSystem _entityCollisionSystem; diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 9cfb0c6c11..c6b6f6eb7d 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -691,15 +691,7 @@ void EntityItem::simulate(const quint64& now) { } } -#ifdef USE_BULLET_PHYSICS - // When Bullet is available we assume that "zero velocity" means "at rest" - // because of collision conditions this simulation does not know about - // so we don't fall in for the non-zero gravity case here. if (hasVelocity()) { -#else // !USE_BULLET_PHYSICS - if (hasVelocity() || hasGravity()) { -#endif // USE_BULLET_PHYSICS - // linear damping glm::vec3 velocity = getVelocity(); if (_damping > 0.0f) { @@ -734,12 +726,10 @@ void EntityItem::simulate(const quint64& now) { if (position.y <= getDistanceToBottomOfEntity()) { velocity = velocity * glm::vec3(1,-1,1); -#ifndef USE_BULLET_PHYSICS // if we've slowed considerably, then just stop moving, but only if no BULLET if (glm::length(velocity) <= ENTITY_ITEM_EPSILON_VELOCITY_LENGTH) { velocity = ENTITY_ITEM_ZERO_VEC3; } -#endif // !USE_BULLET_PHYSICS position.y = getDistanceToBottomOfEntity(); } @@ -756,15 +746,6 @@ void EntityItem::simulate(const quint64& now) { } } -#ifdef USE_BULLET_PHYSICS - // When Bullet is available we assume that it will tell us when velocities go to zero... -#else // !USE_BULLET_PHYSICS - // ... otherwise we help things come to rest by clamping small velocities. - if (glm::length(velocity) <= ENTITY_ITEM_EPSILON_VELOCITY_LENGTH) { - velocity = ENTITY_ITEM_ZERO_VEC3; - } -#endif // USE_BULLET_PHYSICS - // NOTE: the simulation should NOT set any DirtyFlags on this entity setPosition(position); // this will automatically recalculate our collision shape setVelocity(velocity); @@ -781,13 +762,7 @@ void EntityItem::simulate(const quint64& now) { } bool EntityItem::isMoving() const { -#ifdef USE_BULLET_PHYSICS - // When Bullet is available we assume that "zero velocity" means "at rest" - // because of collision conditions this simulation does not know about. return hasVelocity() || hasAngularVelocity(); -#else // !USE_BULLET_PHYSICS - return hasVelocity() || (hasGravity() && !isRestingOnSurface()) || hasAngularVelocity(); -#endif //USE_BULLET_PHYSICS } bool EntityItem::lifetimeHasExpired() const { diff --git a/libraries/physics/src/BulletUtil.h b/libraries/physics/src/BulletUtil.h index 78524a122e..52bf2c8b06 100644 --- a/libraries/physics/src/BulletUtil.h +++ b/libraries/physics/src/BulletUtil.h @@ -12,8 +12,6 @@ #ifndef hifi_BulletUtil_h #define hifi_BulletUtil_h -#ifdef USE_BULLET_PHYSICS - #include #include #include @@ -34,5 +32,4 @@ inline btQuaternion glmToBullet(const glm::quat& g) { return btQuaternion(g.x, g.y, g.z, g.w); } -#endif // USE_BULLET_PHYSICS #endif // hifi_BulletUtil_h diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index a15f8a9f51..87f3d1669a 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -12,9 +12,7 @@ #include #include -#ifdef USE_BULLET_PHYSICS #include "BulletUtil.h" -#endif // USE_BULLET_PHYSICS #include "EntityMotionState.h" QSet* _outgoingEntityList; @@ -49,7 +47,6 @@ MotionType EntityMotionState::computeMotionType() const { return _entity->getCollisionsWillMove() ? MOTION_TYPE_DYNAMIC : MOTION_TYPE_STATIC; } -#ifdef USE_BULLET_PHYSICS // This callback is invoked by the physics simulation in two cases: // (1) when the RigidBody is first added to the world // (irregardless of MotionType: STATIC, DYNAMIC, or KINEMATIC) @@ -77,10 +74,8 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) { _outgoingPacketFlags = DIRTY_PHYSICS_FLAGS; EntityMotionState::enqueueOutgoingEntity(_entity); } -#endif // USE_BULLET_PHYSICS void EntityMotionState::updateObjectEasy(uint32_t flags, uint32_t frame) { -#ifdef USE_BULLET_PHYSICS if (flags & (EntityItem::DIRTY_POSITION | EntityItem::DIRTY_VELOCITY)) { if (flags & EntityItem::DIRTY_POSITION) { _sentPosition = _entity->getPositionInMeters() - ObjectMotionState::getWorldOffset(); @@ -116,11 +111,9 @@ void EntityMotionState::updateObjectEasy(uint32_t flags, uint32_t frame) { _body->updateInertiaTensor(); } _body->activate(); -#endif // USE_BULLET_PHYSICS }; void EntityMotionState::updateObjectVelocities() { -#ifdef USE_BULLET_PHYSICS if (_body) { _sentVelocity = _entity->getVelocityInMeters(); setVelocity(_sentVelocity); @@ -134,7 +127,6 @@ void EntityMotionState::updateObjectVelocities() { _body->setActivationState(ACTIVE_TAG); } -#endif // USE_BULLET_PHYSICS } void EntityMotionState::computeShapeInfo(ShapeInfo& shapeInfo) { @@ -146,7 +138,6 @@ float EntityMotionState::computeMass(const ShapeInfo& shapeInfo) const { } void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_t frame) { -#ifdef USE_BULLET_PHYSICS if (_outgoingPacketFlags) { EntityItemProperties properties = _entity->getProperties(); @@ -213,5 +204,4 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ _outgoingPacketFlags = DIRTY_PHYSICS_FLAGS; _sentFrame = frame; } -#endif // USE_BULLET_PHYSICS } diff --git a/libraries/physics/src/EntityMotionState.h b/libraries/physics/src/EntityMotionState.h index 57f3b52672..d2eb18cdbf 100644 --- a/libraries/physics/src/EntityMotionState.h +++ b/libraries/physics/src/EntityMotionState.h @@ -15,14 +15,6 @@ #include #include "ObjectMotionState.h" -#ifndef USE_BULLET_PHYSICS -// ObjectMotionState stubbery -class ObjectMotionState { -public: - // so that this stub implementation is not completely empty we give the class a data member - bool _stubData; -}; -#endif // USE_BULLET_PHYSICS class EntityItem; @@ -45,13 +37,11 @@ public: /// \return MOTION_TYPE_DYNAMIC or MOTION_TYPE_STATIC based on params set in EntityItem MotionType computeMotionType() const; -#ifdef USE_BULLET_PHYSICS // this relays incoming position/rotation to the RigidBody void getWorldTransform(btTransform& worldTrans) const; // this relays outgoing position/rotation to the EntityItem void setWorldTransform(const btTransform& worldTrans); -#endif // USE_BULLET_PHYSICS // these relay incoming values to the RigidBody void updateObjectEasy(uint32_t flags, uint32_t frame); diff --git a/libraries/physics/src/ObjectMotionState.cpp b/libraries/physics/src/ObjectMotionState.cpp index 9b3e69eb8d..65a2557383 100644 --- a/libraries/physics/src/ObjectMotionState.cpp +++ b/libraries/physics/src/ObjectMotionState.cpp @@ -9,8 +9,6 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifdef USE_BULLET_PHYSICS - #include #include "BulletUtil.h" @@ -174,5 +172,3 @@ bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame) { glm::quat actualRotation = bulletToGLM(worldTrans.getRotation()); return (fabsf(glm::dot(actualRotation, _sentRotation)) < MIN_ROTATION_DOT); } - -#endif // USE_BULLET_PHYSICS diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index ea3d5de73b..1b1af5de6f 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -12,8 +12,13 @@ #ifndef hifi_ObjectMotionState_h #define hifi_ObjectMotionState_h +#include +#include + #include +#include "ShapeInfo.h" + enum MotionType { MOTION_TYPE_STATIC, // no motion MOTION_TYPE_DYNAMIC, // motion according to physical laws @@ -33,13 +38,6 @@ const uint32_t DIRTY_PHYSICS_FLAGS = HARD_DIRTY_PHYSICS_FLAGS | EASY_DIRTY_PHYSI // These are the outgoing flags that the PhysicsEngine can affect: const uint32_t OUTGOING_DIRTY_PHYSICS_FLAGS = EntityItem::DIRTY_POSITION | EntityItem::DIRTY_VELOCITY; -#ifdef USE_BULLET_PHYSICS - -#include -#include -#include // for EntityItem::DIRTY_FOO bitmasks - -#include "ShapeInfo.h" class OctreeEditPacketSender; @@ -112,5 +110,4 @@ protected: glm::vec3 _sentAcceleration; }; -#endif // USE_BULLET_PHYSICS #endif // hifi_ObjectMotionState_h diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index e08f271255..ca83bbf095 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -10,7 +10,6 @@ // #include "PhysicsEngine.h" -#ifdef USE_BULLET_PHYSICS #include "ShapeInfoUtil.h" #include "ThreadSafeDynamicsWorld.h" @@ -400,5 +399,3 @@ void PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motio body->activate(); } - -#endif // USE_BULLET_PHYSICS diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index c6d6bd4626..589286588b 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -14,8 +14,6 @@ typedef unsigned int uint32_t; -#ifdef USE_BULLET_PHYSICS - #include #include @@ -94,11 +92,7 @@ private: EntityEditPacketSender* _entityPacketSender; uint32_t _frameCount; + btScalar _infinity = BT_INFINITY; // HACK: eliminates unused variable warning from Bullet headers }; -#else // USE_BULLET_PHYSICS -// PhysicsEngine stubbery until Bullet is required -class PhysicsEngine { -}; -#endif // USE_BULLET_PHYSICS #endif // hifi_PhysicsEngine_h diff --git a/libraries/physics/src/PhysicsEntity.h b/libraries/physics/src/PhysicsEntity.h index 92b302debb..358c058551 100644 --- a/libraries/physics/src/PhysicsEntity.h +++ b/libraries/physics/src/PhysicsEntity.h @@ -21,10 +21,6 @@ #include #include -#ifdef USE_BULLET_PHYSICS -#include "PhysicsEngine.h" -#endif // USE_BULLET_PHYSICS - class Shape; class PhysicsSimulation; diff --git a/libraries/physics/src/ShapeInfoUtil.cpp b/libraries/physics/src/ShapeInfoUtil.cpp index f562201f73..0e9dc55a8c 100644 --- a/libraries/physics/src/ShapeInfoUtil.cpp +++ b/libraries/physics/src/ShapeInfoUtil.cpp @@ -15,9 +15,6 @@ #include "ShapeInfoUtil.h" #include "BulletUtil.h" -#ifdef USE_BULLET_PHYSICS - - int ShapeInfoUtil::toBulletShapeType(int shapeInfoType) { int bulletShapeType = INVALID_SHAPE_PROXYTYPE; switch(shapeInfoType) { @@ -168,5 +165,3 @@ DoubleHashKey ShapeInfoUtil::computeHash(const ShapeInfo& info) { key._hash2 = (int)hash; return key; } - -#endif // USE_BULLET_PHYSICS diff --git a/libraries/physics/src/ShapeInfoUtil.h b/libraries/physics/src/ShapeInfoUtil.h index 7363cf483b..438e3df715 100644 --- a/libraries/physics/src/ShapeInfoUtil.h +++ b/libraries/physics/src/ShapeInfoUtil.h @@ -12,8 +12,6 @@ #ifndef hifi_ShapeInfoUtil_h #define hifi_ShapeInfoUtil_h -#ifdef USE_BULLET_PHYSICS - #include #include @@ -35,5 +33,4 @@ namespace ShapeInfoUtil { int fromBulletShapeType(int bulletShapeType); }; -#endif // USE_BULLET_PHYSICS #endif // hifi_ShapeInfoUtil_h diff --git a/libraries/physics/src/ShapeManager.cpp b/libraries/physics/src/ShapeManager.cpp index 1da705a5ff..b153150ce6 100644 --- a/libraries/physics/src/ShapeManager.cpp +++ b/libraries/physics/src/ShapeManager.cpp @@ -9,8 +9,6 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifdef USE_BULLET_PHYSICS - #include #include "ShapeInfoUtil.h" @@ -104,6 +102,3 @@ int ShapeManager::getNumReferences(const ShapeInfo& info) const { } return -1; } - - -#endif // USE_BULLET_PHYSICS diff --git a/libraries/physics/src/ShapeManager.h b/libraries/physics/src/ShapeManager.h index 6eb4f363ff..3fe80c7b61 100644 --- a/libraries/physics/src/ShapeManager.h +++ b/libraries/physics/src/ShapeManager.h @@ -12,8 +12,6 @@ #ifndef hifi_ShapeManager_h #define hifi_ShapeManager_h -#ifdef USE_BULLET_PHYSICS - #include #include @@ -52,5 +50,4 @@ private: btAlignedObjectArray _pendingGarbage; }; -#endif // USE_BULLET_PHYSICS #endif // hifi_ShapeManager_h diff --git a/libraries/physics/src/ThreadSafeDynamicsWorld.cpp b/libraries/physics/src/ThreadSafeDynamicsWorld.cpp index e204ae9e7f..c7ee9ce2a0 100644 --- a/libraries/physics/src/ThreadSafeDynamicsWorld.cpp +++ b/libraries/physics/src/ThreadSafeDynamicsWorld.cpp @@ -17,7 +17,6 @@ #include "ThreadSafeDynamicsWorld.h" -#ifdef USE_BULLET_PHYSICS ThreadSafeDynamicsWorld::ThreadSafeDynamicsWorld( btDispatcher* dispatcher, btBroadphaseInterface* pairCache, @@ -82,4 +81,3 @@ int ThreadSafeDynamicsWorld::stepSimulation( btScalar timeStep, int maxSubSteps, return subSteps; } -#endif // USE_BULLET_PHYSICS diff --git a/libraries/physics/src/ThreadSafeDynamicsWorld.h b/libraries/physics/src/ThreadSafeDynamicsWorld.h index 64d5413c56..832efb9b60 100644 --- a/libraries/physics/src/ThreadSafeDynamicsWorld.h +++ b/libraries/physics/src/ThreadSafeDynamicsWorld.h @@ -18,7 +18,6 @@ #ifndef hifi_ThreadSafeDynamicsWorld_h #define hifi_ThreadSafeDynamicsWorld_h -#ifdef USE_BULLET_PHYSICS #include ATTRIBUTE_ALIGNED16(class) ThreadSafeDynamicsWorld : public btDiscreteDynamicsWorld { @@ -40,13 +39,4 @@ public: float getLocalTimeAccumulation() const { return m_localTime; } }; -#else // USE_BULLET_PHYSICS -// stubbery for ThreadSafeDynamicsWorld when Bullet not available -class ThreadSafeDynamicsWorld { -public: - ThreadSafeDynamicsWorld() {} -}; - -#endif // USE_BULLET_PHYSICS - #endif // hifi_ThreadSafeDynamicsWorld_h diff --git a/tests/physics/src/BulletUtilTests.cpp b/tests/physics/src/BulletUtilTests.cpp index 06b1815c6e..a094cfe94b 100644 --- a/tests/physics/src/BulletUtilTests.cpp +++ b/tests/physics/src/BulletUtilTests.cpp @@ -16,7 +16,6 @@ #include "BulletUtilTests.h" -#ifdef USE_BULLET_PHYSICS void BulletUtilTests::fromBulletToGLM() { btVector3 bV(1.23f, 4.56f, 7.89f); glm::vec3 gV = bulletToGLM(bV); @@ -101,14 +100,3 @@ void BulletUtilTests::runAllTests() { fromBulletToGLM(); fromGLMToBullet(); } - -#else // USE_BULLET_PHYSICS -void BulletUtilTests::fromBulletToGLM() { -} - -void BulletUtilTests::fromGLMToBullet() { -} - -void BulletUtilTests::runAllTests() { -} -#endif // USE_BULLET_PHYSICS diff --git a/tests/physics/src/ShapeInfoTests.cpp b/tests/physics/src/ShapeInfoTests.cpp index a4db3a5764..cbef53f2eb 100644 --- a/tests/physics/src/ShapeInfoTests.cpp +++ b/tests/physics/src/ShapeInfoTests.cpp @@ -11,10 +11,8 @@ #include -#ifdef USE_BULLET_PHYSICS #include #include -#endif // USE_BULLET_PHYSICS #include #include @@ -24,7 +22,6 @@ #include "ShapeInfoTests.h" void ShapeInfoTests::testHashFunctions() { -#ifdef USE_BULLET_PHYSICS int maxTests = 10000000; ShapeInfo info; btHashMap hashes; @@ -135,11 +132,9 @@ void ShapeInfoTests::testHashFunctions() { for (int i = 0; i < 32; ++i) { std::cout << "bit 0x" << std::hex << masks[i] << std::dec << " = " << bits[i] << std::endl; } -#endif // USE_BULLET_PHYSICS } void ShapeInfoTests::testBoxShape() { -#ifdef USE_BULLET_PHYSICS ShapeInfo info; glm::vec3 halfExtents(1.23f, 4.56f, 7.89f); info.setBox(halfExtents); @@ -165,11 +160,9 @@ void ShapeInfoTests::testBoxShape() { } delete shape; -#endif // USE_BULLET_PHYSICS } void ShapeInfoTests::testSphereShape() { -#ifdef USE_BULLET_PHYSICS ShapeInfo info; float radius = 1.23f; info.setSphere(radius); @@ -191,11 +184,9 @@ void ShapeInfoTests::testSphereShape() { } delete shape; -#endif // USE_BULLET_PHYSICS } void ShapeInfoTests::testCylinderShape() { -#ifdef USE_BULLET_PHYSICS ShapeInfo info; float radius = 1.23f; float height = 4.56f; @@ -218,11 +209,9 @@ void ShapeInfoTests::testCylinderShape() { } delete shape; -#endif // USE_BULLET_PHYSICS } void ShapeInfoTests::testCapsuleShape() { -#ifdef USE_BULLET_PHYSICS ShapeInfo info; float radius = 1.23f; float height = 4.56f; @@ -245,7 +234,6 @@ void ShapeInfoTests::testCapsuleShape() { } delete shape; -#endif // USE_BULLET_PHYSICS } void ShapeInfoTests::runAllTests() { diff --git a/tests/physics/src/ShapeManagerTests.cpp b/tests/physics/src/ShapeManagerTests.cpp index 5be247f25f..e49b9b8063 100644 --- a/tests/physics/src/ShapeManagerTests.cpp +++ b/tests/physics/src/ShapeManagerTests.cpp @@ -17,7 +17,6 @@ #include "ShapeManagerTests.h" void ShapeManagerTests::testShapeAccounting() { -#ifdef USE_BULLET_PHYSICS ShapeManager shapeManager; ShapeInfo info; info.setBox(glm::vec3(1.0f, 1.0f, 1.0f)); @@ -118,11 +117,9 @@ void ShapeManagerTests::testShapeAccounting() { std::cout << __FILE__ << ":" << __LINE__ << " ERROR: expected refcount = 1 for shape but found refcount = " << numReferences << std::endl; } -#endif // USE_BULLET_PHYSICS } void ShapeManagerTests::addManyShapes() { -#ifdef USE_BULLET_PHYSICS ShapeManager shapeManager; int numSizes = 100; @@ -152,11 +149,9 @@ void ShapeManagerTests::addManyShapes() { std::cout << __FILE__ << ":" << __LINE__ << " ERROR: expected numShapes = " << numSizes << " but found numShapes = " << numShapes << std::endl; } -#endif // USE_BULLET_PHYSICS } void ShapeManagerTests::addBoxShape() { -#ifdef USE_BULLET_PHYSICS ShapeInfo info; glm::vec3 halfExtents(1.23f, 4.56f, 7.89f); info.setBox(halfExtents); @@ -172,11 +167,9 @@ void ShapeManagerTests::addBoxShape() { std::cout << __FILE__ << ":" << __LINE__ << " ERROR: Box ShapeInfo --> shape --> ShapeInfo --> shape did not work" << std::endl; } -#endif // USE_BULLET_PHYSICS } void ShapeManagerTests::addSphereShape() { -#ifdef USE_BULLET_PHYSICS ShapeInfo info; float radius = 1.23f; info.setSphere(radius); @@ -192,11 +185,9 @@ void ShapeManagerTests::addSphereShape() { std::cout << __FILE__ << ":" << __LINE__ << " ERROR: Sphere ShapeInfo --> shape --> ShapeInfo --> shape did not work" << std::endl; } -#endif // USE_BULLET_PHYSICS } void ShapeManagerTests::addCylinderShape() { -#ifdef USE_BULLET_PHYSICS ShapeInfo info; float radius = 1.23f; float height = 4.56f; @@ -213,11 +204,9 @@ void ShapeManagerTests::addCylinderShape() { std::cout << __FILE__ << ":" << __LINE__ << " ERROR: Cylinder ShapeInfo --> shape --> ShapeInfo --> shape did not work" << std::endl; } -#endif // USE_BULLET_PHYSICS } void ShapeManagerTests::addCapsuleShape() { -#ifdef USE_BULLET_PHYSICS ShapeInfo info; float radius = 1.23f; float height = 4.56f; @@ -234,7 +223,6 @@ void ShapeManagerTests::addCapsuleShape() { std::cout << __FILE__ << ":" << __LINE__ << " ERROR: Capsule ShapeInfo --> shape --> ShapeInfo --> shape did not work" << std::endl; } -#endif // USE_BULLET_PHYSICS } void ShapeManagerTests::runAllTests() { From 9eb4d663271600e0526363a5b733710d81ee4edf Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 15 Jan 2015 10:36:17 -0800 Subject: [PATCH 50/93] remove warnings --- libraries/physics/src/BulletUtil.h | 4 ++++ libraries/physics/src/ObjectMotionState.cpp | 8 -------- libraries/physics/src/PhysicsEngine.h | 1 - 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/libraries/physics/src/BulletUtil.h b/libraries/physics/src/BulletUtil.h index 52bf2c8b06..35b75a1040 100644 --- a/libraries/physics/src/BulletUtil.h +++ b/libraries/physics/src/BulletUtil.h @@ -32,4 +32,8 @@ inline btQuaternion glmToBullet(const glm::quat& g) { return btQuaternion(g.x, g.y, g.z, g.w); } +inline bool avoidUnusedVariableWarningInBulletHeaders(float number) { + return number == BT_INFINITY; +} + #endif // hifi_BulletUtil_h diff --git a/libraries/physics/src/ObjectMotionState.cpp b/libraries/physics/src/ObjectMotionState.cpp index 65a2557383..c424c11aa8 100644 --- a/libraries/physics/src/ObjectMotionState.cpp +++ b/libraries/physics/src/ObjectMotionState.cpp @@ -14,14 +14,6 @@ #include "BulletUtil.h" #include "ObjectMotionState.h" -const float MIN_DENSITY = 200.0f; -const float DEFAULT_DENSITY = 1000.0f; -const float MAX_DENSITY = 20000.0f; - -const float MIN_VOLUME = 0.001f; -const float DEFAULT_VOLUME = 1.0f; -const float MAX_VOLUME = 1000000.0f; - const float DEFAULT_FRICTION = 0.5f; const float MAX_FRICTION = 10.0f; diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index 589286588b..578fd1ece4 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -92,7 +92,6 @@ private: EntityEditPacketSender* _entityPacketSender; uint32_t _frameCount; - btScalar _infinity = BT_INFINITY; // HACK: eliminates unused variable warning from Bullet headers }; #endif // hifi_PhysicsEngine_h From 91e321565a7978fd8b9fab0092fc4d2a4a09f02e Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 15 Jan 2015 10:38:17 -0800 Subject: [PATCH 51/93] Change menu item text --- interface/src/Menu.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 79dd0799a9..02892f2fed 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -345,8 +345,8 @@ namespace MenuOption { const QString CollideWithEnvironment = "Collide With World Boundaries"; const QString Collisions = "Collisions"; const QString Console = "Console..."; - const QString CopyAddress = "Copy Address"; - const QString CopyPath = "Copy Path"; + const QString CopyAddress = "Copy Address to Clipboard"; + const QString CopyPath = "Copy Path to Clipboard"; const QString ControlWithSpeech = "Control With Speech"; const QString DontRenderEntitiesAsScene = "Don't Render Entities as Scene"; const QString DontDoPrecisionPicking = "Don't Do Precision Picking"; From 51cc9d6d9a49f29c19d03026e41d72de2be594fa Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 15 Jan 2015 10:46:09 -0800 Subject: [PATCH 52/93] alt method for repressing unused var warnings --- cmake/macros/IncludeBullet.cmake | 1 + libraries/physics/src/BulletUtil.h | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/cmake/macros/IncludeBullet.cmake b/cmake/macros/IncludeBullet.cmake index 0c0c112736..56b6ce0ced 100644 --- a/cmake/macros/IncludeBullet.cmake +++ b/cmake/macros/IncludeBullet.cmake @@ -10,4 +10,5 @@ macro(INCLUDE_BULLET) find_package(Bullet REQUIRED) include_directories("${BULLET_INCLUDE_DIRS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${BULLET_INCLUDE_DIRS}") endmacro(INCLUDE_BULLET) diff --git a/libraries/physics/src/BulletUtil.h b/libraries/physics/src/BulletUtil.h index 35b75a1040..52bf2c8b06 100644 --- a/libraries/physics/src/BulletUtil.h +++ b/libraries/physics/src/BulletUtil.h @@ -32,8 +32,4 @@ inline btQuaternion glmToBullet(const glm::quat& g) { return btQuaternion(g.x, g.y, g.z, g.w); } -inline bool avoidUnusedVariableWarningInBulletHeaders(float number) { - return number == BT_INFINITY; -} - #endif // hifi_BulletUtil_h From d6a3b94c730945aa6f96b5a436d895994b8e678c Mon Sep 17 00:00:00 2001 From: Chris Collins Date: Thu, 15 Jan 2015 10:48:31 -0800 Subject: [PATCH 53/93] Changed references of global.js to a var Changed references of global.js to a var --- examples/acScripts/ControlACs.js | 2 +- examples/acScripts/ControlledAC.js | 2 +- examples/acScripts/botProceduralWayPoints.js | 2 +- examples/acScripts/bot_procedural.js | 2 +- examples/acScripts/bot_randomExpression.js | 2 +- examples/clap.js | 2 +- examples/controllers/hydra/airGuitar.js | 2 +- examples/controllers/hydra/drumStick.js | 2 +- examples/controllers/hydra/frisbee.js | 2 +- examples/controllers/hydra/gun.js | 2 +- examples/controllers/hydra/squeezeHands.js | 2 +- examples/controllers/hydra/toyball.js | 2 +- examples/controllers/oculus/virtualKeyboard.js | 2 +- examples/editEntities.js | 2 +- examples/example/audio/audioBall.js | 2 +- examples/example/audio/radio.js | 2 +- examples/example/entities/editModelExample.js | 2 +- examples/example/entities/entityModelExample.js | 2 +- examples/example/games/spaceInvadersExample.js | 2 +- examples/example/ui/overlaysExample.js | 2 +- examples/libraries/entitySelectionTool.js | 2 +- examples/lobby.js | 2 +- examples/utilities/diagnostics/inWorldTestTone.js | 2 +- examples/utilities/diagnostics/playSoundLoop.js | 2 +- examples/utilities/diagnostics/playSoundWave.js | 2 +- examples/utilities/record/recorder.js | 2 +- 26 files changed, 26 insertions(+), 26 deletions(-) diff --git a/examples/acScripts/ControlACs.js b/examples/acScripts/ControlACs.js index 0edbde4ad1..4f27a36b9d 100644 --- a/examples/acScripts/ControlACs.js +++ b/examples/acScripts/ControlACs.js @@ -9,7 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; // Set the following variables to the right value var NUM_AC = 3; // This is the number of AC. Their ID need to be unique and between 0 (included) and NUM_AC (excluded) diff --git a/examples/acScripts/ControlledAC.js b/examples/acScripts/ControlledAC.js index 4e400670e5..78fe3903cd 100644 --- a/examples/acScripts/ControlledAC.js +++ b/examples/acScripts/ControlledAC.js @@ -9,7 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; // Set the following variables to the values needed var filename = HIFI_PUBLIC_BUCKET + "ozan/bartender.rec"; diff --git a/examples/acScripts/botProceduralWayPoints.js b/examples/acScripts/botProceduralWayPoints.js index b7c1fa1fe2..1e00c9f8b8 100644 --- a/examples/acScripts/botProceduralWayPoints.js +++ b/examples/acScripts/botProceduralWayPoints.js @@ -20,7 +20,7 @@ // //For procedural walk animation -Script.include("../libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; Script.include(HIFI_PUBLIC_BUCKET + "scripts/proceduralAnimationAPI.js"); var procAnimAPI = new ProcAnimAPI(); diff --git a/examples/acScripts/bot_procedural.js b/examples/acScripts/bot_procedural.js index 8b96ed36c2..518ef8cc22 100644 --- a/examples/acScripts/bot_procedural.js +++ b/examples/acScripts/bot_procedural.js @@ -11,7 +11,7 @@ // //For procedural walk animation -Script.include("../libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; Script.include("proceduralAnimationAPI.js"); var procAnimAPI = new ProcAnimAPI(); diff --git a/examples/acScripts/bot_randomExpression.js b/examples/acScripts/bot_randomExpression.js index 32bfb24065..b76e485e4a 100644 --- a/examples/acScripts/bot_randomExpression.js +++ b/examples/acScripts/bot_randomExpression.js @@ -12,7 +12,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("../libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; function getRandomFloat(min, max) { return Math.random() * (max - min) + min; diff --git a/examples/clap.js b/examples/clap.js index 2b011404c0..3b333e4345 100644 --- a/examples/clap.js +++ b/examples/clap.js @@ -12,7 +12,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; var clapAnimation = HIFI_PUBLIC_BUCKET + "animations/ClapAnimations/ClapHands_Standing.fbx"; var ANIMATION_FRAMES_PER_CLAP = 10.0; diff --git a/examples/controllers/hydra/airGuitar.js b/examples/controllers/hydra/airGuitar.js index 6d3d374f3a..29ab2f9c44 100644 --- a/examples/controllers/hydra/airGuitar.js +++ b/examples/controllers/hydra/airGuitar.js @@ -10,7 +10,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("../../libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; function length(v) { return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z); diff --git a/examples/controllers/hydra/drumStick.js b/examples/controllers/hydra/drumStick.js index 14e1413742..d2a948b98e 100644 --- a/examples/controllers/hydra/drumStick.js +++ b/examples/controllers/hydra/drumStick.js @@ -10,7 +10,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("../../libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; function length(v) { return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z); diff --git a/examples/controllers/hydra/frisbee.js b/examples/controllers/hydra/frisbee.js index a9fd74910d..461f4691da 100644 --- a/examples/controllers/hydra/frisbee.js +++ b/examples/controllers/hydra/frisbee.js @@ -15,7 +15,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("../../libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; Script.include("../../libraries/toolBars.js"); const LEFT_PALM = 0; diff --git a/examples/controllers/hydra/gun.js b/examples/controllers/hydra/gun.js index b60a70ca36..1f613adf3b 100644 --- a/examples/controllers/hydra/gun.js +++ b/examples/controllers/hydra/gun.js @@ -14,7 +14,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("../../libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; function getRandomFloat(min, max) { return Math.random() * (max - min) + min; diff --git a/examples/controllers/hydra/squeezeHands.js b/examples/controllers/hydra/squeezeHands.js index 84e5aefb51..2a4756f017 100644 --- a/examples/controllers/hydra/squeezeHands.js +++ b/examples/controllers/hydra/squeezeHands.js @@ -9,7 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("../../libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; var rightHandAnimation = HIFI_PUBLIC_BUCKET + "animations/RightHandAnimPhilip.fbx"; var leftHandAnimation = HIFI_PUBLIC_BUCKET + "animations/LeftHandAnimPhilip.fbx"; diff --git a/examples/controllers/hydra/toyball.js b/examples/controllers/hydra/toyball.js index 4dc65703b7..b2ce6c1463 100644 --- a/examples/controllers/hydra/toyball.js +++ b/examples/controllers/hydra/toyball.js @@ -15,7 +15,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("../../libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; // maybe we should make these constants... var LEFT_PALM = 0; diff --git a/examples/controllers/oculus/virtualKeyboard.js b/examples/controllers/oculus/virtualKeyboard.js index dc3c2eb3cc..d17b36ae4f 100644 --- a/examples/controllers/oculus/virtualKeyboard.js +++ b/examples/controllers/oculus/virtualKeyboard.js @@ -15,7 +15,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("../../libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; const KBD_UPPERCASE_DEFAULT = 0; const KBD_LOWERCASE_DEFAULT = 1; diff --git a/examples/editEntities.js b/examples/editEntities.js index 172089ed62..9c045f0a5b 100644 --- a/examples/editEntities.js +++ b/examples/editEntities.js @@ -11,7 +11,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; Script.include("libraries/stringHelpers.js"); Script.include("libraries/dataviewHelpers.js"); Script.include("libraries/httpMultiPart.js"); diff --git a/examples/example/audio/audioBall.js b/examples/example/audio/audioBall.js index 91ef7c0759..4f352ff1a3 100644 --- a/examples/example/audio/audioBall.js +++ b/examples/example/audio/audioBall.js @@ -13,7 +13,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("../../libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; var sound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Animals/mexicanWhipoorwill.raw"); var CHANCE_OF_PLAYING_SOUND = 0.01; diff --git a/examples/example/audio/radio.js b/examples/example/audio/radio.js index 39409df377..7ac33675a1 100644 --- a/examples/example/audio/radio.js +++ b/examples/example/audio/radio.js @@ -9,7 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("../libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; var modelURL = HIFI_PUBLIC_BUCKET + "models/entities/radio/Speakers.fbx"; var soundURL = HIFI_PUBLIC_BUCKET + "sounds/family.stereo.raw"; diff --git a/examples/example/entities/editModelExample.js b/examples/example/entities/editModelExample.js index 474d9afe26..2a58028521 100644 --- a/examples/example/entities/editModelExample.js +++ b/examples/example/entities/editModelExample.js @@ -11,7 +11,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("../../libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; var count = 0; var moveUntil = 2000; diff --git a/examples/example/entities/entityModelExample.js b/examples/example/entities/entityModelExample.js index d09a349cb0..aab2324496 100644 --- a/examples/example/entities/entityModelExample.js +++ b/examples/example/entities/entityModelExample.js @@ -11,7 +11,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("../libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; var count = 0; var stopAfter = 1000; diff --git a/examples/example/games/spaceInvadersExample.js b/examples/example/games/spaceInvadersExample.js index 5ad8bbe4f6..80b03354ff 100644 --- a/examples/example/games/spaceInvadersExample.js +++ b/examples/example/games/spaceInvadersExample.js @@ -11,7 +11,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("../../libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; var iteration = 0; diff --git a/examples/example/ui/overlaysExample.js b/examples/example/ui/overlaysExample.js index 4e85512545..e4e8bf463b 100644 --- a/examples/example/ui/overlaysExample.js +++ b/examples/example/ui/overlaysExample.js @@ -11,7 +11,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("../../libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; // The "Swatches" example of this script will create 9 different image overlays, that use the color feature to // display different colors as color swatches. The overlays can be clicked on, to change the "selectedSwatch" variable diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index 40db7b057a..4b931f0c57 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -11,7 +11,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; SPACE_LOCAL = "local"; SPACE_WORLD = "world"; diff --git a/examples/lobby.js b/examples/lobby.js index 15a8aca328..d1cadedf1e 100644 --- a/examples/lobby.js +++ b/examples/lobby.js @@ -9,7 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; var panelWall = false; var orbShell = false; diff --git a/examples/utilities/diagnostics/inWorldTestTone.js b/examples/utilities/diagnostics/inWorldTestTone.js index 1fc3cbc2c8..77ec7ba3b2 100644 --- a/examples/utilities/diagnostics/inWorldTestTone.js +++ b/examples/utilities/diagnostics/inWorldTestTone.js @@ -11,7 +11,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("../../libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; var sound = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/220Sine.wav"); diff --git a/examples/utilities/diagnostics/playSoundLoop.js b/examples/utilities/diagnostics/playSoundLoop.js index b9d35141d1..faf23761b4 100644 --- a/examples/utilities/diagnostics/playSoundLoop.js +++ b/examples/utilities/diagnostics/playSoundLoop.js @@ -11,7 +11,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("../../libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; // A few sample files you may want to try: diff --git a/examples/utilities/diagnostics/playSoundWave.js b/examples/utilities/diagnostics/playSoundWave.js index 0741b72ef0..e9bf534e35 100644 --- a/examples/utilities/diagnostics/playSoundWave.js +++ b/examples/utilities/diagnostics/playSoundWave.js @@ -9,7 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; var soundClip = SoundCache.getSound(HIFI_PUBLIC_BUCKET + "sounds/Cocktail%20Party%20Snippets/Walken1.wav"); diff --git a/examples/utilities/record/recorder.js b/examples/utilities/record/recorder.js index ddfa3e0315..f3f46adf1a 100644 --- a/examples/utilities/record/recorder.js +++ b/examples/utilities/record/recorder.js @@ -9,7 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -Script.include("libraries/globals.js"); +HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; Script.include("libraries/toolBars.js"); var recordingFile = "recording.rec"; From dcb4d9f02d3d1c27bab238a4e550cfcb0829efb6 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 15 Jan 2015 10:57:35 -0800 Subject: [PATCH 54/93] Update editEntities to do accurate pick on mouse idle --- examples/editEntities.js | 67 ++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 24 deletions(-) diff --git a/examples/editEntities.js b/examples/editEntities.js index 172089ed62..e3314048cf 100644 --- a/examples/editEntities.js +++ b/examples/editEntities.js @@ -527,8 +527,15 @@ function mousePressEvent(event) { var highlightedEntityID = { isKnownID: false }; var mouseCapturedByTool = false; +var lastMousePosition = null; +var idleMouseTimerId = null; +var IDLE_MOUSE_TIMEOUT = 200; function mouseMoveEvent(event) { + if (idleMouseTimerId) { + Script.clearTimeout(idleMouseTimerId); + } + mouseHasMovedSincePress = true; if (isActive) { // allow the selectionDisplay and cameraManager to handle the event first, if it doesn't handle it, then do our own thing @@ -536,36 +543,48 @@ function mouseMoveEvent(event) { return; } - var pickRay = Camera.computePickRay(event.x, event.y); - var entityIntersection = Entities.findRayIntersection(pickRay); - if (entityIntersection.accurate) { - if(highlightedEntityID.isKnownID && highlightedEntityID.id != entityIntersection.entityID.id) { - selectionDisplay.unhighlightSelectable(highlightedEntityID); - highlightedEntityID = { id: -1, isKnownID: false }; - } + lastMousePosition = { x: event.x, y: event.y }; - var halfDiagonal = Vec3.length(entityIntersection.properties.dimensions) / 2.0; - - var angularSize = 2 * Math.atan(halfDiagonal / Vec3.distance(Camera.getPosition(), - entityIntersection.properties.position)) * 180 / 3.14; - - var sizeOK = (allowLargeModels || angularSize < MAX_ANGULAR_SIZE) - && (allowSmallModels || angularSize > MIN_ANGULAR_SIZE); - - if (entityIntersection.entityID.isKnownID && sizeOK) { - if (wantEntityGlow) { - Entities.editEntity(entityIntersection.entityID, { glowLevel: 0.25 }); - } - highlightedEntityID = entityIntersection.entityID; - selectionDisplay.highlightSelectable(entityIntersection.entityID); - } - - } + highlightEntityUnderCursor(lastMousePosition, false); + idleMouseTimerId = Script.setTimeout(handleIdleMouse, IDLE_MOUSE_TIMEOUT); } else { cameraManager.mouseMoveEvent(event); } } +function handleIdleMouse() { + idleMouseTimerId = null; + highlightEntityUnderCursor(lastMousePosition, true); +} + +function highlightEntityUnderCursor(position, accurateRay) { + var pickRay = Camera.computePickRay(position.x, position.y); + var entityIntersection = Entities.findRayIntersection(pickRay, accurateRay === true); + if (entityIntersection.accurate) { + if(highlightedEntityID.isKnownID && highlightedEntityID.id != entityIntersection.entityID.id) { + selectionDisplay.unhighlightSelectable(highlightedEntityID); + highlightedEntityID = { id: -1, isKnownID: false }; + } + + var halfDiagonal = Vec3.length(entityIntersection.properties.dimensions) / 2.0; + + var angularSize = 2 * Math.atan(halfDiagonal / Vec3.distance(Camera.getPosition(), + entityIntersection.properties.position)) * 180 / 3.14; + + var sizeOK = (allowLargeModels || angularSize < MAX_ANGULAR_SIZE) + && (allowSmallModels || angularSize > MIN_ANGULAR_SIZE); + + if (entityIntersection.entityID.isKnownID && sizeOK) { + if (wantEntityGlow) { + Entities.editEntity(entityIntersection.entityID, { glowLevel: 0.25 }); + } + highlightedEntityID = entityIntersection.entityID; + selectionDisplay.highlightSelectable(entityIntersection.entityID); + } + + } +} + function mouseReleaseEvent(event) { if (isActive && selectionManager.hasSelection()) { From bf6d63cf0c8617dd0b19b5352b0bad50c2dd6ab9 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 15 Jan 2015 10:59:24 -0800 Subject: [PATCH 55/93] Make accurateRay parameter required --- examples/editEntities.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/editEntities.js b/examples/editEntities.js index e3314048cf..2212361e24 100644 --- a/examples/editEntities.js +++ b/examples/editEntities.js @@ -559,7 +559,7 @@ function handleIdleMouse() { function highlightEntityUnderCursor(position, accurateRay) { var pickRay = Camera.computePickRay(position.x, position.y); - var entityIntersection = Entities.findRayIntersection(pickRay, accurateRay === true); + var entityIntersection = Entities.findRayIntersection(pickRay, accurateRay); if (entityIntersection.accurate) { if(highlightedEntityID.isKnownID && highlightedEntityID.id != entityIntersection.entityID.id) { selectionDisplay.unhighlightSelectable(highlightedEntityID); From 2177a1701a43e7b8fba3b5f076bb511244bc9ac2 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 15 Jan 2015 11:38:38 -0800 Subject: [PATCH 56/93] more correct cmake config for Bullet (copying pattern from IncludeGLM.cmake) --- cmake/macros/IncludeBullet.cmake | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmake/macros/IncludeBullet.cmake b/cmake/macros/IncludeBullet.cmake index 56b6ce0ced..186e84d1ab 100644 --- a/cmake/macros/IncludeBullet.cmake +++ b/cmake/macros/IncludeBullet.cmake @@ -10,5 +10,7 @@ macro(INCLUDE_BULLET) find_package(Bullet REQUIRED) include_directories("${BULLET_INCLUDE_DIRS}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${BULLET_INCLUDE_DIRS}") + if (APPLE OR UNIX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${BULLET_INCLUDE_DIRS}") + endif() endmacro(INCLUDE_BULLET) From 067483fce200a3bf8e09e8dfef79c323aac914b3 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 15 Jan 2015 11:54:01 -0800 Subject: [PATCH 57/93] Adding a prototype of ambient lighting with spherical harmonics --- libraries/render-utils/src/Material.slh | 2 +- libraries/render-utils/src/Model.cpp | 16 ++---- .../src/directional_light_shadow_map.slf | 53 ++++++++++++++++++- 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/libraries/render-utils/src/Material.slh b/libraries/render-utils/src/Material.slh index 923158af19..86c6049ec6 100755 --- a/libraries/render-utils/src/Material.slh +++ b/libraries/render-utils/src/Material.slh @@ -60,4 +60,4 @@ Material getMaterial() { -<@endif@> \ No newline at end of file +<@endif@> diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 2b9418b82f..af2f67f429 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -2388,26 +2388,16 @@ int Model::renderMeshesFromList(QVector& list, gpu::Batch& batch, RenderMod qDebug() << "part INDEX:" << j; qDebug() << "NEW part.materialID:" << part.materialID; } - - glm::vec4 diffuse = glm::vec4(material->getDiffuse(), material->getOpacity()); - + if (locations->glowIntensity >= 0) { GLBATCH(glUniform1f)(locations->glowIntensity, glowEffect->getIntensity()); } if (!(translucent && alphaThreshold == 0.0f)) { - GLBATCH(glAlphaFunc)(GL_EQUAL, diffuse.a = glowEffect->getIntensity()); + GLBATCH(glAlphaFunc)(GL_EQUAL, glowEffect->getIntensity()); } - glm::vec4 specular = glm::vec4(material->getSpecular(), 1.0f); - float shininess = material->getShininess(); - shininess = (shininess > 128.0f ? 128.0f: shininess); - + if (locations->materialBufferUnit >= 0) { batch.setUniformBuffer(locations->materialBufferUnit, material->getSchemaBuffer()); - } else { - GLBATCH(glMaterialfv)(GL_FRONT, GL_AMBIENT, (const float*)&diffuse); - GLBATCH(glMaterialfv)(GL_FRONT, GL_DIFFUSE, (const float*)&diffuse); - GLBATCH(glMaterialfv)(GL_FRONT, GL_SPECULAR, (const float*)&specular); - GLBATCH(glMaterialf)(GL_FRONT, GL_SHININESS, shininess); } Texture* diffuseMap = networkPart.diffuseTexture.data(); diff --git a/libraries/render-utils/src/directional_light_shadow_map.slf b/libraries/render-utils/src/directional_light_shadow_map.slf index 1a781af131..1edf85b370 100644 --- a/libraries/render-utils/src/directional_light_shadow_map.slf +++ b/libraries/render-utils/src/directional_light_shadow_map.slf @@ -18,6 +18,40 @@ // Everything about shadow <@include Shadow.slh@> + +struct SphericalHarmonics { + vec4 L00; + vec4 L1m1; + vec4 L10; + vec4 L11; + vec4 L2m2; + vec4 L2m1; + vec4 L20; + vec4 L21; + vec4 L22; +}; + +vec4 evalSphericalLight(SphericalHarmonics sh, vec3 direction ) { + + const float C1 = 0.429043; + const float C2 = 0.511664; + const float C3 = 0.743125; + const float C4 = 0.886227; + const float C5 = 0.247708; + + vec4 value = C1 * sh.L22 * (direction.x * direction.x - direction.y * direction.y) + + C3 * sh.L20 * direction.z * direction.z + + C4 * sh.L00 - C5 * sh.L20 + + 2.0 * C1 * ( sh.L2m2 * direction.x * direction.y + + sh.L21 * direction.x * direction.z + + sh.L2m1 * direction.y * direction.z ) + + 2.0 * C2 * ( sh.L11 * direction.x + + sh.L1m1 * direction.y + + sh.L10 * direction.z ) ; + return value; +} + + void main(void) { DeferredFragment frag = unpackDeferredFragment(gl_TexCoord[0].st); vec4 normalVal = frag.normalVal; @@ -31,6 +65,17 @@ void main(void) { // how much this fragment faces the light direction float diffuse = dot(frag.normal, gl_LightSource[0].position.xyz); + SphericalHarmonics sh; + sh.L00 = vec4( 0.79, 0.44, 0.54, 1.0); + sh.L1m1 = vec4( 0.39, 0.35, 0.60, 1.0); + sh.L10 = vec4(-0.34, -0.18, -0.27, 1.0); + sh.L11 = vec4(-0.29, -0.06, 0.01, 1.0); + sh.L2m2 = vec4(-0.11, -0.05, -0.12, 1.0); + sh.L2m1 = vec4(-0.26, -0.22, -0.47, 1.0); + sh.L20 = vec4(-0.16, -0.09, -0.15, 1.0); + sh.L21 = vec4( 0.56, 0.21, 0.14, 1.0); + sh.L22 = vec4( 0.21, -0.05, -0.30, 1.0); + // Light mapped or not ? if ((normalVal.a >= 0.45) && (normalVal.a <= 0.55)) { normalVal.a = 0.0; @@ -53,9 +98,15 @@ void main(void) { // average values from the shadow map float facingLight = step(0.0, diffuse) * shadowAttenuation; + vec4 ambienTerm = 0.5 * evalSphericalLight(sh, frag.normal); + + if (gl_FragCoord.x > 1024) { + ambienTerm = gl_FrontLightProduct[0].ambient.rgba; + } + // compute the base color based on OpenGL lighting model vec3 baseColor = diffuseVal.rgb * (gl_FrontLightModelProduct.sceneColor.rgb + - gl_FrontLightProduct[0].ambient.rgb + gl_FrontLightProduct[0].diffuse.rgb * (diffuse * facingLight)); + ambienTerm.rgb + gl_FrontLightProduct[0].diffuse.rgb * (diffuse * facingLight)); // compute the specular multiplier (sans exponent) float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position.xyz - normalize(frag.position.xyz)), From 93c3b2fb74352c77358fb35329e07173eb61830b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 15 Jan 2015 13:14:26 -0800 Subject: [PATCH 58/93] repairs for new DependencyManager format --- interface/src/Application.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 46ebe98564..dbc409bac2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3165,8 +3165,8 @@ void Application::updateWindowTitle(){ void Application::updateLocationInServer() { AccountManager& accountManager = AccountManager::getInstance(); - AddressManager::SharedPointer addressManager = DependencyManager::get(); - DomainHandler& domainHandler = NodeList::getInstance()->getDomainHandler(); + auto addressManager = DependencyManager::get(); + DomainHandler& domainHandler = DependencyManager::get()->getDomainHandler(); if (accountManager.isLoggedIn() && domainHandler.isConnected() && (!addressManager->getRootPlaceID().isNull() || !domainHandler.getUUID().isNull())) { From 250a3de9fe23d889bfc4fb8d8c20a54acb60f7e5 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 15 Jan 2015 13:34:33 -0800 Subject: [PATCH 59/93] make node mutex in LimitedNodeList recursive for double read lock --- libraries/networking/src/LimitedNodeList.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 6f79b248cf..5bf416af7f 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -41,6 +41,7 @@ const QUrl DEFAULT_NODE_AUTH_URL = QUrl("https://data.highfidelity.io"); LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short dtlsListenPort) : _sessionUUID(), _nodeHash(), + _nodeMutex(QReadWriteLock::Recursive), _nodeSocket(this), _dtlsSocket(NULL), _localSockAddr(), From d820df4972db058449124b56ca37f22b6b1b249e Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Thu, 15 Jan 2015 22:54:32 +0100 Subject: [PATCH 60/93] ScriptModel destructor --- interface/src/ScriptsModel.cpp | 7 +++++++ interface/src/ScriptsModel.h | 1 + interface/src/ui/RunningScriptsWidget.cpp | 1 + 3 files changed, 9 insertions(+) diff --git a/interface/src/ScriptsModel.cpp b/interface/src/ScriptsModel.cpp index 0c711cd940..b09762b73c 100644 --- a/interface/src/ScriptsModel.cpp +++ b/interface/src/ScriptsModel.cpp @@ -67,6 +67,13 @@ ScriptsModel::ScriptsModel(QObject* parent) : reloadRemoteFiles(); } +ScriptsModel::~ScriptsModel() { + for (int i = _treeNodes.size() - 1; i >= 0; i--) { + delete _treeNodes.at(i); + } + _treeNodes.clear(); +} + TreeNodeBase* ScriptsModel::getTreeNodeFromIndex(const QModelIndex& index) const { if (index.isValid()) { return static_cast(index.internalPointer()); diff --git a/interface/src/ScriptsModel.h b/interface/src/ScriptsModel.h index 549f87c0d7..914a197201 100644 --- a/interface/src/ScriptsModel.h +++ b/interface/src/ScriptsModel.h @@ -67,6 +67,7 @@ class ScriptsModel : public QAbstractItemModel { Q_OBJECT public: ScriptsModel(QObject* parent = NULL); + ~ScriptsModel(); QModelIndex index(int row, int column, const QModelIndex& parent) const; QModelIndex parent(const QModelIndex& child) const; QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; diff --git a/interface/src/ui/RunningScriptsWidget.cpp b/interface/src/ui/RunningScriptsWidget.cpp index 46c8f90ff6..4346d813bb 100644 --- a/interface/src/ui/RunningScriptsWidget.cpp +++ b/interface/src/ui/RunningScriptsWidget.cpp @@ -68,6 +68,7 @@ RunningScriptsWidget::RunningScriptsWidget(QWidget* parent) : RunningScriptsWidget::~RunningScriptsWidget() { delete ui; + _scriptsModel.deleteLater(); } void RunningScriptsWidget::updateFileFilter(const QString& filter) { From 786c0a5462b2092628a6fe3dd42954d402948d4f Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 15 Jan 2015 14:00:45 -0800 Subject: [PATCH 61/93] Drop DM ref before creating new object --- libraries/shared/src/DependencyManager.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libraries/shared/src/DependencyManager.h b/libraries/shared/src/DependencyManager.h index e996e10590..3868bf14da 100644 --- a/libraries/shared/src/DependencyManager.h +++ b/libraries/shared/src/DependencyManager.h @@ -83,11 +83,13 @@ template QSharedPointer DependencyManager::set(Args&&... args) { static size_t hashCode = _manager.getHashCode(); - QSharedPointer instance(new T(args...), &T::customDeleter); - QSharedPointer storedInstance = qSharedPointerCast(instance); - _manager.safeGet(hashCode).swap(storedInstance); + QSharedPointer& instance = _manager.safeGet(hashCode); + instance.clear(); // Clear instance before creation of new one to avoid edge cases + QSharedPointer newInstance(new T(args...), &T::customDeleter); + QSharedPointer storedInstance = qSharedPointerCast(newInstance); + instance.swap(storedInstance); - return instance; + return newInstance; } template From cfb996db0c1c83c6365d42a38ca9660c254b3d25 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 15 Jan 2015 14:15:59 -0800 Subject: [PATCH 62/93] Add missing paramaters to Base3DOverlay copy ctor --- interface/src/ui/overlays/Base3DOverlay.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 81f12d7fbb..57c7aa791b 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -41,7 +41,9 @@ Base3DOverlay::Base3DOverlay(const Base3DOverlay* base3DOverlay) : _rotation(base3DOverlay->_rotation), _isSolid(base3DOverlay->_isSolid), _isDashedLine(base3DOverlay->_isDashedLine), - _ignoreRayIntersection(base3DOverlay->_ignoreRayIntersection) + _ignoreRayIntersection(base3DOverlay->_ignoreRayIntersection), + _drawInFront(base3DOverlay->_drawInFront), + _drawOnHUD(base3DOverlay->_drawOnHUD) { } From 6836f23574c0c7a9b9f704c68b528bea56bce86a Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 15 Jan 2015 14:53:55 -0800 Subject: [PATCH 63/93] add custom FindBullet.cmake module --- cmake/modules/FindBullet.cmake | 89 ++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 cmake/modules/FindBullet.cmake diff --git a/cmake/modules/FindBullet.cmake b/cmake/modules/FindBullet.cmake new file mode 100644 index 0000000000..3487abb233 --- /dev/null +++ b/cmake/modules/FindBullet.cmake @@ -0,0 +1,89 @@ +# - Try to find the Bullet physics engine +# +# This module defines the following variables +# +# BULLET_FOUND - Was bullet found +# BULLET_INCLUDE_DIRS - the Bullet include directories +# BULLET_LIBRARIES - Link to this, by default it includes +# all bullet components (Dynamics, +# Collision, LinearMath, & SoftBody) +# +# This module accepts the following variables +# +# BULLET_ROOT - Can be set to bullet install path or Windows build path +# +# Modified on 2015.01.15 by Andrew Meadows +# This is an adapted version of the FindBullet.cmake module distributed with Cmake 2.8.12.2 +# The original license for that file is displayed below. +# +#============================================================================= +# Copyright 2009 Kitware, Inc. +# Copyright 2009 Philip Lowman +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +macro(_FIND_BULLET_LIBRARY _var) + find_library(${_var} + NAMES + ${ARGN} + HINTS + $ENV{HIFI_LIB_DIR}/bullet + $ENV{BULLET_ROOT_DIR} + ${BULLET_ROOT} + ${BULLET_ROOT}/lib/Release + ${BULLET_ROOT}/lib/Debug + ${BULLET_ROOT}/out/release8/libs + ${BULLET_ROOT}/out/debug8/libs + PATH_SUFFIXES lib + ) + mark_as_advanced(${_var}) +endmacro() + +macro(_BULLET_APPEND_LIBRARIES _list _release) + set(_debug ${_release}_DEBUG) + if(${_debug}) + set(${_list} ${${_list}} optimized ${${_release}} debug ${${_debug}}) + else() + set(${_list} ${${_list}} ${${_release}}) + endif() +endmacro() + +find_path(BULLET_INCLUDE_DIR NAMES btBulletCollisionCommon.h + HINTS + ${BULLET_ROOT}/include + ${BULLET_ROOT}/src + PATH_SUFFIXES bullet +) + +# Find the libraries + +_FIND_BULLET_LIBRARY(BULLET_DYNAMICS_LIBRARY BulletDynamics) +#_FIND_BULLET_LIBRARY(BULLET_DYNAMICS_LIBRARY_DEBUG BulletDynamics_Debug BulletDynamics_d) +_FIND_BULLET_LIBRARY(BULLET_COLLISION_LIBRARY BulletCollision) +#_FIND_BULLET_LIBRARY(BULLET_COLLISION_LIBRARY_DEBUG BulletCollision_Debug BulletCollision_d) +_FIND_BULLET_LIBRARY(BULLET_MATH_LIBRARY BulletMath LinearMath) +#_FIND_BULLET_LIBRARY(BULLET_MATH_LIBRARY_DEBUG BulletMath_Debug BulletMath_d LinearMath_Debug LinearMath_d) +_FIND_BULLET_LIBRARY(BULLET_SOFTBODY_LIBRARY BulletSoftBody) +#_FIND_BULLET_LIBRARY(BULLET_SOFTBODY_LIBRARY_DEBUG BulletSoftBody_Debug BulletSoftBody_d) + + +find_package_handle_standard_args(Bullet "Could NOT find Bullet, try to set the path to Bullet root folder in the system variable BULLET_ROOT_DIR" + BULLET_DYNAMICS_LIBRARY BULLET_COLLISION_LIBRARY BULLET_MATH_LIBRARY + BULLET_INCLUDE_DIR +) + +set(BULLET_INCLUDE_DIRS ${BULLET_INCLUDE_DIR}) +if(BULLET_FOUND) + _BULLET_APPEND_LIBRARIES(BULLET_LIBRARIES BULLET_DYNAMICS_LIBRARY) + _BULLET_APPEND_LIBRARIES(BULLET_LIBRARIES BULLET_COLLISION_LIBRARY) + _BULLET_APPEND_LIBRARIES(BULLET_LIBRARIES BULLET_MATH_LIBRARY) + _BULLET_APPEND_LIBRARIES(BULLET_LIBRARIES BULLET_SOFTBODY_LIBRARY) +endif() From 00f4e92e06920168d0ab9a7a342433097b341bf6 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 15 Jan 2015 14:58:49 -0800 Subject: [PATCH 64/93] fix places array grab --- examples/lobby.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/lobby.js b/examples/lobby.js index 2367819524..87ffddcf17 100644 --- a/examples/lobby.js +++ b/examples/lobby.js @@ -166,7 +166,7 @@ function changeLobbyTextures() { for (var j = 0; j < NUM_PANELS; j++) { var panelIndex = placeIndexToPanelIndex(j); textureProp["textures"]["file" + panelIndex] = HIFI_PUBLIC_BUCKET + "images/places/" - + place[j].id + "/hifi-place-" + place[j].id + "_640x360.jpg"; + + places[j].id + "/hifi-place-" + places[j].id + "_640x360.jpg"; }; Overlays.editOverlay(panelWall, textureProp); From 336f28e0146b8b0f4439b06e42a8391cd9c071c9 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 15 Jan 2015 15:00:42 -0800 Subject: [PATCH 65/93] repair to places array length --- examples/lobby.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/lobby.js b/examples/lobby.js index 87ffddcf17..636f0a95f1 100644 --- a/examples/lobby.js +++ b/examples/lobby.js @@ -253,7 +253,7 @@ function actionStartEvent(event) { if (panelStringIndex != -1) { var panelIndex = parseInt(panelName.slice(5)); var placeIndex = panelIndexToPlaceIndex(panelIndex); - if (placeIndex < place.length) { + if (placeIndex < places.length) { var actionPlace = places[placeIndex]; print("Jumping to " + actionPlace.name + " at " + actionPlace.address From 7ae9635ce7e49c0444e4c9697b54460deff8400a Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 15 Jan 2015 15:27:18 -0800 Subject: [PATCH 66/93] Refactoring the code from directional into DeferredLighting.slh --- libraries/render-utils/src/DeferredBuffer.slh | 9 ++ .../render-utils/src/DeferredLighting.slh | 89 +++++++++++++++++++ .../src/DeferredLightingEffect.cpp | 6 ++ .../render-utils/src/DeferredLightingEffect.h | 19 ++++ .../render-utils/src/directional_light.slf | 11 +++ 5 files changed, 134 insertions(+) create mode 100755 libraries/render-utils/src/DeferredLighting.slh diff --git a/libraries/render-utils/src/DeferredBuffer.slh b/libraries/render-utils/src/DeferredBuffer.slh index da02ef750e..885fa96543 100755 --- a/libraries/render-utils/src/DeferredBuffer.slh +++ b/libraries/render-utils/src/DeferredBuffer.slh @@ -42,6 +42,10 @@ struct DeferredFragment { vec4 specularVal; vec4 position; vec3 normal; + vec3 diffuse; + float opacity; + vec3 specular; + float gloss; }; DeferredFragment unpackDeferredFragment(vec2 texcoord) { @@ -58,6 +62,11 @@ DeferredFragment unpackDeferredFragment(vec2 texcoord) { // Unpack the normal from the map frag.normal = normalize(frag.normalVal.xyz * 2.0 - vec3(1.0)); + frag.diffuse = frag.diffuseVal.xyz; + frag.opacity = frag.diffuseVal.w; + frag.specular = frag.specularVal.xyz; + frag.gloss = frag.specularVal.w; + return frag; } diff --git a/libraries/render-utils/src/DeferredLighting.slh b/libraries/render-utils/src/DeferredLighting.slh new file mode 100755 index 0000000000..71021255dc --- /dev/null +++ b/libraries/render-utils/src/DeferredLighting.slh @@ -0,0 +1,89 @@ + +<@if not DEFERRED_LIGHTING_SLH@> +<@def DEFERRED_LIGHTING_SLH@> + +struct SphericalHarmonics { + vec4 L00; + vec4 L1m1; + vec4 L10; + vec4 L11; + vec4 L2m2; + vec4 L2m1; + vec4 L20; + vec4 L21; + vec4 L22; +}; + +vec4 evalSphericalLight(SphericalHarmonics sh, vec3 direction ) { + + const float C1 = 0.429043; + const float C2 = 0.511664; + const float C3 = 0.743125; + const float C4 = 0.886227; + const float C5 = 0.247708; + + vec4 value = C1 * sh.L22 * (direction.x * direction.x - direction.y * direction.y) + + C3 * sh.L20 * direction.z * direction.z + + C4 * sh.L00 - C5 * sh.L20 + + 2.0 * C1 * ( sh.L2m2 * direction.x * direction.y + + sh.L21 * direction.x * direction.z + + sh.L2m1 * direction.y * direction.z ) + + 2.0 * C2 * ( sh.L11 * direction.x + + sh.L1m1 * direction.y + + sh.L10 * direction.z ) ; + return value; +} + +uniform SphericalHarmonics ambientSphere; + +vec3 evalAmbientSphereAndDirectionalColor(vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { + // Ambient lighting + vec3 ambientLight = evalSphericalLight(ambientSphere, normal).xyz; + if (gl_FragCoord.x > 1024) { + ambientLight = gl_FrontLightProduct[0].ambient.rgb; + } + vec3 ambientColor = diffuseVal.rgb * ambientLight; + + // Diffuse Lighting + float diffuseDot = dot(frag.normal, gl_LightSource[0].position.xyz); + float facingLight = step(0.0, diffuseDot); + vec3 diffuseColor = diffuse * (gl_FrontLightModelProduct.sceneColor.rgb + gl_FrontLightProduct[0].diffuse.rgb * (diffuseDot * facingLight)); + + // compute the specular multiplier (sans exponent) + float specularPower = facingLight * max(0.0, + dot(normalize(gl_LightSource[0].position.xyz - normalize(position)), normal)); + vec3 specularColor = pow(specularPower, gloss * 128.0) * specular; + + // add specular contribution + return vec3(ambientColor + diffuseColor + specularColor); +} + + +vec3 evalAmbientAndDirectionalColor(vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { + // Ambient lighting + vec3 ambientLight = gl_FrontLightProduct[0].ambient.rgb; + vec3 ambientColor = diffuseVal.rgb * ambientLight; + + // Diffuse + float diffuseDot = dot(frag.normal, gl_LightSource[0].position.xyz); + float facingLight = step(0.0, diffuseDot); + vec3 diffuseColor = diffuse * (gl_FrontLightModelProduct.sceneColor.rgb + gl_FrontLightProduct[0].diffuse.rgb * (diffuseDot * facingLight)); + + // compute the specular multiplier (sans exponent) + float specularPower = facingLight * max(0.0, + dot(normalize(gl_LightSource[0].position.xyz - normalize(position)), normal)); + vec3 specularColor = pow(specularPower, gloss * 128.0) * specular; + + // add specular contribution + return vec3(ambientColor + diffuseColor + specularColor); +} +<@endif@> \ No newline at end of file diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 3ce7c42a74..2d44e2c6bd 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -435,3 +435,9 @@ void DeferredLightingEffect::loadLightProgram(const char* fragSource, bool limit locations.radius = program.uniformLocation("radius"); program.release(); } + +void DeferredLightingEffect::setAmbientLightMode(int preset) { + if ((preset >= -1) && (preset < NUM_PRESET)) { + _ambientLightMode = preset; + } +} \ No newline at end of file diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 810aebd508..2c5087c5cb 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -71,6 +71,23 @@ public: void prepare(); void render(); + enum AmbientLightPreset { + OLD_TOWN_SQUARE = 0, + GRACE_CATHEDRAL, + EUCALYPTUS_GROVE, + ST_PETERS_BASILICA, + UFFIZI_GALLERY, + GALILEOS_TOMB, + VINE_STREET_KITCHEN, + BREEZEWAY, + CAMPUS_SUNSET, + FUNSTON_BEACH_SUNSET, + + NUM_PRESET, + }; + + void setAmbientLightMode(int preset); + private: DeferredLightingEffect() { } virtual ~DeferredLightingEffect() { } @@ -126,6 +143,8 @@ private: QVector _postLightingRenderables; AbstractViewStateInterface* _viewState; + + int _ambientLightMode = -1; }; /// Simple interface for objects that require something to be rendered after deferred lighting. diff --git a/libraries/render-utils/src/directional_light.slf b/libraries/render-utils/src/directional_light.slf index db963be913..733da47f8b 100644 --- a/libraries/render-utils/src/directional_light.slf +++ b/libraries/render-utils/src/directional_light.slf @@ -15,6 +15,8 @@ // Everything about deferred buffer <@include DeferredBuffer.slh@> +<@include DeferredLighting.slh@> + void main(void) { DeferredFragment frag = unpackDeferredFragment(gl_TexCoord[0].st); @@ -26,6 +28,14 @@ void main(void) { if ((normalVal.a >= 0.45) && (normalVal.a <= 0.55)) { gl_FragColor = vec4(diffuseVal.rgb * specularVal.rgb, 1.0); } else { + glFragColor = vec4( evalAmbientAndDirectionalColor(frag.position.xyz, + frag.normal, + frag.diffuse, + frag.specular, + frag.gloss), + normalVal.a); + +/* // compute the base color based on OpenGL lighting model float diffuse = dot(frag.normal, gl_LightSource[0].position.xyz); float facingLight = step(0.0, diffuse); @@ -39,5 +49,6 @@ void main(void) { // add specular contribution vec4 specularColor = specularVal; gl_FragColor = vec4(baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb, normalVal.a); +*/ } } From cdaecbd8469b5a3d52f5ceb4a9d2f398ee1c380d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 15 Jan 2015 16:40:13 -0800 Subject: [PATCH 67/93] Update lobby.js --- examples/lobby.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/lobby.js b/examples/lobby.js index 636f0a95f1..fcac7a490b 100644 --- a/examples/lobby.js +++ b/examples/lobby.js @@ -165,8 +165,7 @@ function changeLobbyTextures() { for (var j = 0; j < NUM_PANELS; j++) { var panelIndex = placeIndexToPanelIndex(j); - textureProp["textures"]["file" + panelIndex] = HIFI_PUBLIC_BUCKET + "images/places/" - + places[j].id + "/hifi-place-" + places[j].id + "_640x360.jpg"; + textureProp["textures"]["file" + panelIndex] = places[j].previews.lobby; }; Overlays.editOverlay(panelWall, textureProp); From 61caf5e4b4d7e78af4e606b4d36fcabcfcc638c1 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 15 Jan 2015 17:24:25 -0800 Subject: [PATCH 68/93] Fix path to hydraMove.js --- examples/defaultScripts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/defaultScripts.js b/examples/defaultScripts.js index cdb8e76c65..a14958dd23 100644 --- a/examples/defaultScripts.js +++ b/examples/defaultScripts.js @@ -11,7 +11,7 @@ Script.load("lookWithTouch.js"); Script.load("editEntities.js"); Script.load("selectAudioDevice.js"); -Script.load("hydraMove.js"); +Script.load("controllers/hydra/hydraMove.js"); Script.load("headMove.js"); Script.load("inspect.js"); Script.load("lobby.js"); From a07b5a9723ed28f6cfcb3b21c53fd6fc315ece19 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Thu, 15 Jan 2015 17:34:52 -0800 Subject: [PATCH 69/93] laser pointers to guns, toppling targets (press 't') --- examples/controllers/hydra/gun.js | 98 ++++++++++++++++--------------- 1 file changed, 52 insertions(+), 46 deletions(-) diff --git a/examples/controllers/hydra/gun.js b/examples/controllers/hydra/gun.js index 1f613adf3b..e3450b708e 100644 --- a/examples/controllers/hydra/gun.js +++ b/examples/controllers/hydra/gun.js @@ -16,6 +16,27 @@ HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; +var RED = { red: 255, green: 0, blue: 0 }; +var LASER_WIDTH = 2; + +var pointer = []; +pointer.push(Overlays.addOverlay("line3d", { + start: { x: 0, y: 0, z: 0 }, + end: { x: 0, y: 0, z: 0 }, + color: RED, + alpha: 1, + visible: true, + lineWidth: LASER_WIDTH +})); +pointer.push(Overlays.addOverlay("line3d", { + start: { x: 0, y: 0, z: 0 }, + end: { x: 0, y: 0, z: 0 }, + color: RED, + alpha: 1, + visible: true, + lineWidth: LASER_WIDTH +})); + function getRandomFloat(min, max) { return Math.random() * (max - min) + min; } @@ -26,7 +47,7 @@ var yawFromMouse = 0; var pitchFromMouse = 0; var isMouseDown = false; -var BULLET_VELOCITY = 20.0; +var BULLET_VELOCITY = 5.0; var MIN_THROWER_DELAY = 1000; var MAX_THROWER_DELAY = 1000; var LEFT_BUTTON_3 = 3; @@ -106,8 +127,6 @@ if (showScore) { }); } - - function printVector(string, vector) { print(string + " " + vector.x + ", " + vector.y + ", " + vector.z); } @@ -115,7 +134,7 @@ function printVector(string, vector) { function shootBullet(position, velocity) { var BULLET_SIZE = 0.07; var BULLET_LIFETIME = 10.0; - var BULLET_GRAVITY = -0.02; + var BULLET_GRAVITY = 0.0; bulletID = Entities.addEntity( { type: "Sphere", position: position, @@ -124,6 +143,8 @@ function shootBullet(position, velocity) { velocity: velocity, lifetime: BULLET_LIFETIME, gravity: { x: 0, y: BULLET_GRAVITY, z: 0 }, + damping: 0.01, + density: 5000, ignoreCollisions: false, collisionsWillMove: true }); @@ -146,11 +167,11 @@ function shootBullet(position, velocity) { function shootTarget() { var TARGET_SIZE = 0.50; - var TARGET_GRAVITY = -0.25; + var TARGET_GRAVITY = 0.0; var TARGET_LIFETIME = 300.0; - var TARGET_UP_VELOCITY = 0.5; - var TARGET_FWD_VELOCITY = 1.0; - var DISTANCE_TO_LAUNCH_FROM = 3.0; + var TARGET_UP_VELOCITY = 0.0; + var TARGET_FWD_VELOCITY = 0.0; + var DISTANCE_TO_LAUNCH_FROM = 5.0; var ANGLE_RANGE_FOR_LAUNCH = 20.0; var camera = Camera.getPosition(); //printVector("camera", camera); @@ -166,13 +187,14 @@ function shootTarget() { targetID = Entities.addEntity( { type: "Box", position: newPosition, - dimensions: { x: TARGET_SIZE, y: TARGET_SIZE, z: TARGET_SIZE }, - color: { red: 0, green: 200, blue: 200 }, - //angularVelocity: { x: 1, y: 0, z: 0 }, + dimensions: { x: TARGET_SIZE * (0.5 + Math.random()), y: TARGET_SIZE * (0.5 + Math.random()), z: TARGET_SIZE * (0.5 + Math.random()) / 4.0 }, + color: { red: Math.random() * 255, green: Math.random() * 255, blue: Math.random() * 255 }, velocity: velocity, gravity: { x: 0, y: TARGET_GRAVITY, z: 0 }, lifetime: TARGET_LIFETIME, - damping: 0.0001, + rotation: Camera.getOrientation(), + damping: 0.1, + density: 100.0, collisionsWillMove: true }); // Record start time @@ -183,8 +205,6 @@ function shootTarget() { Audio.playSound(targetLaunchSound, audioOptions); } - - function entityCollisionWithEntity(entity1, entity2, collision) { if (((entity1.id == bulletID.id) || (entity1.id == targetID.id)) && @@ -212,7 +232,7 @@ function keyPressEvent(event) { if (event.text == "t") { var time = MIN_THROWER_DELAY + Math.random() * MAX_THROWER_DELAY; Script.setTimeout(shootTarget, time); - } else if (event.text == ".") { + } else if ((event.text == ".") || (event.text == "SPACE")) { shootFromMouse(); } else if (event.text == "r") { playLoadSound(); @@ -254,7 +274,7 @@ function takeFiringPose() { } } -//MyAvatar.attach(gunModel, "RightHand", {x:0.02, y: 0.11, z: 0.04}, Quat.fromPitchYawRollDegrees(-0, -160, -79), 0.20); +MyAvatar.attach(gunModel, "RightHand", {x:0.02, y: 0.11, z: 0.04}, Quat.fromPitchYawRollDegrees(-0, -160, -79), 0.20); MyAvatar.attach(gunModel, "LeftHand", {x:-0.02, y: 0.11, z: 0.04}, Quat.fromPitchYawRollDegrees(0, 0, 79), 0.20); // Give a bit of time to load before playing sound @@ -262,7 +282,6 @@ Script.setTimeout(playLoadSound, 2000); function update(deltaTime) { if (bulletID && !bulletID.isKnownID) { - print("Trying to identify bullet"); bulletID = Entities.identifyEntity(bulletID); } if (targetID && !targetID.isKnownID) { @@ -304,15 +323,6 @@ function update(deltaTime) { } } - // Check hydra controller for launch button press - if (!isLaunchButtonPressed && Controller.isButtonPressed(LEFT_BUTTON_3)) { - isLaunchButtonPressed = true; - var time = MIN_THROWER_DELAY + Math.random() * MAX_THROWER_DELAY; - Script.setTimeout(shootTarget, time); - } else if (isLaunchButtonPressed && !Controller.isButtonPressed(LEFT_BUTTON_3)) { - isLaunchButtonPressed = false; - - } // check for trigger press @@ -335,14 +345,21 @@ function update(deltaTime) { shootABullet = true; } } + var palmController = t * controllersPerTrigger; + var palmPosition = Controller.getSpatialControlPosition(palmController); + var fingerTipController = palmController + 1; + var fingerTipPosition = Controller.getSpatialControlPosition(fingerTipController); + var laserTip = Vec3.sum(Vec3.multiply(100.0, Vec3.subtract(fingerTipPosition, palmPosition)), palmPosition); + + // Update Lasers + Overlays.editOverlay(pointer[t], { + start: palmPosition, + end: laserTip, + alpha: 1 + }); if (shootABullet) { - var palmController = t * controllersPerTrigger; - var palmPosition = Controller.getSpatialControlPosition(palmController); - - var fingerTipController = palmController + 1; - var fingerTipPosition = Controller.getSpatialControlPosition(fingerTipController); - + var palmToFingerTipVector = { x: (fingerTipPosition.x - palmPosition.x), y: (fingerTipPosition.y - palmPosition.y), @@ -361,20 +378,8 @@ function update(deltaTime) { } } -function mousePressEvent(event) { - isMouseDown = true; - lastX = event.x; - lastY = event.y; - - if (Overlays.getOverlayAtPoint({ x: event.x, y: event.y }) === offButton) { - Script.stop(); - } else { - shootFromMouse(); - } -} - function shootFromMouse() { - var DISTANCE_FROM_CAMERA = 2.0; + var DISTANCE_FROM_CAMERA = 1.0; var camera = Camera.getPosition(); var forwardVector = Quat.getFront(Camera.getOrientation()); var newPosition = Vec3.sum(camera, Vec3.multiply(forwardVector, DISTANCE_FROM_CAMERA)); @@ -402,6 +407,8 @@ function mouseMoveEvent(event) { function scriptEnding() { Overlays.deleteOverlay(reticle); Overlays.deleteOverlay(offButton); + Overlays.deleteOverlay(pointer[0]); + Overlays.deleteOverlay(pointer[1]); Overlays.deleteOverlay(text); MyAvatar.detachOne(gunModel); clearPose(); @@ -410,7 +417,6 @@ function scriptEnding() { Entities.entityCollisionWithEntity.connect(entityCollisionWithEntity); Script.scriptEnding.connect(scriptEnding); Script.update.connect(update); -Controller.mousePressEvent.connect(mousePressEvent); Controller.mouseReleaseEvent.connect(mouseReleaseEvent); Controller.mouseMoveEvent.connect(mouseMoveEvent); Controller.keyPressEvent.connect(keyPressEvent); From 891cb42eff45f9b5deb9af7a059066029c291ba0 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 15 Jan 2015 17:41:59 -0800 Subject: [PATCH 70/93] use new place names in domain-server settings --- domain-server/resources/web/js/settings.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/domain-server/resources/web/js/settings.js b/domain-server/resources/web/js/settings.js index 1e9051d717..1ca11af0e1 100644 --- a/domain-server/resources/web/js/settings.js +++ b/domain-server/resources/web/js/settings.js @@ -652,7 +652,7 @@ function chooseFromHighFidelityDomains(clickedButton) { clickedButton.attr('disabled', 'disabled') // get a list of user domains from data-web - data_web_domains_url = "https://data.highfidelity.io/api/v1/domains?access_token=" + data_web_domains_url = "http://localhost:3000/api/v1/domains?access_token=" $.getJSON(data_web_domains_url + Settings.initialValues.metaverse.access_token, function(data){ modal_buttons = { @@ -667,7 +667,7 @@ function chooseFromHighFidelityDomains(clickedButton) { modal_body = "

Choose the High Fidelity domain you want this domain-server to represent.
This will set your domain ID on the settings page.

" domain_select = $("") _.each(data.data.domains, function(domain){ - domain_select.append("") + domain_select.append(""); }) modal_body += "" + domain_select[0].outerHTML modal_buttons["success"] = { From 2c1d4c8a64263f8193087879454b0c1a2c2d5147 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 15 Jan 2015 17:44:15 -0800 Subject: [PATCH 71/93] fix settings url to check domains --- domain-server/resources/web/js/settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/resources/web/js/settings.js b/domain-server/resources/web/js/settings.js index 1ca11af0e1..bdd80df9ec 100644 --- a/domain-server/resources/web/js/settings.js +++ b/domain-server/resources/web/js/settings.js @@ -652,7 +652,7 @@ function chooseFromHighFidelityDomains(clickedButton) { clickedButton.attr('disabled', 'disabled') // get a list of user domains from data-web - data_web_domains_url = "http://localhost:3000/api/v1/domains?access_token=" + data_web_domains_url = "https://data.highfidelity.io/api/v1/domains?access_token=" $.getJSON(data_web_domains_url + Settings.initialValues.metaverse.access_token, function(data){ modal_buttons = { From 250fd98fee02cb372a1ab45b876ffeeaae2d3cc8 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 15 Jan 2015 17:51:01 -0800 Subject: [PATCH 72/93] support for simple kinematic motion --- interface/src/Application.h | 1 + libraries/entities/src/EntityItem.cpp | 48 +++++++++++++++++++ libraries/entities/src/EntityItem.h | 2 + libraries/physics/src/EntityMotionState.cpp | 37 ++++++++++++-- libraries/physics/src/EntityMotionState.h | 7 ++- libraries/physics/src/KinematicController.cpp | 22 +++++++++ libraries/physics/src/KinematicController.h | 37 ++++++++++++++ libraries/physics/src/ObjectMotionState.cpp | 17 +++++-- libraries/physics/src/ObjectMotionState.h | 7 ++- libraries/physics/src/PhysicsEngine.cpp | 31 +++++++----- libraries/physics/src/PhysicsEngine.h | 12 ++--- libraries/physics/src/PhysicsEntity.h | 4 -- .../src/SimpleEntityKinematicController.cpp | 21 ++++++++ .../src/SimpleEntityKinematicController.h | 36 ++++++++++++++ 14 files changed, 251 insertions(+), 31 deletions(-) create mode 100644 libraries/physics/src/KinematicController.cpp create mode 100644 libraries/physics/src/KinematicController.h create mode 100644 libraries/physics/src/SimpleEntityKinematicController.cpp create mode 100644 libraries/physics/src/SimpleEntityKinematicController.h diff --git a/interface/src/Application.h b/interface/src/Application.h index d9ec5a1eae..94ae8fa189 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 885d589ed1..6792cf0d3e 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -742,6 +742,54 @@ void EntityItem::simulate(const quint64& now) { _lastSimulated = now; } +void EntityItem::simulateSimpleKinematicMotion(float timeElapsed) { + if (hasAngularVelocity()) { + // angular damping + glm::vec3 angularVelocity = getAngularVelocity(); + if (_angularDamping > 0.0f) { + angularVelocity *= powf(1.0f - _angularDamping, timeElapsed); + setAngularVelocity(angularVelocity); + } + + float angularSpeed = glm::length(_angularVelocity); + const float EPSILON_ANGULAR_VELOCITY_LENGTH = 0.1f; // + if (angularSpeed < EPSILON_ANGULAR_VELOCITY_LENGTH) { + setAngularVelocity(ENTITY_ITEM_ZERO_VEC3); + } else { + // NOTE: angularSpeed is currently in degrees/sec!!! + // TODO: Andrew to convert to radians/sec + float angle = timeElapsed * glm::radians(angularSpeed); + glm::vec3 axis = _angularVelocity / angularSpeed; + glm::quat dQ = glm::angleAxis(angle, axis); + glm::quat rotation = getRotation(); + rotation = glm::normalize(dQ * rotation); + setRotation(rotation); + } + } + + if (hasVelocity()) { + // linear damping + glm::vec3 velocity = getVelocity(); + if (_damping > 0.0f) { + velocity *= powf(1.0f - _damping, timeElapsed); + } + + // integrate position forward + glm::vec3 position = getPosition() + (velocity * timeElapsed); + + // apply gravity + if (hasGravity()) { + // handle resting on surface case, this is definitely a bit of a hack, and it only works on the + // "ground" plane of the domain, but for now it's what we've got + velocity += getGravity() * timeElapsed; + } + + // NOTE: the simulation should NOT set any DirtyFlags on this entity + setPosition(position); // this will automatically recalculate our collision shape + setVelocity(velocity); + } +} + bool EntityItem::isMoving() const { #ifdef USE_BULLET_PHYSICS // When Bullet is available we assume that "zero velocity" means "at rest" diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index b84739e07e..8f5c0ed88a 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -128,6 +128,8 @@ public: // perform linear extrapolation for SimpleEntitySimulation void simulate(const quint64& now); + + void simulateSimpleKinematicMotion(float timeElapsed); virtual bool needsToCallUpdate() const { return false; } diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 019f00fb48..2f2f4f836a 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -16,6 +16,8 @@ #include "BulletUtil.h" #endif // USE_BULLET_PHYSICS #include "EntityMotionState.h" +#include "SimpleEntityKinematicController.h" + QSet* _outgoingEntityList; @@ -40,13 +42,24 @@ EntityMotionState::~EntityMotionState() { assert(_entity); _entity->setPhysicsInfo(NULL); _entity = NULL; + delete _kinematicController; + _kinematicController = NULL; } MotionType EntityMotionState::computeMotionType() const { - // HACK: According to EntityTree the meaning of "static" is "not moving" whereas - // to Bullet it means "can't move". For demo purposes we temporarily interpret - // Entity::weightless to mean Bullet::static. - return _entity->getCollisionsWillMove() ? MOTION_TYPE_DYNAMIC : MOTION_TYPE_STATIC; + if (_entity->getCollisionsWillMove()) { + return MOTION_TYPE_DYNAMIC; + } + return _entity->isMoving() ? MOTION_TYPE_KINEMATIC : MOTION_TYPE_STATIC; +} + +void EntityMotionState::addKinematicController() { + if (!_kinematicController) { + _kinematicController = new SimpleEntityKinematicController(_entity); + _kinematicController->start(); + } else { + _kinematicController->start(); + } } #ifdef USE_BULLET_PHYSICS @@ -56,6 +69,9 @@ MotionType EntityMotionState::computeMotionType() const { // (2) at the beginning of each simulation frame for KINEMATIC RigidBody's -- // it is an opportunity for outside code to update the object's simulation position void EntityMotionState::getWorldTransform(btTransform& worldTrans) const { + if (_kinematicController && _kinematicController->isRunning()) { + _kinematicController->stepForward(); + } worldTrans.setOrigin(glmToBullet(_entity->getPositionInMeters() - ObjectMotionState::getWorldOffset())); worldTrans.setRotation(glmToBullet(_entity->getRotation())); } @@ -211,3 +227,16 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ } #endif // USE_BULLET_PHYSICS } + +uint32_t EntityMotionState::getIncomingDirtyFlags() const { + uint32_t dirtyFlags = _entity->getDirtyFlags(); + + // we add DIRTY_MOTION_TYPE if the body's motion type disagrees with entity velocity settings + int bodyFlags = _body->getCollisionFlags(); + bool isMoving = _entity->isMoving(); + if (((bodyFlags & btCollisionObject::CF_STATIC_OBJECT) && isMoving) || + (bodyFlags & btCollisionObject::CF_KINEMATIC_OBJECT && !isMoving)) { + dirtyFlags |= EntityItem::DIRTY_MOTION_TYPE; + } + return dirtyFlags; +} diff --git a/libraries/physics/src/EntityMotionState.h b/libraries/physics/src/EntityMotionState.h index 863edebe7d..a4acfa6193 100644 --- a/libraries/physics/src/EntityMotionState.h +++ b/libraries/physics/src/EntityMotionState.h @@ -15,6 +15,7 @@ #include #include "ObjectMotionState.h" + #ifndef USE_BULLET_PHYSICS // ObjectMotionState stubbery class ObjectMotionState { @@ -39,12 +40,16 @@ public: static void setOutgoingEntityList(QSet* list); static void enqueueOutgoingEntity(EntityItem* entity); + EntityMotionState() = delete; // prevent compiler from making default ctor EntityMotionState(EntityItem* item); virtual ~EntityMotionState(); /// \return MOTION_TYPE_DYNAMIC or MOTION_TYPE_STATIC based on params set in EntityItem MotionType computeMotionType() const; + // virtual override for ObjectMotionState + void addKinematicController(); + #ifdef USE_BULLET_PHYSICS // this relays incoming position/rotation to the RigidBody void getWorldTransform(btTransform& worldTrans) const; @@ -61,7 +66,7 @@ public: void sendUpdate(OctreeEditPacketSender* packetSender, uint32_t frame); - uint32_t getIncomingDirtyFlags() const { return _entity->getDirtyFlags(); } + uint32_t getIncomingDirtyFlags() const; void clearIncomingDirtyFlags(uint32_t flags) { _entity->clearDirtyFlags(flags); } protected: diff --git a/libraries/physics/src/KinematicController.cpp b/libraries/physics/src/KinematicController.cpp new file mode 100644 index 0000000000..abcf669694 --- /dev/null +++ b/libraries/physics/src/KinematicController.cpp @@ -0,0 +1,22 @@ +// +// KinematicController.cpp +// libraries/physcis/src +// +// Created by Andrew Meadows 2015.01.13 +// 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 "KinematicController.h" +#include "PhysicsEngine.h" + +KinematicController::KinematicController() { + _lastFrame = PhysicsEngine::getFrameCount(); +} + +void KinematicController::start() { + _enabled = true; + _lastFrame = PhysicsEngine::getFrameCount(); +} diff --git a/libraries/physics/src/KinematicController.h b/libraries/physics/src/KinematicController.h new file mode 100644 index 0000000000..c1240c29e4 --- /dev/null +++ b/libraries/physics/src/KinematicController.h @@ -0,0 +1,37 @@ +// +// KinematicController.h +// libraries/physcis/src +// +// Created by Andrew Meadows 2015.01.13 +// 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_KinematicController_h +#define hifi_KinematicController_h + +#include +#include + +/// KinematicController defines an API for derived classes. + +class KinematicController { +public: + KinematicController(); + + virtual ~KinematicController() {} + + virtual void stepForward() = 0; + + void start(); + void stop() { _enabled = false; } + bool isRunning() const { return _enabled; } + +protected: + bool _enabled = false; + uint32_t _lastFrame; +}; + +#endif // hifi_KinematicController_h diff --git a/libraries/physics/src/ObjectMotionState.cpp b/libraries/physics/src/ObjectMotionState.cpp index 6e0b2a784c..c5bbb0e899 100644 --- a/libraries/physics/src/ObjectMotionState.cpp +++ b/libraries/physics/src/ObjectMotionState.cpp @@ -14,7 +14,9 @@ #include #include "BulletUtil.h" +#include "KinematicController.h" #include "ObjectMotionState.h" +#include "PhysicsEngine.h" const float MIN_DENSITY = 200.0f; const float DEFAULT_DENSITY = 1000.0f; @@ -67,6 +69,10 @@ ObjectMotionState::ObjectMotionState() : ObjectMotionState::~ObjectMotionState() { // NOTE: you MUST remove this MotionState from the world before you call the dtor. assert(_body == NULL); + if (_kinematicController) { + delete _kinematicController; + _kinematicController = NULL; + } } void ObjectMotionState::setDensity(float density) { @@ -121,11 +127,9 @@ bool ObjectMotionState::doesNotNeedToSendUpdate() const { return !_body->isActive() && _numNonMovingUpdates > MAX_NUM_NON_MOVING_UPDATES; } -const float FIXED_SUBSTEP = 1.0f / 60.0f; - bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame) { assert(_body); - float dt = (float)(simulationFrame - _sentFrame) * FIXED_SUBSTEP; + float dt = (float)(simulationFrame - _sentFrame) * PHYSICS_ENGINE_FIXED_SUBSTEP; _sentFrame = simulationFrame; bool isActive = _body->isActive(); @@ -186,4 +190,11 @@ bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame) { return (fabsf(glm::dot(actualRotation, _sentRotation)) < MIN_ROTATION_DOT); } +void ObjectMotionState::removeKinematicController() { + if (_kinematicController) { + delete _kinematicController; + _kinematicController = NULL; + } +} + #endif // USE_BULLET_PHYSICS diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index b9d077f4bb..1ea3411286 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -22,7 +22,6 @@ enum MotionType { // The update flags trigger two varieties of updates: "hard" which require the body to be pulled // and re-added to the physics engine and "easy" which just updates the body properties. -typedef unsigned int uint32_t; const uint32_t HARD_DIRTY_PHYSICS_FLAGS = (uint32_t)(EntityItem::DIRTY_MOTION_TYPE | EntityItem::DIRTY_SHAPE); const uint32_t EASY_DIRTY_PHYSICS_FLAGS = (uint32_t)(EntityItem::DIRTY_POSITION | EntityItem::DIRTY_VELOCITY | EntityItem::DIRTY_MASS | EntityItem::DIRTY_COLLISION_GROUP); @@ -42,6 +41,7 @@ const uint32_t OUTGOING_DIRTY_PHYSICS_FLAGS = EntityItem::DIRTY_POSITION | Entit #include "ShapeInfo.h" class OctreeEditPacketSender; +class KinematicController; class ObjectMotionState : public btMotionState { public: @@ -90,6 +90,9 @@ public: virtual MotionType computeMotionType() const = 0; + virtual void addKinematicController() = 0; + virtual void removeKinematicController(); + friend class PhysicsEngine; protected: float _density; @@ -114,6 +117,8 @@ protected: glm::vec3 _sentVelocity; glm::vec3 _sentAngularVelocity; // radians per second glm::vec3 _sentAcceleration; + + KinematicController* _kinematicController = NULL; }; #endif // USE_BULLET_PHYSICS diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 666fcd2e89..dd188ae93d 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -15,7 +15,12 @@ #include "ShapeInfoUtil.h" #include "ThreadSafeDynamicsWorld.h" -class EntityTree; +static uint32_t _frameCount; + +// static +uint32_t PhysicsEngine::getFrameCount() { + return _frameCount; +} PhysicsEngine::PhysicsEngine(const glm::vec3& offset) : _collisionConfig(NULL), @@ -24,8 +29,7 @@ PhysicsEngine::PhysicsEngine(const glm::vec3& offset) _constraintSolver(NULL), _dynamicsWorld(NULL), _originOffset(offset), - _entityPacketSender(NULL), - _frameCount(0) { + _entityPacketSender(NULL) { } PhysicsEngine::~PhysicsEngine() { @@ -196,8 +200,6 @@ void PhysicsEngine::init(EntityEditPacketSender* packetSender) { EntityMotionState::setOutgoingEntityList(&_entitiesToBeSorted); } -const float FIXED_SUBSTEP = 1.0f / 60.0f; - void PhysicsEngine::stepSimulation() { lock(); // NOTE: the grand order of operations is: @@ -210,13 +212,13 @@ void PhysicsEngine::stepSimulation() { relayIncomingChangesToSimulation(); const int MAX_NUM_SUBSTEPS = 4; - const float MAX_TIMESTEP = (float)MAX_NUM_SUBSTEPS * FIXED_SUBSTEP; + const float MAX_TIMESTEP = (float)MAX_NUM_SUBSTEPS * PHYSICS_ENGINE_FIXED_SUBSTEP; float dt = 1.0e-6f * (float)(_clock.getTimeMicroseconds()); _clock.reset(); float timeStep = btMin(dt, MAX_TIMESTEP); // This is step (2). - int numSubSteps = _dynamicsWorld->stepSimulation(timeStep, MAX_NUM_SUBSTEPS, FIXED_SUBSTEP); + int numSubSteps = _dynamicsWorld->stepSimulation(timeStep, MAX_NUM_SUBSTEPS, PHYSICS_ENGINE_FIXED_SUBSTEP); _frameCount += (uint32_t)numSubSteps; unlock(); @@ -257,9 +259,12 @@ bool PhysicsEngine::addObject(ObjectMotionState* motionState) { case MOTION_TYPE_KINEMATIC: { body = new btRigidBody(mass, motionState, shape, inertia); body->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT); - body->setActivationState(DISABLE_DEACTIVATION); body->updateInertiaTensor(); motionState->_body = body; + motionState->addKinematicController(); + const float KINEMATIC_LINEAR_VELOCITY_THRESHOLD = 0.01f; // 1 cm/sec + const float KINEMATIC_ANGULAR_VELOCITY_THRESHOLD = 0.01f; // ~1 deg/sec + body->setSleepingThresholds(KINEMATIC_LINEAR_VELOCITY_THRESHOLD, KINEMATIC_ANGULAR_VELOCITY_THRESHOLD); break; } case MOTION_TYPE_DYNAMIC: { @@ -271,9 +276,9 @@ bool PhysicsEngine::addObject(ObjectMotionState* motionState) { motionState->updateObjectVelocities(); // NOTE: Bullet will deactivate any object whose velocity is below these thresholds for longer than 2 seconds. // (the 2 seconds is determined by: static btRigidBody::gDeactivationTime - const float LINEAR_VELOCITY_THRESHOLD = 0.05f; // 5 cm/sec - const float ANGULAR_VELOCITY_THRESHOLD = 0.087266f; // ~5 deg/sec - body->setSleepingThresholds(LINEAR_VELOCITY_THRESHOLD, ANGULAR_VELOCITY_THRESHOLD); + const float DYNAMIC_LINEAR_VELOCITY_THRESHOLD = 0.05f; // 5 cm/sec + const float DYNAMIC_ANGULAR_VELOCITY_THRESHOLD = 0.087266f; // ~5 deg/sec + body->setSleepingThresholds(DYNAMIC_LINEAR_VELOCITY_THRESHOLD, DYNAMIC_ANGULAR_VELOCITY_THRESHOLD); break; } case MOTION_TYPE_STATIC: @@ -307,6 +312,7 @@ bool PhysicsEngine::removeObject(ObjectMotionState* motionState) { _shapeManager.releaseShape(info); delete body; motionState->_body = NULL; + motionState->removeKinematicController(); return true; } return false; @@ -350,6 +356,7 @@ void PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motio body->setMassProps(0.0f, btVector3(0.0f, 0.0f, 0.0f)); body->updateInertiaTensor(); + motionState->addKinematicController(); break; } case MOTION_TYPE_DYNAMIC: { @@ -364,6 +371,7 @@ void PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motio body->updateInertiaTensor(); } body->forceActivationState(ACTIVE_TAG); + motionState->removeKinematicController(); break; } default: { @@ -378,6 +386,7 @@ void PhysicsEngine::updateObjectHard(btRigidBody* body, ObjectMotionState* motio body->setLinearVelocity(btVector3(0.0f, 0.0f, 0.0f)); body->setAngularVelocity(btVector3(0.0f, 0.0f, 0.0f)); + motionState->removeKinematicController(); break; } } diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index c6d6bd4626..fd81e12eb8 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -12,10 +12,9 @@ #ifndef hifi_PhysicsEngine_h #define hifi_PhysicsEngine_h -typedef unsigned int uint32_t; - #ifdef USE_BULLET_PHYSICS +#include #include #include @@ -28,9 +27,13 @@ typedef unsigned int uint32_t; #include "ThreadSafeDynamicsWorld.h" const float HALF_SIMULATION_EXTENT = 512.0f; // meters +const float PHYSICS_ENGINE_FIXED_SUBSTEP = 1.0f / 60.0f; + +class ObjectMotionState; class PhysicsEngine : public EntitySimulation { public: + static uint32_t getFrameCount(); PhysicsEngine(const glm::vec3& offset); @@ -68,9 +71,6 @@ public: /// \return duration of fixed simulation substep float getFixedSubStep() const; - /// \return number of simulation frames the physics engine has taken - uint32_t getFrameCount() const { return _frameCount; } - protected: void updateObjectHard(btRigidBody* body, ObjectMotionState* motionState, uint32_t flags); void updateObjectEasy(btRigidBody* body, ObjectMotionState* motionState, uint32_t flags); @@ -92,8 +92,6 @@ private: QSet _outgoingPackets; // MotionStates with pending changes that need to be sent over wire EntityEditPacketSender* _entityPacketSender; - - uint32_t _frameCount; }; #else // USE_BULLET_PHYSICS diff --git a/libraries/physics/src/PhysicsEntity.h b/libraries/physics/src/PhysicsEntity.h index 92b302debb..358c058551 100644 --- a/libraries/physics/src/PhysicsEntity.h +++ b/libraries/physics/src/PhysicsEntity.h @@ -21,10 +21,6 @@ #include #include -#ifdef USE_BULLET_PHYSICS -#include "PhysicsEngine.h" -#endif // USE_BULLET_PHYSICS - class Shape; class PhysicsSimulation; diff --git a/libraries/physics/src/SimpleEntityKinematicController.cpp b/libraries/physics/src/SimpleEntityKinematicController.cpp new file mode 100644 index 0000000000..478ec1d12f --- /dev/null +++ b/libraries/physics/src/SimpleEntityKinematicController.cpp @@ -0,0 +1,21 @@ +// +// SimpleEntityKinematicController.cpp +// libraries/physcis/src +// +// Created by Andrew Meadows 2015.01.13 +// 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 "PhysicsEngine.h" +#include "SimpleEntityKinematicController.h" + +void SimpleEntityKinematicController:: stepForward() { + uint32_t frame = PhysicsEngine::getFrameCount(); + float dt = (frame - _lastFrame) * PHYSICS_ENGINE_FIXED_SUBSTEP; + _entity->simulateSimpleKinematicMotion(dt); + _lastFrame = frame; +} + diff --git a/libraries/physics/src/SimpleEntityKinematicController.h b/libraries/physics/src/SimpleEntityKinematicController.h new file mode 100644 index 0000000000..78c8569a0f --- /dev/null +++ b/libraries/physics/src/SimpleEntityKinematicController.h @@ -0,0 +1,36 @@ +// +// SimpleEntityKinematicController.h +// libraries/physcis/src +// +// Created by Andrew Meadows 2015.01.13 +// 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_SimpleEntityKinematicController_h +#define hifi_SimpleEntityKinematicController_h + +/// SimpleKinematicConstroller performs simple exrapolation of velocities. + +#include +#include + +#include "KinematicController.h" + +class SimpleEntityKinematicController : public KinematicController { +public: + SimpleEntityKinematicController() = delete; // prevent compiler from making a default ctor + + SimpleEntityKinematicController(EntityItem* entity) : KinematicController(), _entity(entity) { assert(entity); } + + ~SimpleEntityKinematicController() { _entity = NULL; } + + void stepForward(); + +private: + EntityItem* _entity; +}; + +#endif // hifi_SimpleEntityKinematicController_h From 4c1cd991f43896322ffd22759751f7217cbe8230 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 15 Jan 2015 17:53:37 -0800 Subject: [PATCH 73/93] remove pessimistic send of object updates we have not yet seen the headache of packetloss and unreliable messages --- libraries/physics/src/ObjectMotionState.cpp | 23 ++++++++------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/libraries/physics/src/ObjectMotionState.cpp b/libraries/physics/src/ObjectMotionState.cpp index c5bbb0e899..ff78306141 100644 --- a/libraries/physics/src/ObjectMotionState.cpp +++ b/libraries/physics/src/ObjectMotionState.cpp @@ -133,22 +133,17 @@ bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame) { _sentFrame = simulationFrame; bool isActive = _body->isActive(); - if (isActive) { - const float MAX_UPDATE_PERIOD_FOR_ACTIVE_THINGS = 10.0f; - if (dt > MAX_UPDATE_PERIOD_FOR_ACTIVE_THINGS) { - return true; - } - } else if (_sentMoving) { - if (!isActive) { + if (!isActive) { + if (_sentMoving) { // this object just went inactive so send an update immediately return true; - } - } else { - const float NON_MOVING_UPDATE_PERIOD = 1.0f; - if (dt > NON_MOVING_UPDATE_PERIOD && _numNonMovingUpdates < MAX_NUM_NON_MOVING_UPDATES) { - // RELIABLE_SEND_HACK: since we're not yet using a reliable method for non-moving update packets we repeat these - // at a faster rate than the MAX period above, and only send a limited number of them. - return true; + } else { + const float NON_MOVING_UPDATE_PERIOD = 1.0f; + if (dt > NON_MOVING_UPDATE_PERIOD && _numNonMovingUpdates < MAX_NUM_NON_MOVING_UPDATES) { + // RELIABLE_SEND_HACK: since we're not yet using a reliable method for non-moving update packets we repeat these + // at a faster rate than the MAX period above, and only send a limited number of them. + return true; + } } } From ba31309206eef8560e4414c64e13d98f1c6f8f35 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 16 Jan 2015 08:57:35 -0800 Subject: [PATCH 74/93] also find debug Bullet libs --- cmake/modules/FindBullet.cmake | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmake/modules/FindBullet.cmake b/cmake/modules/FindBullet.cmake index 3487abb233..9401a799e1 100644 --- a/cmake/modules/FindBullet.cmake +++ b/cmake/modules/FindBullet.cmake @@ -66,13 +66,13 @@ find_path(BULLET_INCLUDE_DIR NAMES btBulletCollisionCommon.h # Find the libraries _FIND_BULLET_LIBRARY(BULLET_DYNAMICS_LIBRARY BulletDynamics) -#_FIND_BULLET_LIBRARY(BULLET_DYNAMICS_LIBRARY_DEBUG BulletDynamics_Debug BulletDynamics_d) +_FIND_BULLET_LIBRARY(BULLET_DYNAMICS_LIBRARY_DEBUG BulletDynamics_Debug BulletDynamics_d) _FIND_BULLET_LIBRARY(BULLET_COLLISION_LIBRARY BulletCollision) -#_FIND_BULLET_LIBRARY(BULLET_COLLISION_LIBRARY_DEBUG BulletCollision_Debug BulletCollision_d) +_FIND_BULLET_LIBRARY(BULLET_COLLISION_LIBRARY_DEBUG BulletCollision_Debug BulletCollision_d) _FIND_BULLET_LIBRARY(BULLET_MATH_LIBRARY BulletMath LinearMath) -#_FIND_BULLET_LIBRARY(BULLET_MATH_LIBRARY_DEBUG BulletMath_Debug BulletMath_d LinearMath_Debug LinearMath_d) +_FIND_BULLET_LIBRARY(BULLET_MATH_LIBRARY_DEBUG BulletMath_Debug BulletMath_d LinearMath_Debug LinearMath_d) _FIND_BULLET_LIBRARY(BULLET_SOFTBODY_LIBRARY BulletSoftBody) -#_FIND_BULLET_LIBRARY(BULLET_SOFTBODY_LIBRARY_DEBUG BulletSoftBody_Debug BulletSoftBody_d) +_FIND_BULLET_LIBRARY(BULLET_SOFTBODY_LIBRARY_DEBUG BulletSoftBody_Debug BulletSoftBody_d) find_package_handle_standard_args(Bullet "Could NOT find Bullet, try to set the path to Bullet root folder in the system variable BULLET_ROOT_DIR" From 4392af3b3a8018ea7c5a89feaa2a1cb49e46e07c Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 16 Jan 2015 09:26:43 -0800 Subject: [PATCH 75/93] Remove pre-Bullet server-side EntityItem motion --- libraries/entities/src/EntityItem.cpp | 32 ++------------------------- 1 file changed, 2 insertions(+), 30 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 9cfb0c6c11..69cd16469e 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -691,15 +691,7 @@ void EntityItem::simulate(const quint64& now) { } } -#ifdef USE_BULLET_PHYSICS - // When Bullet is available we assume that "zero velocity" means "at rest" - // because of collision conditions this simulation does not know about - // so we don't fall in for the non-zero gravity case here. if (hasVelocity()) { -#else // !USE_BULLET_PHYSICS - if (hasVelocity() || hasGravity()) { -#endif // USE_BULLET_PHYSICS - // linear damping glm::vec3 velocity = getVelocity(); if (_damping > 0.0f) { @@ -733,14 +725,6 @@ void EntityItem::simulate(const quint64& now) { // handle bounces off the ground... We bounce at the distance to the bottom of our entity if (position.y <= getDistanceToBottomOfEntity()) { velocity = velocity * glm::vec3(1,-1,1); - -#ifndef USE_BULLET_PHYSICS - // if we've slowed considerably, then just stop moving, but only if no BULLET - if (glm::length(velocity) <= ENTITY_ITEM_EPSILON_VELOCITY_LENGTH) { - velocity = ENTITY_ITEM_ZERO_VEC3; - } -#endif // !USE_BULLET_PHYSICS - position.y = getDistanceToBottomOfEntity(); } @@ -756,14 +740,8 @@ void EntityItem::simulate(const quint64& now) { } } -#ifdef USE_BULLET_PHYSICS - // When Bullet is available we assume that it will tell us when velocities go to zero... -#else // !USE_BULLET_PHYSICS - // ... otherwise we help things come to rest by clamping small velocities. - if (glm::length(velocity) <= ENTITY_ITEM_EPSILON_VELOCITY_LENGTH) { - velocity = ENTITY_ITEM_ZERO_VEC3; - } -#endif // USE_BULLET_PHYSICS + // NOTE: we don't zero out very small velocities --> we rely on a remote Bullet simulation + // to tell us when the entity has stopped. // NOTE: the simulation should NOT set any DirtyFlags on this entity setPosition(position); // this will automatically recalculate our collision shape @@ -781,13 +759,7 @@ void EntityItem::simulate(const quint64& now) { } bool EntityItem::isMoving() const { -#ifdef USE_BULLET_PHYSICS - // When Bullet is available we assume that "zero velocity" means "at rest" - // because of collision conditions this simulation does not know about. return hasVelocity() || hasAngularVelocity(); -#else // !USE_BULLET_PHYSICS - return hasVelocity() || (hasGravity() && !isRestingOnSurface()) || hasAngularVelocity(); -#endif //USE_BULLET_PHYSICS } bool EntityItem::lifetimeHasExpired() const { From d1fb071208202dc2517e5c7a28017978c2aed936 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 16 Jan 2015 09:38:53 -0800 Subject: [PATCH 76/93] Adding ambient sphere in the lighting equation and menu to control te presets --- interface/src/Application.cpp | 32 +++- interface/src/Application.h | 1 + interface/src/Menu.cpp | 15 ++ interface/src/Menu.h | 12 ++ .../render-utils/src/DeferredLighting.slh | 57 +++--- .../src/DeferredLightingEffect.cpp | 178 +++++++++++++++++- .../render-utils/src/DeferredLightingEffect.h | 11 +- .../src/directional_ambient_light.slf | 42 +++++ ...onal_ambient_light_cascaded_shadow_map.slf | 49 +++++ .../directional_ambient_light_shadow_map.slf | 50 +++++ .../render-utils/src/directional_light.slf | 42 ++--- .../directional_light_cascaded_shadow_map.slf | 54 ++---- .../src/directional_light_shadow_map.slf | 107 ++--------- 13 files changed, 469 insertions(+), 181 deletions(-) create mode 100755 libraries/render-utils/src/directional_ambient_light.slf create mode 100755 libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf create mode 100755 libraries/render-utils/src/directional_ambient_light_shadow_map.slf diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index dbc409bac2..ff6c87123f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2797,7 +2797,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs } glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); - + DependencyManager::get()->prepare(); if (!selfAvatarOnly) { @@ -2848,6 +2848,8 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs { + DependencyManager::get()->setAmbientLightMode(getRenderAmbientLight()); + PROFILE_RANGE("DeferredLighting"); PerformanceTimer perfTimer("lighting"); DependencyManager::get()->render(); @@ -3973,3 +3975,31 @@ float Application::getRenderResolutionScale() const { return 1.0f; } } + +int Application::getRenderAmbientLight() const { + if (Menu::getInstance()->isOptionChecked(MenuOption::RenderAmbientLightGlobal)) { + return -1; + } else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderAmbientLight0)) { + return 0; + } else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderAmbientLight1)) { + return 1; + } else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderAmbientLight2)) { + return 2; + } else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderAmbientLight3)) { + return 3; + } else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderAmbientLight4)) { + return 4; + } else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderAmbientLight5)) { + return 5; + } else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderAmbientLight6)) { + return 6; + } else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderAmbientLight7)) { + return 7; + } else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderAmbientLight8)) { + return 8; + } else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderAmbientLight9)) { + return 9; + } else { + return -1; + } +} diff --git a/interface/src/Application.h b/interface/src/Application.h index a66a30abce..b87a4435b9 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -287,6 +287,7 @@ public: bool isLookingAtMyAvatar(Avatar* avatar); float getRenderResolutionScale() const; + int getRenderAmbientLight() const; unsigned int getRenderTargetFramerate() const; bool isVSyncOn() const; diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index c96ca9bb6f..38c7ab843f 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -343,6 +343,21 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::AmbientOcclusion); addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::DontFadeOnOctreeServerChanges); addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::DisableAutoAdjustLOD); + + QMenu* ambientLightMenu = renderOptionsMenu->addMenu(MenuOption::RenderAmbientLight); + QActionGroup* ambientLightGroup = new QActionGroup(ambientLightMenu); + ambientLightGroup->setExclusive(true); + ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLightGlobal, 0, true)); + ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight0, 0, false)); + ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight1, 0, false)); + ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight2, 0, false)); + ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight3, 0, false)); + ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight4, 0, false)); + ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight5, 0, false)); + ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight6, 0, false)); + ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight7, 0, false)); + ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight8, 0, false)); + ambientLightGroup->addAction(addCheckableActionToQMenuAndActionHash(ambientLightMenu, MenuOption::RenderAmbientLight9, 0, false)); QMenu* shadowMenu = renderOptionsMenu->addMenu("Shadows"); QActionGroup* shadowGroup = new QActionGroup(shadowMenu); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 52fb17a10d..b2854f8131 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -440,6 +440,18 @@ namespace MenuOption { const QString RenderResolutionHalf = "1/2"; const QString RenderResolutionThird = "1/3"; const QString RenderResolutionQuarter = "1/4"; + const QString RenderAmbientLight = "Ambient Light"; + const QString RenderAmbientLightGlobal = "Global"; + const QString RenderAmbientLight0 = "OLD_TOWN_SQUARE"; + const QString RenderAmbientLight1 = "GRACE_CATHEDRAL"; + const QString RenderAmbientLight2 = "EUCALYPTUS_GROVE"; + const QString RenderAmbientLight3 = "ST_PETERS_BASILICA"; + const QString RenderAmbientLight4 = "UFFIZI_GALLERY"; + const QString RenderAmbientLight5 = "GALILEOS_TOMB"; + const QString RenderAmbientLight6 = "VINE_STREET_KITCHEN"; + const QString RenderAmbientLight7 = "BREEZEWAY"; + const QString RenderAmbientLight8 = "CAMPUS_SUNSET"; + const QString RenderAmbientLight9 = "FUNSTON_BEACH_SUNSET"; const QString ResetAvatarSize = "Reset Avatar Size"; const QString ResetSensors = "Reset Sensors"; const QString RunningScripts = "Running Scripts"; diff --git a/libraries/render-utils/src/DeferredLighting.slh b/libraries/render-utils/src/DeferredLighting.slh index 71021255dc..42d25a3666 100755 --- a/libraries/render-utils/src/DeferredLighting.slh +++ b/libraries/render-utils/src/DeferredLighting.slh @@ -45,17 +45,20 @@ vec4 evalSphericalLight(SphericalHarmonics sh, vec3 direction ) { uniform SphericalHarmonics ambientSphere; -vec3 evalAmbientSphereAndDirectionalColor(vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { - // Ambient lighting - vec3 ambientLight = evalSphericalLight(ambientSphere, normal).xyz; - if (gl_FragCoord.x > 1024) { - ambientLight = gl_FrontLightProduct[0].ambient.rgb; - } - vec3 ambientColor = diffuseVal.rgb * ambientLight; +vec3 evalAmbientColor(vec3 normal, vec3 diffuse, vec3 specular, float gloss) { + return diffuse.rgb * gl_FrontLightProduct[0].ambient.rgb; +} +vec3 evalAmbientSphereColor(vec3 normal, vec3 diffuse, vec3 specular, float gloss) { + vec3 ambientLight = 0.5 * evalSphericalLight(ambientSphere, normal).xyz; + + return diffuse.rgb * ambientLight; +} + +vec3 evalDirectionalColor(float shadowAttenuation, vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { // Diffuse Lighting - float diffuseDot = dot(frag.normal, gl_LightSource[0].position.xyz); - float facingLight = step(0.0, diffuseDot); + float diffuseDot = dot(normal, gl_LightSource[0].position.xyz); + float facingLight = step(0.0, diffuseDot) * shadowAttenuation; vec3 diffuseColor = diffuse * (gl_FrontLightModelProduct.sceneColor.rgb + gl_FrontLightProduct[0].diffuse.rgb * (diffuseDot * facingLight)); // compute the specular multiplier (sans exponent) @@ -64,26 +67,30 @@ vec3 evalAmbientSphereAndDirectionalColor(vec3 position, vec3 normal, vec3 diffu vec3 specularColor = pow(specularPower, gloss * 128.0) * specular; // add specular contribution - return vec3(ambientColor + diffuseColor + specularColor); + return vec3(diffuseColor + specularColor); } -vec3 evalAmbientAndDirectionalColor(vec3 position, vec3 normal, vec3 diffuse, vec3 specular, float gloss) { - // Ambient lighting - vec3 ambientLight = gl_FrontLightProduct[0].ambient.rgb; - vec3 ambientColor = diffuseVal.rgb * ambientLight; - - // Diffuse - float diffuseDot = dot(frag.normal, gl_LightSource[0].position.xyz); - float facingLight = step(0.0, diffuseDot); - vec3 diffuseColor = diffuse * (gl_FrontLightModelProduct.sceneColor.rgb + gl_FrontLightProduct[0].diffuse.rgb * (diffuseDot * facingLight)); +vec3 evalLightmappedColor(float shadowAttenuation, vec3 normal, vec3 diffuse, vec3 lightmap) { + + float diffuseDot = dot(normal, gl_LightSource[0].position.xyz); + + // need to catch normals perpendicular to the projection plane hence the magic number for the threshold + // it should be just 0, but we have innacurracy so we need to overshoot + const float PERPENDICULAR_THRESHOLD = -0.005; + float facingLight = step(PERPENDICULAR_THRESHOLD, diffuseDot); - // compute the specular multiplier (sans exponent) - float specularPower = facingLight * max(0.0, - dot(normalize(gl_LightSource[0].position.xyz - normalize(position)), normal)); - vec3 specularColor = pow(specularPower, gloss * 128.0) * specular; + // evaluate the shadow test but only relevant for light facing fragments + float lightAttenuation = (1 - facingLight) + facingLight * shadowAttenuation; + + // diffuse light is the lightmap dimmed by shadow + vec3 diffuseLight = lightAttenuation * lightmap; - // add specular contribution - return vec3(ambientColor + diffuseColor + specularColor); + // ambient is a tiny percentage of the lightmap and only when in the shadow + vec3 ambientLight = (1 - lightAttenuation) * 0.5 * lightmap; + + return diffuse * (ambientLight + diffuseLight); } + + <@endif@> \ No newline at end of file diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 2d44e2c6bd..a7b8d068bb 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -35,9 +35,150 @@ #include "directional_light_shadow_map_frag.h" #include "directional_light_cascaded_shadow_map_frag.h" +#include "directional_ambient_light_frag.h" +#include "directional_ambient_light_shadow_map_frag.h" +#include "directional_ambient_light_cascaded_shadow_map_frag.h" + #include "point_light_frag.h" #include "spot_light_frag.h" +class SphericalHarmonics { +public: + glm::vec3 L00 ; float spare0; + glm::vec3 L1m1 ; float spare1; + glm::vec3 L10 ; float spare2; + glm::vec3 L11 ; float spare3; + glm::vec3 L2m2 ; float spare4; + glm::vec3 L2m1 ; float spare5; + glm::vec3 L20 ; float spare6; + glm::vec3 L21 ; float spare7; + glm::vec3 L22 ; float spare8; + + void assignPreset(int p) { + switch (p) { + case DeferredLightingEffect::OLD_TOWN_SQUARE: { + L00 = glm::vec3( 0.871297f, 0.875222f, 0.864470f); + L1m1 = glm::vec3( 0.175058f, 0.245335f, 0.312891f); + L10 = glm::vec3( 0.034675f, 0.036107f, 0.037362f); + L11 = glm::vec3(-0.004629f,-0.029448f,-0.048028f); + L2m2 = glm::vec3(-0.120535f,-0.121160f,-0.117507f); + L2m1 = glm::vec3( 0.003242f, 0.003624f, 0.007511f); + L20 = glm::vec3(-0.028667f,-0.024926f,-0.020998f); + L21 = glm::vec3(-0.077539f,-0.086325f,-0.091591f); + L22 = glm::vec3(-0.161784f,-0.191783f,-0.219152f); + } + break; + case DeferredLightingEffect::GRACE_CATHEDRAL: { + L00 = glm::vec3( 0.79f, 0.44f, 0.54f); + L1m1 = glm::vec3( 0.39f, 0.35f, 0.60f); + L10 = glm::vec3(-0.34f, -0.18f, -0.27f); + L11 = glm::vec3(-0.29f, -0.06f, 0.01f); + L2m2 = glm::vec3(-0.11f, -0.05f, -0.12f); + L2m1 = glm::vec3(-0.26f, -0.22f, -0.47f); + L20 = glm::vec3(-0.16f, -0.09f, -0.15f); + L21 = glm::vec3( 0.56f, 0.21f, 0.14f); + L22 = glm::vec3( 0.21f, -0.05f, -0.30f); + } + break; + case DeferredLightingEffect::EUCALYPTUS_GROVE: { + L00 = glm::vec3( 0.38f, 0.43f, 0.45f); + L1m1 = glm::vec3( 0.29f, 0.36f, 0.41f); + L10 = glm::vec3( 0.04f, 0.03f, 0.01f); + L11 = glm::vec3(-0.10f, -0.10f, -0.09f); + L2m2 = glm::vec3(-0.06f, -0.06f, -0.04f); + L2m1 = glm::vec3( 0.01f, -0.01f, -0.05f); + L20 = glm::vec3(-0.09f, -0.13f, -0.15f); + L21 = glm::vec3(-0.06f, -0.05f, -0.04f); + L22 = glm::vec3( 0.02f, 0.00f, -0.05f); + } + break; + case DeferredLightingEffect::ST_PETERS_BASILICA: { + L00 = glm::vec3( 0.36f, 0.26f, 0.23f); + L1m1 = glm::vec3( 0.18f, 0.14f, 0.13f); + L10 = glm::vec3(-0.02f, -0.01f, 0.00f); + L11 = glm::vec3( 0.03f, 0.02f, -0.00f); + L2m2 = glm::vec3( 0.02f, 0.01f, -0.00f); + L2m1 = glm::vec3(-0.05f, -0.03f, -0.01f); + L20 = glm::vec3(-0.09f, -0.08f, -0.07f); + L21 = glm::vec3( 0.01f, 0.00f, 0.00f); + L22 = glm::vec3(-0.08f, -0.03f, -0.00f); + } + break; + case DeferredLightingEffect::UFFIZI_GALLERY: { + L00 = glm::vec3( 0.32f, 0.31f, 0.35f); + L1m1 = glm::vec3( 0.37f, 0.37f, 0.43f); + L10 = glm::vec3( 0.00f, 0.00f, 0.00f); + L11 = glm::vec3(-0.01f, -0.01f, -0.01f); + L2m2 = glm::vec3(-0.02f, -0.02f, -0.03f); + L2m1 = glm::vec3(-0.01f, -0.01f, -0.01f); + L20 = glm::vec3(-0.28f, -0.28f, -0.32f); + L21 = glm::vec3( 0.00f, 0.00f, 0.00f); + L22 = glm::vec3(-0.24f, -0.24f, -0.28f); + } + break; + case DeferredLightingEffect::GALILEOS_TOMB: { + L00 = glm::vec3( 1.04f, 0.76f, 0.71f); + L1m1 = glm::vec3( 0.44f, 0.34f, 0.34f); + L10 = glm::vec3(-0.22f, -0.18f, -0.17f); + L11 = glm::vec3( 0.71f, 0.54f, 0.56f); + L2m2 = glm::vec3( 0.64f, 0.50f, 0.52f); + L2m1 = glm::vec3(-0.12f, -0.09f, -0.08f); + L20 = glm::vec3(-0.37f, -0.28f, -0.32f); + L21 = glm::vec3(-0.17f, -0.13f, -0.13f); + L22 = glm::vec3( 0.55f, 0.42f, 0.42f); + } + break; + case DeferredLightingEffect::VINE_STREET_KITCHEN: { + L00 = glm::vec3( 0.64f, 0.67f, 0.73f); + L1m1 = glm::vec3( 0.28f, 0.32f, 0.33f); + L10 = glm::vec3( 0.42f, 0.60f, 0.77f); + L11 = glm::vec3(-0.05f, -0.04f, -0.02f); + L2m2 = glm::vec3(-0.10f, -0.08f, -0.05f); + L2m1 = glm::vec3( 0.25f, 0.39f, 0.53f); + L20 = glm::vec3( 0.38f, 0.54f, 0.71f); + L21 = glm::vec3( 0.06f, 0.01f, -0.02f); + L22 = glm::vec3(-0.03f, -0.02f, -0.03f); + } + break; + case DeferredLightingEffect::BREEZEWAY: { + L00 = glm::vec3( 0.32f, 0.36f, 0.38f); + L1m1 = glm::vec3( 0.37f, 0.41f, 0.45f); + L10 = glm::vec3(-0.01f, -0.01f, -0.01f); + L11 = glm::vec3(-0.10f, -0.12f, -0.12f); + L2m2 = glm::vec3(-0.13f, -0.15f, -0.17f); + L2m1 = glm::vec3(-0.01f, -0.02f, 0.02f); + L20 = glm::vec3(-0.07f, -0.08f, -0.09f); + L21 = glm::vec3( 0.02f, 0.03f, 0.03f); + L22 = glm::vec3(-0.29f, -0.32f, -0.36f); + } + break; + case DeferredLightingEffect::CAMPUS_SUNSET: { + L00 = glm::vec3( 0.79f, 0.94f, 0.98f); + L1m1 = glm::vec3( 0.44f, 0.56f, 0.70f); + L10 = glm::vec3(-0.10f, -0.18f, -0.27f); + L11 = glm::vec3( 0.45f, 0.38f, 0.20f); + L2m2 = glm::vec3( 0.18f, 0.14f, 0.05f); + L2m1 = glm::vec3(-0.14f, -0.22f, -0.31f); + L20 = glm::vec3(-0.39f, -0.40f, -0.36f); + L21 = glm::vec3( 0.09f, 0.07f, 0.04f); + L22 = glm::vec3( 0.67f, 0.67f, 0.52f); + } + break; + case DeferredLightingEffect::FUNSTON_BEACH_SUNSET: { + L00 = glm::vec3( 0.68f, 0.69f, 0.70f); + L1m1 = glm::vec3( 0.32f, 0.37f, 0.44f); + L10 = glm::vec3(-0.17f, -0.17f, -0.17f); + L11 = glm::vec3(-0.45f, -0.42f, -0.34f); + L2m2 = glm::vec3(-0.17f, -0.17f, -0.15f); + L2m1 = glm::vec3(-0.08f, -0.09f, -0.10f); + L20 = glm::vec3(-0.03f, -0.02f, -0.01f); + L21 = glm::vec3( 0.16f, 0.14f, 0.10f); + L22 = glm::vec3( 0.37f, 0.31f, 0.20f); + } + break; + } + } +}; void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) { _viewState = viewState; @@ -54,6 +195,13 @@ void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) { _directionalLightShadowMapLocations); loadLightProgram(directional_light_cascaded_shadow_map_frag, false, _directionalLightCascadedShadowMap, _directionalLightCascadedShadowMapLocations); + + loadLightProgram(directional_ambient_light_frag, false, _directionalAmbientSphereLight, _directionalAmbientSphereLightLocations); + loadLightProgram(directional_ambient_light_shadow_map_frag, false, _directionalAmbientSphereLightShadowMap, + _directionalAmbientSphereLightShadowMapLocations); + loadLightProgram(directional_ambient_light_cascaded_shadow_map_frag, false, _directionalAmbientSphereLightCascadedShadowMap, + _directionalAmbientSphereLightCascadedShadowMapLocations); + loadLightProgram(point_light_frag, true, _pointLight, _pointLightLocations); loadLightProgram(spot_light_frag, true, _spotLight, _spotLightLocations); } @@ -206,18 +354,43 @@ void DeferredLightingEffect::render() { if (_viewState->getCascadeShadowsEnabled()) { program = &_directionalLightCascadedShadowMap; locations = &_directionalLightCascadedShadowMapLocations; - _directionalLightCascadedShadowMap.bind(); - _directionalLightCascadedShadowMap.setUniform(locations->shadowDistances, _viewState->getShadowDistances()); + if (_ambientLightMode > -1) { + program = &_directionalAmbientSphereLightCascadedShadowMap; + locations = &_directionalAmbientSphereLightCascadedShadowMapLocations; + } + program->bind(); + program->setUniform(locations->shadowDistances, _viewState->getShadowDistances()); } else { + if (_ambientLightMode > -1) { + program = &_directionalAmbientSphereLightShadowMap; + locations = &_directionalAmbientSphereLightShadowMapLocations; + } program->bind(); } program->setUniformValue(locations->shadowScale, 1.0f / textureCache->getShadowFramebufferObject()->width()); } else { + if (_ambientLightMode > -1) { + program = &_directionalAmbientSphereLight; + locations = &_directionalAmbientSphereLightLocations; + } program->bind(); } + + if (locations->ambientSphere >= 0) { + SphericalHarmonics sh; + if (_ambientLightMode < NUM_PRESET) { + sh.assignPreset(_ambientLightMode); + } else { + sh.assignPreset(0); + } + + for (int i =0; i <9; i++) { + program->setUniformValue(locations->ambientSphere + i, *(((QVector4D*) &sh) + i)); + } + } float left, right, bottom, top, nearVal, farVal; glm::vec4 nearClipPlane, farClipPlane; @@ -433,6 +606,7 @@ void DeferredLightingEffect::loadLightProgram(const char* fragSource, bool limit locations.depthTexCoordOffset = program.uniformLocation("depthTexCoordOffset"); locations.depthTexCoordScale = program.uniformLocation("depthTexCoordScale"); locations.radius = program.uniformLocation("radius"); + locations.ambientSphere = program.uniformLocation("ambientSphere.L00"); program.release(); } diff --git a/libraries/render-utils/src/DeferredLightingEffect.h b/libraries/render-utils/src/DeferredLightingEffect.h index 2c5087c5cb..cd8585eade 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.h +++ b/libraries/render-utils/src/DeferredLightingEffect.h @@ -101,6 +101,7 @@ private: int depthTexCoordOffset; int depthTexCoordScale; int radius; + int ambientSphere; }; static void loadLightProgram(const char* fragSource, bool limited, ProgramObject& program, LightLocations& locations); @@ -108,12 +109,20 @@ private: ProgramObject _simpleProgram; int _glowIntensityLocation; + ProgramObject _directionalAmbientSphereLight; + LightLocations _directionalAmbientSphereLightLocations; + ProgramObject _directionalAmbientSphereLightShadowMap; + LightLocations _directionalAmbientSphereLightShadowMapLocations; + ProgramObject _directionalAmbientSphereLightCascadedShadowMap; + LightLocations _directionalAmbientSphereLightCascadedShadowMapLocations; + ProgramObject _directionalLight; LightLocations _directionalLightLocations; ProgramObject _directionalLightShadowMap; LightLocations _directionalLightShadowMapLocations; ProgramObject _directionalLightCascadedShadowMap; LightLocations _directionalLightCascadedShadowMapLocations; + ProgramObject _pointLight; LightLocations _pointLightLocations; ProgramObject _spotLight; @@ -144,7 +153,7 @@ private: AbstractViewStateInterface* _viewState; - int _ambientLightMode = -1; + int _ambientLightMode = 0; }; /// Simple interface for objects that require something to be rendered after deferred lighting. diff --git a/libraries/render-utils/src/directional_ambient_light.slf b/libraries/render-utils/src/directional_ambient_light.slf new file mode 100755 index 0000000000..803bd5ac30 --- /dev/null +++ b/libraries/render-utils/src/directional_ambient_light.slf @@ -0,0 +1,42 @@ +<@include Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// directional_light.frag +// fragment shader +// +// Created by Andrzej Kapolka on 9/3/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +// Everything about deferred buffer +<@include DeferredBuffer.slh@> + +<@include DeferredLighting.slh@> + +void main(void) { + DeferredFragment frag = unpackDeferredFragment(gl_TexCoord[0].st); + + // Light mapped or not ? + if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { + gl_FragColor = vec4( evalLightmappedColor( + 1.0, + frag.normal, + frag.diffuse, + frag.specularVal.xyz), + 1.0); + } else { + vec3 color = evalAmbientSphereColor(frag.normal, frag.diffuse, frag.specular, frag.gloss) + + evalDirectionalColor(1.0, + frag.position.xyz, + frag.normal, + frag.diffuse, + frag.specular, + frag.gloss); + + gl_FragColor = vec4(color, frag.normalVal.a); + } +} diff --git a/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf b/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf new file mode 100755 index 0000000000..5f88c558d3 --- /dev/null +++ b/libraries/render-utils/src/directional_ambient_light_cascaded_shadow_map.slf @@ -0,0 +1,49 @@ +<@include Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// directional_light.frag +// fragment shader +// +// Created by Andrzej Kapolka on 9/3/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +// Everything about deferred buffer +<@include DeferredBuffer.slh@> + +<@include DeferredLighting.slh@> + +// Everything about shadow +<@include Shadow.slh@> + +void main(void) { + DeferredFragment frag = unpackDeferredFragment(gl_TexCoord[0].st); + + // Eval shadow Texcoord and then Attenuation + vec4 shadowTexcoord = evalCascadedShadowTexcoord(frag.position); + float shadowAttenuation = evalShadowAttenuation(shadowTexcoord); + + // Light mapped or not ? + if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { + gl_FragColor = vec4(evalLightmappedColor( + shadowAttenuation, + frag.normal, + frag.diffuse, + frag.specularVal.xyz), + 1.0); + } else { + vec3 color = evalAmbientSphereColor(frag.normal, frag.diffuse, frag.specular, frag.gloss) + + evalDirectionalColor(shadowAttenuation, + frag.position.xyz, + frag.normal, + frag.diffuse, + frag.specular, + frag.gloss); + + gl_FragColor = vec4(color, frag.normalVal.a); + } +} diff --git a/libraries/render-utils/src/directional_ambient_light_shadow_map.slf b/libraries/render-utils/src/directional_ambient_light_shadow_map.slf new file mode 100755 index 0000000000..6c241853e3 --- /dev/null +++ b/libraries/render-utils/src/directional_ambient_light_shadow_map.slf @@ -0,0 +1,50 @@ +<@include Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// directional_light.frag +// fragment shader +// +// Created by Andrzej Kapolka on 9/3/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +// Everything about deferred buffer +<@include DeferredBuffer.slh@> + +<@include DeferredLighting.slh@> + +// Everything about shadow +<@include Shadow.slh@> + + +void main(void) { + DeferredFragment frag = unpackDeferredFragment(gl_TexCoord[0].st); + + // Eval shadow Texcoord and then Attenuation + vec4 shadowTexcoord = evalShadowTexcoord(frag.position); + float shadowAttenuation = evalShadowAttenuation(shadowTexcoord); + + // Light mapped or not ? + if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { + gl_FragColor = vec4(evalLightmappedColor( + shadowAttenuation, + frag.normal, + frag.diffuse, + frag.specularVal.xyz), + 1.0); + } else { + vec3 color = evalAmbientSphereColor(frag.normal, frag.diffuse, frag.specular, frag.gloss) + + evalDirectionalColor(shadowAttenuation, + frag.position.xyz, + frag.normal, + frag.diffuse, + frag.specular, + frag.gloss); + + gl_FragColor = vec4(color, frag.normalVal.a); + } +} diff --git a/libraries/render-utils/src/directional_light.slf b/libraries/render-utils/src/directional_light.slf index 733da47f8b..8ff6cd6c87 100644 --- a/libraries/render-utils/src/directional_light.slf +++ b/libraries/render-utils/src/directional_light.slf @@ -20,35 +20,23 @@ void main(void) { DeferredFragment frag = unpackDeferredFragment(gl_TexCoord[0].st); - vec4 normalVal = frag.normalVal; - vec4 diffuseVal = frag.diffuseVal; - vec4 specularVal = frag.specularVal; - // Light mapped or not ? - if ((normalVal.a >= 0.45) && (normalVal.a <= 0.55)) { - gl_FragColor = vec4(diffuseVal.rgb * specularVal.rgb, 1.0); + if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { + gl_FragColor = vec4( evalLightmappedColor( + 1.0, + frag.normal, + frag.diffuse, + frag.specularVal.xyz), + 1.0); } else { - glFragColor = vec4( evalAmbientAndDirectionalColor(frag.position.xyz, - frag.normal, - frag.diffuse, - frag.specular, - frag.gloss), - normalVal.a); + vec3 color = evalAmbientColor(frag.normal, frag.diffuse, frag.specular, frag.gloss) + + evalDirectionalColor(1.0, + frag.position.xyz, + frag.normal, + frag.diffuse, + frag.specular, + frag.gloss); -/* - // compute the base color based on OpenGL lighting model - float diffuse = dot(frag.normal, gl_LightSource[0].position.xyz); - float facingLight = step(0.0, diffuse); - vec3 baseColor = diffuseVal.rgb * (gl_FrontLightModelProduct.sceneColor.rgb + - gl_FrontLightProduct[0].ambient.rgb + gl_FrontLightProduct[0].diffuse.rgb * (diffuse * facingLight)); - - // compute the specular multiplier (sans exponent) - float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position.xyz - normalize(frag.position.xyz)), - frag.normal)); - - // add specular contribution - vec4 specularColor = specularVal; - gl_FragColor = vec4(baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb, normalVal.a); -*/ + gl_FragColor = vec4(color, frag.normalVal.a); } } diff --git a/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf b/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf index f7e21252fb..ccf8909b64 100644 --- a/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf +++ b/libraries/render-utils/src/directional_light_cascaded_shadow_map.slf @@ -15,55 +15,35 @@ // Everything about deferred buffer <@include DeferredBuffer.slh@> +<@include DeferredLighting.slh@> + // Everything about shadow <@include Shadow.slh@> void main(void) { DeferredFragment frag = unpackDeferredFragment(gl_TexCoord[0].st); - vec4 normalVal = frag.normalVal; - vec4 diffuseVal = frag.diffuseVal; - vec4 specularVal = frag.specularVal; // Eval shadow Texcoord and then Attenuation vec4 shadowTexcoord = evalCascadedShadowTexcoord(frag.position); float shadowAttenuation = evalShadowAttenuation(shadowTexcoord); - // how much this fragment faces the light direction - float diffuse = dot(frag.normal, gl_LightSource[0].position.xyz); - // Light mapped or not ? - if ((normalVal.a >= 0.45) && (normalVal.a <= 0.55)) { - normalVal.a = 1.0; - - // need to catch normals perpendicular to the projection plane hence the magic number for the threshold - // it should be just 0, but we have innacurracy so we need to overshoot - const float PERPENDICULAR_THRESHOLD = -0.005; - float facingLight = step(PERPENDICULAR_THRESHOLD, diffuse); - - // evaluate the shadow test but only relevant for light facing fragments - float lightAttenuation = (1 - facingLight) + facingLight * shadowAttenuation; - - // diffuse light is the lightmap dimmed by shadow - vec3 diffuseLight = lightAttenuation * specularVal.rgb; - // ambient is a tiny percentage of the lightmap and only when in the shadow - vec3 ambientLight = (1 - lightAttenuation) * 0.5 * specularVal.rgb; - - gl_FragColor = vec4(diffuseVal.rgb * (ambientLight + diffuseLight), 1.0); + if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { + gl_FragColor = vec4(evalLightmappedColor( + shadowAttenuation, + frag.normal, + frag.diffuse, + frag.specularVal.xyz), + 1.0); } else { + vec3 color = evalAmbientColor(frag.normal, frag.diffuse, frag.specular, frag.gloss) + + evalDirectionalColor(shadowAttenuation, + frag.position.xyz, + frag.normal, + frag.diffuse, + frag.specular, + frag.gloss); - // average values from the shadow map - float facingLight = step(0.0, diffuse) * shadowAttenuation; - - // compute the base color based on OpenGL lighting model - vec3 baseColor = diffuseVal.rgb * (gl_FrontLightModelProduct.sceneColor.rgb + - gl_FrontLightProduct[0].ambient.rgb + gl_FrontLightProduct[0].diffuse.rgb * (diffuse * facingLight)); - - // compute the specular multiplier (sans exponent) - float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position.xyz - normalize(frag.position.xyz)), - frag.normal)); - - // add specular contribution - vec4 specularColor = specularVal; - gl_FragColor = vec4(baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb, normalVal.a); + gl_FragColor = vec4(color, frag.normalVal.a); } } diff --git a/libraries/render-utils/src/directional_light_shadow_map.slf b/libraries/render-utils/src/directional_light_shadow_map.slf index 1edf85b370..13435e9101 100644 --- a/libraries/render-utils/src/directional_light_shadow_map.slf +++ b/libraries/render-utils/src/directional_light_shadow_map.slf @@ -15,105 +15,36 @@ // Everything about deferred buffer <@include DeferredBuffer.slh@> +<@include DeferredLighting.slh@> + // Everything about shadow -<@include Shadow.slh@> - - -struct SphericalHarmonics { - vec4 L00; - vec4 L1m1; - vec4 L10; - vec4 L11; - vec4 L2m2; - vec4 L2m1; - vec4 L20; - vec4 L21; - vec4 L22; -}; - -vec4 evalSphericalLight(SphericalHarmonics sh, vec3 direction ) { - - const float C1 = 0.429043; - const float C2 = 0.511664; - const float C3 = 0.743125; - const float C4 = 0.886227; - const float C5 = 0.247708; - - vec4 value = C1 * sh.L22 * (direction.x * direction.x - direction.y * direction.y) + - C3 * sh.L20 * direction.z * direction.z + - C4 * sh.L00 - C5 * sh.L20 + - 2.0 * C1 * ( sh.L2m2 * direction.x * direction.y + - sh.L21 * direction.x * direction.z + - sh.L2m1 * direction.y * direction.z ) + - 2.0 * C2 * ( sh.L11 * direction.x + - sh.L1m1 * direction.y + - sh.L10 * direction.z ) ; - return value; -} +<@include Shadow.slh@> void main(void) { DeferredFragment frag = unpackDeferredFragment(gl_TexCoord[0].st); - vec4 normalVal = frag.normalVal; - vec4 diffuseVal = frag.diffuseVal; - vec4 specularVal = frag.specularVal; // Eval shadow Texcoord and then Attenuation vec4 shadowTexcoord = evalShadowTexcoord(frag.position); float shadowAttenuation = evalShadowAttenuation(shadowTexcoord); - // how much this fragment faces the light direction - float diffuse = dot(frag.normal, gl_LightSource[0].position.xyz); - - SphericalHarmonics sh; - sh.L00 = vec4( 0.79, 0.44, 0.54, 1.0); - sh.L1m1 = vec4( 0.39, 0.35, 0.60, 1.0); - sh.L10 = vec4(-0.34, -0.18, -0.27, 1.0); - sh.L11 = vec4(-0.29, -0.06, 0.01, 1.0); - sh.L2m2 = vec4(-0.11, -0.05, -0.12, 1.0); - sh.L2m1 = vec4(-0.26, -0.22, -0.47, 1.0); - sh.L20 = vec4(-0.16, -0.09, -0.15, 1.0); - sh.L21 = vec4( 0.56, 0.21, 0.14, 1.0); - sh.L22 = vec4( 0.21, -0.05, -0.30, 1.0); - // Light mapped or not ? - if ((normalVal.a >= 0.45) && (normalVal.a <= 0.55)) { - normalVal.a = 0.0; + if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) { + gl_FragColor = vec4(evalLightmappedColor( + shadowAttenuation, + frag.normal, + frag.diffuse, + frag.specularVal.xyz), + 1.0); + } else { + vec3 color = evalAmbientColor(frag.normal, frag.diffuse, frag.specular, frag.gloss) + + evalDirectionalColor(shadowAttenuation, + frag.position.xyz, + frag.normal, + frag.diffuse, + frag.specular, + frag.gloss); - // need to catch normals perpendicular to the projection plane hence the magic number for the threshold - // it should be just 0, be we have innacurracy so we need to overshoot - const float PERPENDICULAR_THRESHOLD = -0.005; - float facingLight = step(PERPENDICULAR_THRESHOLD, diffuse); - - // evaluate the shadow test but only relevant for light facing fragments - float lightAttenuation = (1 - facingLight) + facingLight * shadowAttenuation; - - // diffuse light is the lightmap dimmed by shadow - vec3 diffuseLight = lightAttenuation * specularVal.rgb; - // ambient is a tiny percentage of the lightmap and only when in the shadow - vec3 ambientLight = (1 - lightAttenuation) * 0.5 * specularVal.rgb; - - gl_FragColor = vec4(diffuseVal.rgb * (ambientLight + diffuseLight), 1.0); - } else { - // average values from the shadow map - float facingLight = step(0.0, diffuse) * shadowAttenuation; - - vec4 ambienTerm = 0.5 * evalSphericalLight(sh, frag.normal); - - if (gl_FragCoord.x > 1024) { - ambienTerm = gl_FrontLightProduct[0].ambient.rgba; - } - - // compute the base color based on OpenGL lighting model - vec3 baseColor = diffuseVal.rgb * (gl_FrontLightModelProduct.sceneColor.rgb + - ambienTerm.rgb + gl_FrontLightProduct[0].diffuse.rgb * (diffuse * facingLight)); - - // compute the specular multiplier (sans exponent) - float specular = facingLight * max(0.0, dot(normalize(gl_LightSource[0].position.xyz - normalize(frag.position.xyz)), - frag.normal)); - - // add specular contribution - vec4 specularColor = specularVal; - gl_FragColor = vec4(baseColor.rgb + pow(specular, specularColor.a * 128.0) * specularColor.rgb, normalVal.a); + gl_FragColor = vec4(color, frag.normalVal.a); } } From 0e38ea88545b0dd41082daf1defdf964c4cb93a9 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 16 Jan 2015 09:41:43 -0800 Subject: [PATCH 77/93] Adding ambient sphere in the lighting equation and menu to control te presets --- libraries/render-utils/src/DeferredLighting.slh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/render-utils/src/DeferredLighting.slh b/libraries/render-utils/src/DeferredLighting.slh index 42d25a3666..5582ab8e77 100755 --- a/libraries/render-utils/src/DeferredLighting.slh +++ b/libraries/render-utils/src/DeferredLighting.slh @@ -93,4 +93,4 @@ vec3 evalLightmappedColor(float shadowAttenuation, vec3 normal, vec3 diffuse, ve } -<@endif@> \ No newline at end of file +<@endif@> From 8634d86167f0371dac0ce6e25a1871454372bd6c Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 16 Jan 2015 09:43:21 -0800 Subject: [PATCH 78/93] Adding ambient sphere in the lighting equation and menu to control te presets --- libraries/render-utils/src/DeferredLightingEffect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index a7b8d068bb..0bb3cd9220 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -614,4 +614,4 @@ void DeferredLightingEffect::setAmbientLightMode(int preset) { if ((preset >= -1) && (preset < NUM_PRESET)) { _ambientLightMode = preset; } -} \ No newline at end of file +} From 2427fa68cdea2d2d92fec3f035de052f6cc50188 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 16 Jan 2015 10:06:39 -0800 Subject: [PATCH 79/93] remove unnecessary Bullet #include --- libraries/physics/src/KinematicController.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/physics/src/KinematicController.h b/libraries/physics/src/KinematicController.h index c1240c29e4..382d4cbfd9 100644 --- a/libraries/physics/src/KinematicController.h +++ b/libraries/physics/src/KinematicController.h @@ -13,7 +13,6 @@ #define hifi_KinematicController_h #include -#include /// KinematicController defines an API for derived classes. From 6b55b4ff821a83473f666ec0a2716b624e64b7cf Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 16 Jan 2015 10:26:51 -0800 Subject: [PATCH 80/93] No more Magic numbers and fixing the code path for linux --- libraries/gpu/src/gpu/GLBackend.cpp | 5 ++++- libraries/render-utils/src/DeferredLightingEffect.cpp | 4 +++- libraries/render-utils/src/Model.cpp | 9 ++++++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index ed1b97a58f..a01b39c35f 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -498,9 +498,12 @@ void GLBackend::do_setUniformBuffer(Batch& batch, uint32 paramOffset) { // NOT working so we ll stick to the uniform float array until we move to core profile // GLuint bo = getBufferID(*uniformBuffer); //glUniformBufferEXT(_shader._program, slot, bo); -#else +#elif defined(Q_OS_WIN) GLuint bo = getBufferID(*uniformBuffer); glBindBufferRange(GL_UNIFORM_BUFFER, slot, bo, rangeStart, rangeSize); +#else + GLfloat* data = (GLfloat*) (uniformBuffer->getData() + rangeStart); + glUniform4fv(slot, rangeSize / sizeof(GLfloat[4]), data); #endif CHECK_GL_ERROR(); } diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index 0bb3cd9220..5cbdd04f64 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -54,6 +54,8 @@ public: glm::vec3 L21 ; float spare7; glm::vec3 L22 ; float spare8; + static const int NUM_COEFFICIENTS = 9; + void assignPreset(int p) { switch (p) { case DeferredLightingEffect::OLD_TOWN_SQUARE: { @@ -387,7 +389,7 @@ void DeferredLightingEffect::render() { sh.assignPreset(0); } - for (int i =0; i <9; i++) { + for (int i =0; i setUniformValue(locations->ambientSphere + i, *(((QVector4D*) &sh) + i)); } } diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 1bca37aa10..97e6124517 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -206,7 +206,7 @@ void Model::initProgram(ProgramObject& program, Model::Locations& locations, boo } else { locations.materialBufferUnit = -1; } -#else +#elif defined(Q_OS_WIN) loc = glGetUniformBlockIndex(program.programId(), "materialBuffer"); if (loc >= 0) { glUniformBlockBinding(program.programId(), loc, 1); @@ -214,6 +214,13 @@ void Model::initProgram(ProgramObject& program, Model::Locations& locations, boo } else { locations.materialBufferUnit = -1; } +#else + loc = program.uniformLocation("materialBuffer"); + if (loc >= 0) { + locations.materialBufferUnit = loc; + } else { + locations.materialBufferUnit = -1; + } #endif if (!program.isLinked()) { From 7c9419aa4eb2ec214034146c957a478131c7c3a8 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 16 Jan 2015 10:34:52 -0800 Subject: [PATCH 81/93] fix non-bullet build --- libraries/physics/src/EntityMotionState.cpp | 3 ++- libraries/physics/src/EntityMotionState.h | 2 ++ libraries/physics/src/PhysicsEngine.cpp | 8 +++++--- libraries/physics/src/PhysicsEngine.h | 8 ++++++-- libraries/physics/src/SimpleEntityKinematicController.h | 2 ++ 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index a5a91acb09..80cd16713b 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -234,7 +234,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ uint32_t EntityMotionState::getIncomingDirtyFlags() const { uint32_t dirtyFlags = _entity->getDirtyFlags(); - +#ifdef USE_BULLET_PHYSICS // we add DIRTY_MOTION_TYPE if the body's motion type disagrees with entity velocity settings int bodyFlags = _body->getCollisionFlags(); bool isMoving = _entity->isMoving(); @@ -242,5 +242,6 @@ uint32_t EntityMotionState::getIncomingDirtyFlags() const { (bodyFlags & btCollisionObject::CF_KINEMATIC_OBJECT && !isMoving)) { dirtyFlags |= EntityItem::DIRTY_MOTION_TYPE; } +#endif // USE_BULLET_PHYSICS return dirtyFlags; } diff --git a/libraries/physics/src/EntityMotionState.h b/libraries/physics/src/EntityMotionState.h index ce2becd729..6d98ee167d 100644 --- a/libraries/physics/src/EntityMotionState.h +++ b/libraries/physics/src/EntityMotionState.h @@ -18,9 +18,11 @@ #ifndef USE_BULLET_PHYSICS // ObjectMotionState stubbery +#include "KinematicController.h" class ObjectMotionState { public: // so that this stub implementation is not completely empty we give the class a data member + KinematicController* _kinematicController; bool _stubData; }; #endif // USE_BULLET_PHYSICS diff --git a/libraries/physics/src/PhysicsEngine.cpp b/libraries/physics/src/PhysicsEngine.cpp index 62553d1cc4..c5c2d91cf3 100644 --- a/libraries/physics/src/PhysicsEngine.cpp +++ b/libraries/physics/src/PhysicsEngine.cpp @@ -10,10 +10,7 @@ // #include "PhysicsEngine.h" -#ifdef USE_BULLET_PHYSICS -#include "ShapeInfoUtil.h" -#include "ThreadSafeDynamicsWorld.h" static uint32_t _frameCount; @@ -22,6 +19,11 @@ uint32_t PhysicsEngine::getFrameCount() { return _frameCount; } +#ifdef USE_BULLET_PHYSICS + +#include "ShapeInfoUtil.h" +#include "ThreadSafeDynamicsWorld.h" + PhysicsEngine::PhysicsEngine(const glm::vec3& offset) : _collisionConfig(NULL), _collisionDispatcher(NULL), diff --git a/libraries/physics/src/PhysicsEngine.h b/libraries/physics/src/PhysicsEngine.h index fd81e12eb8..b11dd82081 100644 --- a/libraries/physics/src/PhysicsEngine.h +++ b/libraries/physics/src/PhysicsEngine.h @@ -12,9 +12,12 @@ #ifndef hifi_PhysicsEngine_h #define hifi_PhysicsEngine_h +#include + +const float PHYSICS_ENGINE_FIXED_SUBSTEP = 1.0f / 60.0f; + #ifdef USE_BULLET_PHYSICS -#include #include #include @@ -27,7 +30,6 @@ #include "ThreadSafeDynamicsWorld.h" const float HALF_SIMULATION_EXTENT = 512.0f; // meters -const float PHYSICS_ENGINE_FIXED_SUBSTEP = 1.0f / 60.0f; class ObjectMotionState; @@ -97,6 +99,8 @@ private: #else // USE_BULLET_PHYSICS // PhysicsEngine stubbery until Bullet is required class PhysicsEngine { +public: + static uint32_t getFrameCount(); }; #endif // USE_BULLET_PHYSICS #endif // hifi_PhysicsEngine_h diff --git a/libraries/physics/src/SimpleEntityKinematicController.h b/libraries/physics/src/SimpleEntityKinematicController.h index 78c8569a0f..1edfaf8d2c 100644 --- a/libraries/physics/src/SimpleEntityKinematicController.h +++ b/libraries/physics/src/SimpleEntityKinematicController.h @@ -17,6 +17,8 @@ #include #include +#include + #include "KinematicController.h" class SimpleEntityKinematicController : public KinematicController { From 9c1196a2a6a0f9867e7b1a8566c03a8f194520f6 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 16 Jan 2015 12:08:56 -0800 Subject: [PATCH 82/93] put user location without curly braces --- interface/src/Application.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ff6c87123f..3ef17e9067 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3187,11 +3187,13 @@ void Application::updateLocationInServer() { if (!addressManager->getRootPlaceID().isNull()) { const QString PLACE_ID_KEY_IN_LOCATION = "place_id"; - locationObject.insert(PLACE_ID_KEY_IN_LOCATION, addressManager->getRootPlaceID().toString()); + locationObject.insert(PLACE_ID_KEY_IN_LOCATION, + uuidStringWithoutCurlyBraces(addressManager->getRootPlaceID())); } else { const QString DOMAIN_ID_KEY_IN_LOCATION = "domain_id"; - locationObject.insert(DOMAIN_ID_KEY_IN_LOCATION, domainHandler.getUUID().toString()); + locationObject.insert(DOMAIN_ID_KEY_IN_LOCATION, + uuidStringWithoutCurlyBraces(domainHandler.getUUID())); } rootObject.insert(LOCATION_KEY_IN_ROOT, locationObject); From 54a6a0a27c5d1f7614ba7843a12c7c8c7960f96a Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 16 Jan 2015 12:50:50 -0800 Subject: [PATCH 83/93] use custom config when hunting for bullet include --- cmake/modules/FindBullet.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/modules/FindBullet.cmake b/cmake/modules/FindBullet.cmake index 9401a799e1..98d26b5ea4 100644 --- a/cmake/modules/FindBullet.cmake +++ b/cmake/modules/FindBullet.cmake @@ -58,6 +58,8 @@ endmacro() find_path(BULLET_INCLUDE_DIR NAMES btBulletCollisionCommon.h HINTS + $ENV{HIFI_LIB_DIR}/bullet + $ENV{BULLET_ROOT_DIR} ${BULLET_ROOT}/include ${BULLET_ROOT}/src PATH_SUFFIXES bullet From a293c61c0540eb323a750780941a8cda17ab41b9 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 16 Jan 2015 13:20:58 -0800 Subject: [PATCH 84/93] use hifi_library_search_hints() macro --- cmake/modules/FindBullet.cmake | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/cmake/modules/FindBullet.cmake b/cmake/modules/FindBullet.cmake index 98d26b5ea4..5b2bd6696c 100644 --- a/cmake/modules/FindBullet.cmake +++ b/cmake/modules/FindBullet.cmake @@ -30,13 +30,16 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) + +include("${MACRO_DIR}/HifiLibrarySearchHints.cmake") +hifi_library_search_hints("bullet") + macro(_FIND_BULLET_LIBRARY _var) find_library(${_var} NAMES ${ARGN} HINTS - $ENV{HIFI_LIB_DIR}/bullet - $ENV{BULLET_ROOT_DIR} + ${BULLET_SEARCH_DIRS} ${BULLET_ROOT} ${BULLET_ROOT}/lib/Release ${BULLET_ROOT}/lib/Debug @@ -58,8 +61,7 @@ endmacro() find_path(BULLET_INCLUDE_DIR NAMES btBulletCollisionCommon.h HINTS - $ENV{HIFI_LIB_DIR}/bullet - $ENV{BULLET_ROOT_DIR} + ${BULLET_SEARCH_DIRS} ${BULLET_ROOT}/include ${BULLET_ROOT}/src PATH_SUFFIXES bullet From e5eccbc7911eee567ed23171105f492a124b7d53 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 16 Jan 2015 13:25:43 -0800 Subject: [PATCH 85/93] add back BULLET_ROOT_DIR hint --- cmake/modules/FindBullet.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/modules/FindBullet.cmake b/cmake/modules/FindBullet.cmake index 5b2bd6696c..7651de0972 100644 --- a/cmake/modules/FindBullet.cmake +++ b/cmake/modules/FindBullet.cmake @@ -40,6 +40,7 @@ macro(_FIND_BULLET_LIBRARY _var) ${ARGN} HINTS ${BULLET_SEARCH_DIRS} + $ENV{BULLET_ROOT_DIR} ${BULLET_ROOT} ${BULLET_ROOT}/lib/Release ${BULLET_ROOT}/lib/Debug @@ -62,6 +63,7 @@ endmacro() find_path(BULLET_INCLUDE_DIR NAMES btBulletCollisionCommon.h HINTS ${BULLET_SEARCH_DIRS} + $ENV{BULLET_ROOT_DIR} ${BULLET_ROOT}/include ${BULLET_ROOT}/src PATH_SUFFIXES bullet From 0a04dc844516a7475d3f85c439751e0a2ad95d4a Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 16 Jan 2015 13:38:11 -0800 Subject: [PATCH 86/93] modify PATH_SUFFIXES when hunting for include dir --- cmake/modules/FindBullet.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/modules/FindBullet.cmake b/cmake/modules/FindBullet.cmake index 7651de0972..9a2ccb09bb 100644 --- a/cmake/modules/FindBullet.cmake +++ b/cmake/modules/FindBullet.cmake @@ -66,7 +66,7 @@ find_path(BULLET_INCLUDE_DIR NAMES btBulletCollisionCommon.h $ENV{BULLET_ROOT_DIR} ${BULLET_ROOT}/include ${BULLET_ROOT}/src - PATH_SUFFIXES bullet + PATH_SUFFIXES bullet include/bullet ) # Find the libraries From 9a60896a405ec6afc0e9f87e10de06bf7dc6c1e4 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 16 Jan 2015 14:24:50 -0800 Subject: [PATCH 87/93] fix double targets and freezing bullets --- libraries/physics/src/EntityMotionState.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index a15f8a9f51..c83d194f59 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -147,6 +147,9 @@ float EntityMotionState::computeMass(const ShapeInfo& shapeInfo) const { void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_t frame) { #ifdef USE_BULLET_PHYSICS + if (!_entity->isKnownID()) { + return; // never update entities that are unknown + } if (_outgoingPacketFlags) { EntityItemProperties properties = _entity->getProperties(); From b2cadbe36af0e7b6c3f238357f33bc43676ff6f8 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 16 Jan 2015 15:24:26 -0800 Subject: [PATCH 88/93] Stop notifications of all users at startup --- examples/notifications.js | 43 ++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/examples/notifications.js b/examples/notifications.js index 5527fc35fc..9a6fbbce29 100644 --- a/examples/notifications.js +++ b/examples/notifications.js @@ -259,14 +259,16 @@ function checkSize(){ // Triggers notification if a user logs on or off function onOnlineUsersChanged(users) { - for (user in users) { - if (last_users.indexOf(users[user]) == -1.0) { - createNotification(users[user] + " has joined"); + if (!isStartingUp()) { // Skip user notifications at startup. + for (user in users) { + if (last_users.indexOf(users[user]) == -1.0) { + createNotification(users[user] + " has joined"); + } } - } - for (user in last_users) { - if (users.indexOf(last_users[user]) == -1.0) { - createNotification(last_users[user] + " has left"); + for (user in last_users) { + if (users.indexOf(last_users[user]) == -1.0) { + createNotification(last_users[user] + " has left"); + } } } last_users = users; @@ -348,17 +350,38 @@ function dismiss(firstNoteOut, firstButOut, firstOut) { myAlpha.splice(firstOut,1); } -// This is meant to show users online at startup but currently shows 0 users. -function onConnected() { +// This reports the number of users online at startup +function reportUsers() { var numUsers = GlobalServices.onlineUsers.length; var welcome = "Welcome! There are " + numUsers + " users online now."; createNotification(welcome); } +var STARTUP_TIMEOUT = 500, // ms + startingUp = true, + startupTimer = null; + +function finishStartup() { + startingUp = false; + Script.clearTimeout(startupTimer); + reportUsers(); +} + +function isStartingUp() { + // Is starting up until get no checks that it is starting up for STARTUP_TIMEOUT + if (startingUp) { + if (startupTimer) { + Script.clearTimeout(startupTimer); + } + startupTimer = Script.setTimeout(finishStartup, STARTUP_TIMEOUT); + } + return startingUp; +} + + AudioDevice.muteToggled.connect(onMuteStateChanged); Controller.keyPressEvent.connect(keyPressEvent); Controller.mousePressEvent.connect(mousePressEvent); -GlobalServices.connected.connect(onConnected); GlobalServices.onlineUsersChanged.connect(onOnlineUsersChanged); GlobalServices.incomingMessage.connect(onIncomingMessage); Controller.keyReleaseEvent.connect(keyReleaseEvent); From 117ed9206c32cce2b211f9258e81dd80c3ed6295 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 16 Jan 2015 16:19:47 -0800 Subject: [PATCH 89/93] add ${BULLET_SEARCH_DIRS}/include, remove PATH_SUFFIXES include/bullet --- cmake/modules/FindBullet.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/modules/FindBullet.cmake b/cmake/modules/FindBullet.cmake index 9a2ccb09bb..e99b557df4 100644 --- a/cmake/modules/FindBullet.cmake +++ b/cmake/modules/FindBullet.cmake @@ -62,11 +62,11 @@ endmacro() find_path(BULLET_INCLUDE_DIR NAMES btBulletCollisionCommon.h HINTS - ${BULLET_SEARCH_DIRS} + ${BULLET_SEARCH_DIRS}/include $ENV{BULLET_ROOT_DIR} ${BULLET_ROOT}/include ${BULLET_ROOT}/src - PATH_SUFFIXES bullet include/bullet + PATH_SUFFIXES bullet ) # Find the libraries From 614a7eb0b5dba99dfb45cdae16c437276a026f83 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 16 Jan 2015 16:49:11 -0800 Subject: [PATCH 90/93] fix for entities rendering as black on linux --- cmake/macros/AutoScribeShader.cmake | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cmake/macros/AutoScribeShader.cmake b/cmake/macros/AutoScribeShader.cmake index 5584afe5e9..8b221c8c59 100755 --- a/cmake/macros/AutoScribeShader.cmake +++ b/cmake/macros/AutoScribeShader.cmake @@ -42,6 +42,11 @@ function(AUTOSCRIBE_SHADER SHADER_FILE) set(GLPROFILE MAC_GL) set(SCRIBE_ARGS -c++ -D GLPROFILE ${GLPROFILE} ${SCRIBE_INCLUDES} -o ${SHADER_TARGET} ${SHADER_FILE}) + add_custom_command(OUTPUT ${SHADER_TARGET} COMMAND scribe ${SCRIBE_ARGS} DEPENDS scribe ${SHADER_INCLUDE_FILES} ${SHADER_FILE}) + elseif (UNIX) + set(GLPROFILE LINUX_GL) + set(SCRIBE_ARGS -c++ -D GLPROFILE ${GLPROFILE} ${SCRIBE_INCLUDES} -o ${SHADER_TARGET} ${SHADER_FILE}) + add_custom_command(OUTPUT ${SHADER_TARGET} COMMAND scribe ${SCRIBE_ARGS} DEPENDS scribe ${SHADER_INCLUDE_FILES} ${SHADER_FILE}) else (APPLE) set(GLPROFILE PC_GL) From 9860feec6193ecdb55eb1e422f77c90dc54ca5a7 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Mon, 19 Jan 2015 09:54:44 -0800 Subject: [PATCH 91/93] Tweak 3D text overlay text size calculations --- interface/src/ui/overlays/Text3DOverlay.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index 92f6350936..2f4cde50f7 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -238,8 +238,8 @@ QSizeF Text3DOverlay::textSize(const QString& text) const { QFont font(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE); // Same font properties as render() QFontMetrics fontMetrics(font); - const float TEXT_SCALE_ADJUST = 1.02f; // Experimentally detemined for the specified font - const int TEXT_HEIGHT_ADJUST = -6; + const float TEXT_SCALE_ADJUST = 1.025f; // Experimentally detemined for the specified font + const int TEXT_HEIGHT_ADJUST = -10; float scaleFactor = _lineHeight * TEXT_SCALE_ADJUST * LINE_SCALE_RATIO / (float)FIXED_FONT_POINT_SIZE; QStringList lines = text.split(QRegExp("\r\n|\r|\n")); From 990ca8397eb5860a073365d100a4606abd586d0b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 19 Jan 2015 10:23:05 -0800 Subject: [PATCH 92/93] add extra debugging for AddressManager connect to domain --- libraries/networking/src/AddressManager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 17cb919b19..fba3861f43 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -389,6 +389,8 @@ void AddressManager::setDomainInfo(const QString& hostname, quint16 port) { _rootPlaceName = hostname; _rootPlaceID = QUuid(); + qDebug() << "Possible domain change required to connect to domain at" << hostname << "on" << port; + emit possibleDomainChangeRequired(hostname, port); } From fd9b56fe49dcb5ca7775254eccf559b0f1bb4b8f Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 19 Jan 2015 10:41:45 -0800 Subject: [PATCH 93/93] add lib/Release and lib/Debug to lib PATH_SUFFIXES --- cmake/modules/FindBullet.cmake | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cmake/modules/FindBullet.cmake b/cmake/modules/FindBullet.cmake index e99b557df4..65d064e91b 100644 --- a/cmake/modules/FindBullet.cmake +++ b/cmake/modules/FindBullet.cmake @@ -42,11 +42,9 @@ macro(_FIND_BULLET_LIBRARY _var) ${BULLET_SEARCH_DIRS} $ENV{BULLET_ROOT_DIR} ${BULLET_ROOT} - ${BULLET_ROOT}/lib/Release - ${BULLET_ROOT}/lib/Debug ${BULLET_ROOT}/out/release8/libs ${BULLET_ROOT}/out/debug8/libs - PATH_SUFFIXES lib + PATH_SUFFIXES lib lib/Release lib/Debug ) mark_as_advanced(${_var}) endmacro()