From 02d3d384ca00af2ac9bc7d8364247bee56784407 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 13 Dec 2013 19:02:45 -0800 Subject: [PATCH 01/17] added basic support for hit particles with the palm of the hand --- interface/src/avatar/Hand.cpp | 74 +++++++++++++++---- libraries/avatars/src/HandData.h | 6 +- libraries/particles/src/Particle.h | 4 +- .../particles/src/ParticleCollisionSystem.cpp | 2 +- 4 files changed, 67 insertions(+), 19 deletions(-) diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index b718729fcb..ad1c3fbf50 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -72,22 +72,47 @@ void Hand::reset() { } void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, float deltaTime) { + int handID = palm.getSixenseID(); - glm::vec3 targetPosition = fingerTipPosition / (float)TREE_SCALE; - float targetRadius = (TOY_BALL_RADIUS * 2.0f) / (float)TREE_SCALE; + glm::vec3 targetPosition = palm.getPosition() / (float)TREE_SCALE; + float targetRadius = 0.25f / (float)TREE_SCALE; // (TOY_BALL_RADIUS * 4.0f) / (float)TREE_SCALE; const Particle* closestParticle = Application::getInstance()->getParticles() ->getTree()->findClosestParticle(targetPosition, targetRadius); if (closestParticle) { //printf("potentially caught... particle ID:%d\n", closestParticle->getID()); - // you can create a ParticleEditHandle by doing this... - ParticleEditHandle* caughtParticle = Application::getInstance()->newParticleEditHandle(closestParticle->getID()); + if (!_toyBallInHand[handID]) { + printf("particle ID:%d NOT IN HAND\n", closestParticle->getID()); + + // you can create a ParticleEditHandle by doing this... + ParticleEditHandle* caughtParticle = Application::getInstance()->newParticleEditHandle(closestParticle->getID()); - // but make sure you clean it up, when you're done - delete caughtParticle; + // reflect off the hand... + printf("particle ID:%d old velocity=%f,%f,%f\n", closestParticle->getID(), + closestParticle->getVelocity().x, closestParticle->getVelocity().y, closestParticle->getVelocity().z); + glm::vec3 newVelocity = glm::reflect(closestParticle->getVelocity(), palm.getNormal()); + + printf("particle ID:%d REFLECT velocity=%f,%f,%f\n", closestParticle->getID(), + newVelocity.x, newVelocity.y, newVelocity.z); + + newVelocity += palm.getTipVelocity() / (float)TREE_SCALE; + + printf("particle ID:%d with TIP velocity=%f,%f,%f\n", closestParticle->getID(), + newVelocity.x, newVelocity.y, newVelocity.z); + + caughtParticle->updateParticle(closestParticle->getPosition(), + closestParticle->getRadius(), + closestParticle->getXColor(), + newVelocity, + closestParticle->getGravity(), + closestParticle->getDamping(), + closestParticle->getUpdateScript()); + + // but make sure you clean it up, when you're done + delete caughtParticle; + } } - int handID = palm.getSixenseID(); // If there's a ball in hand, and the user presses the skinny button, then change the color of the ball int currentControllerButtons = palm.getControllerButtons(); @@ -118,8 +143,9 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f // create the ball, call MakeParticle, and use the resulting ParticleEditHandle to // manage the newly created particle. // Create a particle on the particle server + glm::vec3 ballPosition = palm.getPosition(); _ballParticleEditHandles[handID] = Application::getInstance()->makeParticle( - fingerTipPosition / (float)TREE_SCALE, + ballPosition / (float)TREE_SCALE, TOY_BALL_RADIUS / (float) TREE_SCALE, TOY_BALL_ON_SERVER_COLOR[_whichBallColor[handID]], NO_VELOCITY / (float)TREE_SCALE, @@ -129,7 +155,8 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f } } else { // Ball is in hand - _ballParticleEditHandles[handID]->updateParticle(fingerTipPosition / (float)TREE_SCALE, + glm::vec3 ballPosition = palm.getPosition(); + _ballParticleEditHandles[handID]->updateParticle(ballPosition / (float)TREE_SCALE, TOY_BALL_RADIUS / (float) TREE_SCALE, TOY_BALL_ON_SERVER_COLOR[_whichBallColor[handID]], NO_VELOCITY / (float)TREE_SCALE, @@ -142,13 +169,14 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f if (_toyBallInHand[handID]) { _toyBallInHand[handID] = false; + glm::vec3 ballPosition = palm.getPosition(); glm::vec3 handVelocity = palm.getRawVelocity(); glm::vec3 fingerTipVelocity = palm.getTipVelocity(); glm::quat avatarRotation = _owningAvatar->getOrientation(); glm::vec3 toyBallVelocity = avatarRotation * fingerTipVelocity; // ball is no longer in hand... - _ballParticleEditHandles[handID]->updateParticle(fingerTipPosition / (float)TREE_SCALE, + _ballParticleEditHandles[handID]->updateParticle(ballPosition / (float)TREE_SCALE, TOY_BALL_RADIUS / (float) TREE_SCALE, TOY_BALL_ON_SERVER_COLOR[_whichBallColor[handID]], toyBallVelocity / (float)TREE_SCALE, @@ -406,8 +434,25 @@ void Hand::renderLeapHands() { //const glm::vec3 handColor = _ballColor; const glm::vec3 handColor(1.0, 0.84, 0.66); // use the skin color + + glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); + + for (size_t i = 0; i < getNumPalms(); ++i) { + PalmData& palm = getPalms()[i]; + if (!palm.isActive()) { + continue; + } + glm::vec3 targetPosition = palm.getPosition(); + float targetRadius = 0.25f; + glPushMatrix(); + glColor4f(1,1,0, alpha); + glTranslatef(targetPosition.x, targetPosition.y, targetPosition.z); + glutWireSphere(targetRadius, 20.0f, 20.0f); + glPopMatrix(); + } + glPushMatrix(); // Draw the leap balls for (size_t i = 0; i < _leapFingerTipBalls.size(); i++) { @@ -444,11 +489,14 @@ void Hand::renderLeapHands() { for (size_t i = 0; i < getNumPalms(); ++i) { PalmData& palm = getPalms()[i]; if (palm.isActive()) { - const float palmThickness = 0.02f; - glColor4f(handColor.r, handColor.g, handColor.b, 0.25); + const float palmThickness = 0.05f; //0.02f; + //glColor4f(handColor.r, handColor.g, handColor.b, 0.25); + glColor4f(1.0, 0.0, 0.0, 0.25); glm::vec3 tip = palm.getPosition(); glm::vec3 root = palm.getPosition() + palm.getNormal() * palmThickness; - Avatar::renderJointConnectingCone(root, tip, 0.05, 0.03); + const float radiusA = 0.25f; // 0.05f; + const float radiusB = 0.23f; // 0.03f; + Avatar::renderJointConnectingCone(root, tip, radiusA, radiusB); } } glDepthMask(GL_TRUE); diff --git a/libraries/avatars/src/HandData.h b/libraries/avatars/src/HandData.h index 6fba4d5e2c..86f29cf2f1 100755 --- a/libraries/avatars/src/HandData.h +++ b/libraries/avatars/src/HandData.h @@ -122,8 +122,8 @@ private: class PalmData { public: PalmData(HandData* owningHandData); - glm::vec3 getPosition() const { return _owningHandData->leapPositionToWorldPosition(_rawPosition); } - glm::vec3 getNormal() const { return _owningHandData->leapDirectionToWorldDirection(_rawNormal); } + glm::vec3 getPosition() const { return _owningHandData->leapPositionToWorldPosition(_rawPosition); } + glm::vec3 getNormal() const { return _owningHandData->leapDirectionToWorldDirection(_rawNormal); } const glm::vec3& getRawPosition() const { return _rawPosition; } const glm::vec3& getRawNormal() const { return _rawNormal; } @@ -140,7 +140,7 @@ public: void setSixenseID(int id) { _sixenseID = id; } void setRawRotation(const glm::quat rawRotation) { _rawRotation = rawRotation; }; - const glm::quat getRawRotation() const { return _rawRotation; } + glm::quat getRawRotation() const { return _rawRotation; } void setRawPosition(const glm::vec3& pos) { _rawPosition = pos; } void setRawNormal(const glm::vec3& normal) { _rawNormal = normal; } void setRawVelocity(const glm::vec3& velocity) { _rawVelocity = velocity; } diff --git a/libraries/particles/src/Particle.h b/libraries/particles/src/Particle.h index 8e754fee39..1d80adabc6 100644 --- a/libraries/particles/src/Particle.h +++ b/libraries/particles/src/Particle.h @@ -57,7 +57,7 @@ public: const glm::vec3& getPosition() const { return _position; } const rgbColor& getColor() const { return _color; } - xColor getColor() { xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; } + xColor getXColor() const { xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; } float getRadius() const { return _radius; } const glm::vec3& getVelocity() const { return _velocity; } const glm::vec3& getGravity() const { return _gravity; } @@ -129,7 +129,7 @@ public: public slots: glm::vec3 getPosition() const { return _particle->getPosition(); } glm::vec3 getVelocity() const { return _particle->getVelocity(); } - xColor getColor() const { return _particle->getColor(); } + xColor getColor() const { return _particle->getXColor(); } glm::vec3 getGravity() const { return _particle->getGravity(); } float getDamping() const { return _particle->getDamping(); } float getRadius() const { return _particle->getRadius(); } diff --git a/libraries/particles/src/ParticleCollisionSystem.cpp b/libraries/particles/src/ParticleCollisionSystem.cpp index 764cbe3381..8928a3db8c 100644 --- a/libraries/particles/src/ParticleCollisionSystem.cpp +++ b/libraries/particles/src/ParticleCollisionSystem.cpp @@ -119,7 +119,7 @@ void ParticleCollisionSystem::applyHardCollision(Particle* particle, const glm:: } } ParticleEditHandle particleEditHandle(_packetSender, _particles, particle->getID()); - particleEditHandle.updateParticle(position, particle->getRadius(), particle->getColor(), velocity, + particleEditHandle.updateParticle(position, particle->getRadius(), particle->getXColor(), velocity, particle->getGravity(), particle->getDamping(), particle->getUpdateScript()); } From e2fbb7beb4ec3e285775a9bb9dcba5ab95c69577 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 14 Dec 2013 08:14:38 -0800 Subject: [PATCH 02/17] first cut at splitting out scripting engine from agent to add to client --- assignment-client/src/Agent.cpp | 1 + interface/CMakeLists.txt | 1 + interface/src/Application.cpp | 62 +++++++++++- interface/src/Application.h | 4 + interface/src/Menu.cpp | 3 + interface/src/Menu.h | 1 + libraries/particles/src/Particle.cpp | 3 + .../src/ParticleScriptingInterface.cpp | 49 ++++++++-- .../src/ParticleScriptingInterface.h | 56 ++++++----- libraries/scriptengine/CMakeLists.txt | 30 ++++++ libraries/scriptengine/src/ScriptEngine.cpp | 94 +++++++++++++++++++ libraries/scriptengine/src/ScriptEngine.h | 45 +++++++++ 12 files changed, 318 insertions(+), 31 deletions(-) create mode 100644 libraries/scriptengine/CMakeLists.txt create mode 100644 libraries/scriptengine/src/ScriptEngine.cpp create mode 100644 libraries/scriptengine/src/ScriptEngine.h diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 97638456fd..8ee9d1dc36 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -24,6 +24,7 @@ Agent::Agent(const unsigned char* dataBuffer, int numBytes) : ThreadedAssignment(dataBuffer, numBytes) { + _particleScriptingInterface.init(); } void Agent::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) { diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 31f6e74e5a..00bbd50d8a 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -87,6 +87,7 @@ link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR}) link_hifi_library(particles ${TARGET_NAME} ${ROOT_DIR}) link_hifi_library(avatars ${TARGET_NAME} ${ROOT_DIR}) link_hifi_library(audio ${TARGET_NAME} ${ROOT_DIR}) +link_hifi_library(scriptengine ${TARGET_NAME} ${ROOT_DIR}) # find required libraries find_package(Faceshift) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f12cd94578..a93ba820dc 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -139,7 +139,8 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _recentMaxPackets(0), _resetRecentMaxPacketsSoon(true), _swatch(NULL), - _pasteMode(false) + _pasteMode(false), + _scriptEngine(NULL) { _applicationStartupTime = startup_time; _window->setWindowTitle("Interface"); @@ -4385,3 +4386,62 @@ void Application::packetSentNotification(ssize_t length) { _bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(length); } +void Application::loadScript() { + // shut down and stop any existing script + if (_scriptEngine) { + _scriptEngine->stop(); + _scriptEngine = NULL; + } + + + QString desktopLocation = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); + QString suggestedName = desktopLocation.append("/script.js"); + + QString fileNameString = QFileDialog::getOpenFileName(_glWidget, tr("Open Script"), suggestedName, + tr("JavaScript Files (*.js)")); + QByteArray fileNameAscii = fileNameString.toLocal8Bit(); + const char* fileName = fileNameAscii.data(); + + printf("fileName:%s\n",fileName); + + std::ifstream file(fileName, std::ios::in|std::ios::binary|std::ios::ate); + if(!file.is_open()) { + printf("error loading file\n"); + return; + } + qDebug("loading file %s...\n", fileName); + + // get file length.... + unsigned long fileLength = file.tellg(); + file.seekg( 0, std::ios::beg ); + + // read the entire file into a buffer, WHAT!? Why not. + char* entireFile = new char[fileLength]; + file.read((char*)entireFile, fileLength); + file.close(); + + QString script(entireFile); + delete[] entireFile; + + // start the script on a new thread... + _scriptEngine = new ScriptEngine(script); + + QThread* workerThread = new QThread(this); + + connect(workerThread, SIGNAL(started()), _scriptEngine, SLOT(run())); + + connect(_scriptEngine, SIGNAL(finished()), this, SLOT(assignmentCompleted())); + connect(_scriptEngine, SIGNAL(finished()), workerThread, SLOT(quit())); + connect(_scriptEngine, SIGNAL(finished()), _scriptEngine, SLOT(deleteLater())); + connect(_scriptEngine, SIGNAL(finished()), workerThread, SLOT(deleteLater())); + + _scriptEngine->moveToThread(workerThread); + + // Starts an event loop, and emits workerThread->started() + workerThread->start(); + + + + // restore the main window's active state + _window->activateWindow(); +} diff --git a/interface/src/Application.h b/interface/src/Application.h index a37e13147a..8b9127032f 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #ifndef _WIN32 @@ -217,6 +218,7 @@ public slots: void doKillLocalVoxels(); void decreaseVoxelSize(); void increaseVoxelSize(); + void loadScript(); private slots: @@ -495,6 +497,8 @@ private: std::vector _voxelFades; std::vector _avatarFades; + + ScriptEngine* _scriptEngine; }; #endif /* defined(__interface__Application__) */ diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 13510067cd..44c04b685d 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -90,6 +90,9 @@ Menu::Menu() : this, SLOT(login()))); + addDisabledActionAndSeparator(fileMenu, "Scripts"); + addActionToQMenuAndActionHash(fileMenu, MenuOption::LoadScript, Qt::CTRL | Qt::Key_O, appInstance, SLOT(loadScript())); + addDisabledActionAndSeparator(fileMenu, "Voxels"); addActionToQMenuAndActionHash(fileMenu, MenuOption::ExportVoxels, Qt::CTRL | Qt::Key_E, appInstance, SLOT(exportVoxels())); addActionToQMenuAndActionHash(fileMenu, MenuOption::ImportVoxels, Qt::CTRL | Qt::Key_I, appInstance, SLOT(importVoxels())); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index aa3b925517..a1dce998bd 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -217,6 +217,7 @@ namespace MenuOption { const QString OldVoxelCullingMode = "Old Voxel Culling Mode"; const QString TurnWithHead = "Turn using Head"; const QString ClickToFly = "Fly to voxel on click"; + const QString LoadScript = "Open and Run Script..."; const QString Oscilloscope = "Audio Oscilloscope"; const QString Pair = "Pair"; const QString PasteVoxels = "Paste"; diff --git a/libraries/particles/src/Particle.cpp b/libraries/particles/src/Particle.cpp index 25695c5f81..f66a05608a 100644 --- a/libraries/particles/src/Particle.cpp +++ b/libraries/particles/src/Particle.cpp @@ -415,6 +415,9 @@ void Particle::update() { void Particle::runScript() { if (!_updateScript.isEmpty()) { + + qDebug() << "Script: " << _updateScript << "\n"; + QScriptEngine engine; // register meta-type for glm::vec3 and rgbColor conversions diff --git a/libraries/particles/src/ParticleScriptingInterface.cpp b/libraries/particles/src/ParticleScriptingInterface.cpp index bedfab73a0..74640fa671 100644 --- a/libraries/particles/src/ParticleScriptingInterface.cpp +++ b/libraries/particles/src/ParticleScriptingInterface.cpp @@ -8,19 +8,56 @@ #include "ParticleScriptingInterface.h" -ParticleScriptingInterface::ParticleScriptingInterface() : - _jurisdictionListener(NODE_TYPE_PARTICLE_SERVER), +ParticleScriptingInterface::ParticleScriptingInterface(ParticleEditPacketSender* particleSender, + JurisdictionListener* particleJurisdictionListener) : _nextCreatorTokenID(0) { - _jurisdictionListener.initialize(true); - _particlePacketSender.setServerJurisdictions(_jurisdictionListener.getJurisdictions()); + setParticlePacketSender(particleSender); + setJurisdictionListener(particleJurisdictionListener); } +ParticleScriptingInterface::~ParticleScriptingInterface() { + if (_managedJuridiciontListerner) { + delete _jurisdictionListener; + } + if (_managedPacketSender) { + delete _particlePacketSender; + } +} + + +void ParticleScriptingInterface::setParticlePacketSender(ParticleEditPacketSender* particlePacketSender) { + _particlePacketSender = particlePacketSender; +} + +void ParticleScriptingInterface::setJurisdictionListener(JurisdictionListener* jurisdictionListener) { + _jurisdictionListener = jurisdictionListener; +} + +void ParticleScriptingInterface::init() { + if (_jurisdictionListener) { + _managedJuridiciontListerner = false; + } else { + _managedJuridiciontListerner = true; + _jurisdictionListener = new JurisdictionListener(NODE_TYPE_PARTICLE_SERVER); + _jurisdictionListener->initialize(true); + } + + if (_particlePacketSender) { + _managedPacketSender = false; + } else { + _managedPacketSender = true; + _particlePacketSender = new ParticleEditPacketSender(); + _particlePacketSender->setServerJurisdictions(_jurisdictionListener->getJurisdictions()); + } +} + + void ParticleScriptingInterface::queueParticleAdd(PACKET_TYPE addPacketType, ParticleDetail& addParticleDetails) { - _particlePacketSender.queueParticleEditMessages(addPacketType, 1, &addParticleDetails); + _particlePacketSender->queueParticleEditMessages(addPacketType, 1, &addParticleDetails); } -uint32_t ParticleScriptingInterface::queueParticleAdd(glm::vec3 position, float radius, +unsigned int ParticleScriptingInterface::queueParticleAdd(glm::vec3 position, float radius, xColor color, glm::vec3 velocity, glm::vec3 gravity, float damping, QString updateScript) { // The application will keep track of creatorTokenID diff --git a/libraries/particles/src/ParticleScriptingInterface.h b/libraries/particles/src/ParticleScriptingInterface.h index 76a422bd46..0aaec977db 100644 --- a/libraries/particles/src/ParticleScriptingInterface.h +++ b/libraries/particles/src/ParticleScriptingInterface.h @@ -18,71 +18,79 @@ class ParticleScriptingInterface : public QObject { Q_OBJECT public: - ParticleScriptingInterface(); - - ParticleEditPacketSender* getParticlePacketSender() { return &_particlePacketSender; } - JurisdictionListener* getJurisdictionListener() { return &_jurisdictionListener; } + ParticleScriptingInterface(ParticleEditPacketSender* particleSender = NULL, + JurisdictionListener* particleJurisdictionListener = NULL); + + ~ParticleScriptingInterface(); + + ParticleEditPacketSender* getParticlePacketSender() const { return _particlePacketSender; } + JurisdictionListener* getJurisdictionListener() const { return _jurisdictionListener; } + void setParticlePacketSender(ParticleEditPacketSender* particlePacketSender); + void setJurisdictionListener(JurisdictionListener* jurisdictionListener); + void init(); public slots: /// queues the creation of a Particle which will be sent by calling process on the PacketSender /// returns the creatorTokenID for the newly created particle - uint32_t queueParticleAdd(glm::vec3 position, float radius, + unsigned int queueParticleAdd(glm::vec3 position, float radius, xColor color, glm::vec3 velocity, glm::vec3 gravity, float damping, QString updateScript); /// Set the desired max packet size in bytes that should be created - void setMaxPacketSize(int maxPacketSize) { return _particlePacketSender.setMaxPacketSize(maxPacketSize); } + void setMaxPacketSize(int maxPacketSize) { return _particlePacketSender->setMaxPacketSize(maxPacketSize); } /// returns the current desired max packet size in bytes that will be created - int getMaxPacketSize() const { return _particlePacketSender.getMaxPacketSize(); } + int getMaxPacketSize() const { return _particlePacketSender->getMaxPacketSize(); } /// set the max packets per second send rate - void setPacketsPerSecond(int packetsPerSecond) { return _particlePacketSender.setPacketsPerSecond(packetsPerSecond); } + void setPacketsPerSecond(int packetsPerSecond) { return _particlePacketSender->setPacketsPerSecond(packetsPerSecond); } /// get the max packets per second send rate - int getPacketsPerSecond() const { return _particlePacketSender.getPacketsPerSecond(); } + int getPacketsPerSecond() const { return _particlePacketSender->getPacketsPerSecond(); } /// does a particle server exist to send to - bool serversExist() const { return _particlePacketSender.serversExist(); } + bool serversExist() const { return _particlePacketSender->serversExist(); } /// are there packets waiting in the send queue to be sent - bool hasPacketsToSend() const { return _particlePacketSender.hasPacketsToSend(); } + bool hasPacketsToSend() const { return _particlePacketSender->hasPacketsToSend(); } /// how many packets are there in the send queue waiting to be sent - int packetsToSendCount() const { return _particlePacketSender.packetsToSendCount(); } + int packetsToSendCount() const { return _particlePacketSender->packetsToSendCount(); } /// returns the packets per second send rate of this object over its lifetime - float getLifetimePPS() const { return _particlePacketSender.getLifetimePPS(); } + float getLifetimePPS() const { return _particlePacketSender->getLifetimePPS(); } /// returns the bytes per second send rate of this object over its lifetime - float getLifetimeBPS() const { return _particlePacketSender.getLifetimeBPS(); } + float getLifetimeBPS() const { return _particlePacketSender->getLifetimeBPS(); } /// returns the packets per second queued rate of this object over its lifetime - float getLifetimePPSQueued() const { return _particlePacketSender.getLifetimePPSQueued(); } + float getLifetimePPSQueued() const { return _particlePacketSender->getLifetimePPSQueued(); } /// returns the bytes per second queued rate of this object over its lifetime - float getLifetimeBPSQueued() const { return _particlePacketSender.getLifetimeBPSQueued(); } + float getLifetimeBPSQueued() const { return _particlePacketSender->getLifetimeBPSQueued(); } /// returns lifetime of this object from first packet sent to now in usecs - long long unsigned int getLifetimeInUsecs() const { return _particlePacketSender.getLifetimeInUsecs(); } + long long unsigned int getLifetimeInUsecs() const { return _particlePacketSender->getLifetimeInUsecs(); } /// returns lifetime of this object from first packet sent to now in usecs - float getLifetimeInSeconds() const { return _particlePacketSender.getLifetimeInSeconds(); } + float getLifetimeInSeconds() const { return _particlePacketSender->getLifetimeInSeconds(); } /// returns the total packets sent by this object over its lifetime - long long unsigned int getLifetimePacketsSent() const { return _particlePacketSender.getLifetimePacketsSent(); } + long long unsigned int getLifetimePacketsSent() const { return _particlePacketSender->getLifetimePacketsSent(); } /// returns the total bytes sent by this object over its lifetime - long long unsigned int getLifetimeBytesSent() const { return _particlePacketSender.getLifetimeBytesSent(); } + long long unsigned int getLifetimeBytesSent() const { return _particlePacketSender->getLifetimeBytesSent(); } /// returns the total packets queued by this object over its lifetime - long long unsigned int getLifetimePacketsQueued() const { return _particlePacketSender.getLifetimePacketsQueued(); } + long long unsigned int getLifetimePacketsQueued() const { return _particlePacketSender->getLifetimePacketsQueued(); } /// returns the total bytes queued by this object over its lifetime - long long unsigned int getLifetimeBytesQueued() const { return _particlePacketSender.getLifetimeBytesQueued(); } + long long unsigned int getLifetimeBytesQueued() const { return _particlePacketSender->getLifetimeBytesQueued(); } private: /// attached ParticleEditPacketSender that handles queuing and sending of packets to VS - ParticleEditPacketSender _particlePacketSender; - JurisdictionListener _jurisdictionListener; + ParticleEditPacketSender* _particlePacketSender; + JurisdictionListener* _jurisdictionListener; + bool _managedPacketSender; + bool _managedJuridiciontListerner; void queueParticleAdd(PACKET_TYPE addPacketType, ParticleDetail& addParticleDetails); diff --git a/libraries/scriptengine/CMakeLists.txt b/libraries/scriptengine/CMakeLists.txt new file mode 100644 index 0000000000..593feab014 --- /dev/null +++ b/libraries/scriptengine/CMakeLists.txt @@ -0,0 +1,30 @@ +cmake_minimum_required(VERSION 2.8) + +set(ROOT_DIR ../..) +set(MACRO_DIR ${ROOT_DIR}/cmake/macros) + +# setup for find modules +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/modules/") + +set(TARGET_NAME scriptengine) + +find_package(Qt5Widgets REQUIRED) + +include(${MACRO_DIR}/SetupHifiLibrary.cmake) +setup_hifi_library(${TARGET_NAME}) + +qt5_use_modules(${TARGET_NAME} Widgets) + +include(${MACRO_DIR}/IncludeGLM.cmake) +include_glm(${TARGET_NAME} ${ROOT_DIR}) + +include(${MACRO_DIR}/LinkHifiLibrary.cmake) +link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) +link_hifi_library(octree ${TARGET_NAME} ${ROOT_DIR}) +link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR}) +link_hifi_library(particles ${TARGET_NAME} ${ROOT_DIR}) + +# link ZLIB +find_package(ZLIB) +include_directories(${ZLIB_INCLUDE_DIRS}) +target_link_libraries(${TARGET_NAME} ${ZLIB_LIBRARIES}) diff --git a/libraries/scriptengine/src/ScriptEngine.cpp b/libraries/scriptengine/src/ScriptEngine.cpp new file mode 100644 index 0000000000..2768dd1ab5 --- /dev/null +++ b/libraries/scriptengine/src/ScriptEngine.cpp @@ -0,0 +1,94 @@ +// +// Agent.cpp +// hifi +// +// Created by Stephen Birarda on 7/1/13. +// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ScriptEngine.h" + +ScriptEngine::ScriptEngine(QString scriptContents) { + _scriptContents = scriptContents; + _isFinished = false; +} + +void ScriptEngine::run() { + QScriptEngine engine; + + // register meta-type for glm::vec3 conversions + registerMetaTypes(&engine); + + QScriptValue agentValue = engine.newQObject(this); + engine.globalObject().setProperty("Agent", agentValue); + + QScriptValue voxelScripterValue = engine.newQObject(&_voxelScriptingInterface); + engine.globalObject().setProperty("Voxels", voxelScripterValue); + + QScriptValue particleScripterValue = engine.newQObject(&_particleScriptingInterface); + engine.globalObject().setProperty("Particles", particleScripterValue); + + QScriptValue treeScaleValue = engine.newVariant(QVariant(TREE_SCALE)); + engine.globalObject().setProperty("TREE_SCALE", treeScaleValue); + + const unsigned int VISUAL_DATA_CALLBACK_USECS = (1.0 / 60.0) * 1000 * 1000; + + // let the VoxelPacketSender know how frequently we plan to call it + _voxelScriptingInterface.getVoxelPacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS); + _particleScriptingInterface.getParticlePacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS); + + QScriptValue result = engine.evaluate(_scriptContents); + qDebug() << "Evaluated script.\n"; + + if (engine.hasUncaughtException()) { + int line = engine.uncaughtExceptionLineNumber(); + qDebug() << "Uncaught exception at line" << line << ":" << result.toString() << "\n"; + } + + timeval startTime; + gettimeofday(&startTime, NULL); + + int thisFrame = 0; + + qDebug() << "before while... thisFrame:" << thisFrame << "\n"; + + while (!_isFinished) { + + qDebug() << "while... thisFrame:" << thisFrame << "\n"; + + int usecToSleep = usecTimestamp(&startTime) + (thisFrame++ * VISUAL_DATA_CALLBACK_USECS) - usecTimestampNow(); + if (usecToSleep > 0) { + usleep(usecToSleep); + } + + QCoreApplication::processEvents(); + + bool willSendVisualDataCallBack = true; + + if (willSendVisualDataCallBack) { + qDebug() << "willSendVisualDataCallback thisFrame:" << thisFrame << "\n"; + emit willSendVisualDataCallback(); + } + + + if (engine.hasUncaughtException()) { + int line = engine.uncaughtExceptionLineNumber(); + qDebug() << "Uncaught exception at line" << line << ":" << engine.uncaughtException().toString() << "\n"; + } + + + } +} diff --git a/libraries/scriptengine/src/ScriptEngine.h b/libraries/scriptengine/src/ScriptEngine.h new file mode 100644 index 0000000000..21e9c9485c --- /dev/null +++ b/libraries/scriptengine/src/ScriptEngine.h @@ -0,0 +1,45 @@ +// +// ScriptEngine.h +// hifi +// +// Created by Stephen Birarda on 7/1/13. +// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// + +#ifndef __hifi__ScriptEngine__ +#define __hifi__ScriptEngine__ + +#include + +#include +#include +#include + +#include +#include + +class ScriptEngine : public QObject { + Q_OBJECT +public: + ScriptEngine(QString scriptContents); + +public slots: + void run(); + void stop() { + _isFinished = true; + emit finished(); + } + +signals: + void willSendAudioDataCallback(); + void willSendVisualDataCallback(); + void finished(); +protected: + QString _scriptContents; + bool _isFinished; +private: + VoxelScriptingInterface _voxelScriptingInterface; + ParticleScriptingInterface _particleScriptingInterface; +}; + +#endif /* defined(__hifi__ScriptEngine__) */ From c2d5accbc974c86f9d81e69700597a25f2166aef Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 14 Dec 2013 13:25:33 -0800 Subject: [PATCH 03/17] implement OctreeScriptingInterface base class to share common behavior for particle and voxel scripting --- assignment-client/src/Agent.cpp | 1 + .../octree/src/OctreeScriptingInterface.cpp | 51 ++++++++++ .../octree/src/OctreeScriptingInterface.h | 95 +++++++++++++++++++ .../particles/src/ParticleEditPacketSender.h | 2 +- .../src/ParticleScriptingInterface.cpp | 45 +-------- .../src/ParticleScriptingInterface.h | 72 +------------- libraries/voxels/src/VoxelEditPacketSender.h | 2 +- .../voxels/src/VoxelScriptingInterface.cpp | 9 +- .../voxels/src/VoxelScriptingInterface.h | 67 ++----------- 9 files changed, 164 insertions(+), 180 deletions(-) create mode 100644 libraries/octree/src/OctreeScriptingInterface.cpp create mode 100644 libraries/octree/src/OctreeScriptingInterface.h diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 8ee9d1dc36..8f02ed9a2e 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -25,6 +25,7 @@ Agent::Agent(const unsigned char* dataBuffer, int numBytes) : ThreadedAssignment(dataBuffer, numBytes) { _particleScriptingInterface.init(); + _voxelScriptingInterface.init(); } void Agent::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr) { diff --git a/libraries/octree/src/OctreeScriptingInterface.cpp b/libraries/octree/src/OctreeScriptingInterface.cpp new file mode 100644 index 0000000000..383e7a3877 --- /dev/null +++ b/libraries/octree/src/OctreeScriptingInterface.cpp @@ -0,0 +1,51 @@ +// +// OctreeScriptingInterface.cpp +// hifi +// +// Created by Brad Hefta-Gaub on 12/6/13 +// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// + +#include "OctreeScriptingInterface.h" + +OctreeScriptingInterface::OctreeScriptingInterface(OctreeEditPacketSender* packetSender, + JurisdictionListener* jurisdictionListener) +{ + setPacketSender(packetSender); + setJurisdictionListener(jurisdictionListener); +} + +OctreeScriptingInterface::~OctreeScriptingInterface() { + if (_managedJuridiciontListerner) { + delete _jurisdictionListener; + } + if (_managedPacketSender) { + delete _packetSender; + } +} + +void OctreeScriptingInterface::setPacketSender(OctreeEditPacketSender* packetSender) { + _packetSender = packetSender; +} + +void OctreeScriptingInterface::setJurisdictionListener(JurisdictionListener* jurisdictionListener) { + _jurisdictionListener = jurisdictionListener; +} + +void OctreeScriptingInterface::init() { + if (_jurisdictionListener) { + _managedJuridiciontListerner = false; + } else { + _managedJuridiciontListerner = true; + _jurisdictionListener = new JurisdictionListener(getServerNodeType()); + _jurisdictionListener->initialize(true); + } + + if (_packetSender) { + _managedPacketSender = false; + } else { + _managedPacketSender = true; + _packetSender = createPacketSender(); + _packetSender->setServerJurisdictions(_jurisdictionListener->getJurisdictions()); + } +} diff --git a/libraries/octree/src/OctreeScriptingInterface.h b/libraries/octree/src/OctreeScriptingInterface.h new file mode 100644 index 0000000000..7eb0538ca2 --- /dev/null +++ b/libraries/octree/src/OctreeScriptingInterface.h @@ -0,0 +1,95 @@ +// +// OctreeScriptingInterface.h +// hifi +// +// Created by Brad Hefta-Gaub on 12/6/13 +// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// + +#ifndef __hifi__OctreeScriptingInterface__ +#define __hifi__OctreeScriptingInterface__ + +#include + +#include "JurisdictionListener.h" +#include "OctreeEditPacketSender.h" + +/// handles scripting of Particle commands from JS passed to assigned clients +class OctreeScriptingInterface : public QObject { + Q_OBJECT +public: + OctreeScriptingInterface(OctreeEditPacketSender* packetSender = NULL, + JurisdictionListener* jurisdictionListener = NULL); + + ~OctreeScriptingInterface(); + + OctreeEditPacketSender* getPacketSender() const { return _packetSender; } + JurisdictionListener* getJurisdictionListener() const { return _jurisdictionListener; } + void setPacketSender(OctreeEditPacketSender* packetSender); + void setJurisdictionListener(JurisdictionListener* jurisdictionListener); + void init(); + + virtual NODE_TYPE getServerNodeType() const = 0; + virtual OctreeEditPacketSender* createPacketSender() = 0; + +public slots: + /// Set the desired max packet size in bytes that should be created + void setMaxPacketSize(int maxPacketSize) { return _packetSender->setMaxPacketSize(maxPacketSize); } + + /// returns the current desired max packet size in bytes that will be created + int getMaxPacketSize() const { return _packetSender->getMaxPacketSize(); } + + /// set the max packets per second send rate + void setPacketsPerSecond(int packetsPerSecond) { return _packetSender->setPacketsPerSecond(packetsPerSecond); } + + /// get the max packets per second send rate + int getPacketsPerSecond() const { return _packetSender->getPacketsPerSecond(); } + + /// does a particle server exist to send to + bool serversExist() const { return _packetSender->serversExist(); } + + /// are there packets waiting in the send queue to be sent + bool hasPacketsToSend() const { return _packetSender->hasPacketsToSend(); } + + /// how many packets are there in the send queue waiting to be sent + int packetsToSendCount() const { return _packetSender->packetsToSendCount(); } + + /// returns the packets per second send rate of this object over its lifetime + float getLifetimePPS() const { return _packetSender->getLifetimePPS(); } + + /// returns the bytes per second send rate of this object over its lifetime + float getLifetimeBPS() const { return _packetSender->getLifetimeBPS(); } + + /// returns the packets per second queued rate of this object over its lifetime + float getLifetimePPSQueued() const { return _packetSender->getLifetimePPSQueued(); } + + /// returns the bytes per second queued rate of this object over its lifetime + float getLifetimeBPSQueued() const { return _packetSender->getLifetimeBPSQueued(); } + + /// returns lifetime of this object from first packet sent to now in usecs + long long unsigned int getLifetimeInUsecs() const { return _packetSender->getLifetimeInUsecs(); } + + /// returns lifetime of this object from first packet sent to now in usecs + float getLifetimeInSeconds() const { return _packetSender->getLifetimeInSeconds(); } + + /// returns the total packets sent by this object over its lifetime + long long unsigned int getLifetimePacketsSent() const { return _packetSender->getLifetimePacketsSent(); } + + /// returns the total bytes sent by this object over its lifetime + long long unsigned int getLifetimeBytesSent() const { return _packetSender->getLifetimeBytesSent(); } + + /// returns the total packets queued by this object over its lifetime + long long unsigned int getLifetimePacketsQueued() const { return _packetSender->getLifetimePacketsQueued(); } + + /// returns the total bytes queued by this object over its lifetime + long long unsigned int getLifetimeBytesQueued() const { return _packetSender->getLifetimeBytesQueued(); } + +protected: + /// attached OctreeEditPacketSender that handles queuing and sending of packets to VS + OctreeEditPacketSender* _packetSender; + JurisdictionListener* _jurisdictionListener; + bool _managedPacketSender; + bool _managedJuridiciontListerner; +}; + +#endif /* defined(__hifi__OctreeScriptingInterface__) */ diff --git a/libraries/particles/src/ParticleEditPacketSender.h b/libraries/particles/src/ParticleEditPacketSender.h index b5d9ac45ca..6a21ca3ae2 100644 --- a/libraries/particles/src/ParticleEditPacketSender.h +++ b/libraries/particles/src/ParticleEditPacketSender.h @@ -15,7 +15,7 @@ #include "Particle.h" /// Utility for processing, packing, queueing and sending of outbound edit voxel messages. -class ParticleEditPacketSender : public virtual OctreeEditPacketSender { +class ParticleEditPacketSender : public OctreeEditPacketSender { public: ParticleEditPacketSender(PacketSenderNotify* notify = NULL) : OctreeEditPacketSender(notify) { } ~ParticleEditPacketSender() { } diff --git a/libraries/particles/src/ParticleScriptingInterface.cpp b/libraries/particles/src/ParticleScriptingInterface.cpp index 74640fa671..cb534cc522 100644 --- a/libraries/particles/src/ParticleScriptingInterface.cpp +++ b/libraries/particles/src/ParticleScriptingInterface.cpp @@ -8,53 +8,10 @@ #include "ParticleScriptingInterface.h" -ParticleScriptingInterface::ParticleScriptingInterface(ParticleEditPacketSender* particleSender, - JurisdictionListener* particleJurisdictionListener) : - _nextCreatorTokenID(0) -{ - setParticlePacketSender(particleSender); - setJurisdictionListener(particleJurisdictionListener); -} - -ParticleScriptingInterface::~ParticleScriptingInterface() { - if (_managedJuridiciontListerner) { - delete _jurisdictionListener; - } - if (_managedPacketSender) { - delete _particlePacketSender; - } -} - - -void ParticleScriptingInterface::setParticlePacketSender(ParticleEditPacketSender* particlePacketSender) { - _particlePacketSender = particlePacketSender; -} - -void ParticleScriptingInterface::setJurisdictionListener(JurisdictionListener* jurisdictionListener) { - _jurisdictionListener = jurisdictionListener; -} - -void ParticleScriptingInterface::init() { - if (_jurisdictionListener) { - _managedJuridiciontListerner = false; - } else { - _managedJuridiciontListerner = true; - _jurisdictionListener = new JurisdictionListener(NODE_TYPE_PARTICLE_SERVER); - _jurisdictionListener->initialize(true); - } - - if (_particlePacketSender) { - _managedPacketSender = false; - } else { - _managedPacketSender = true; - _particlePacketSender = new ParticleEditPacketSender(); - _particlePacketSender->setServerJurisdictions(_jurisdictionListener->getJurisdictions()); - } -} void ParticleScriptingInterface::queueParticleAdd(PACKET_TYPE addPacketType, ParticleDetail& addParticleDetails) { - _particlePacketSender->queueParticleEditMessages(addPacketType, 1, &addParticleDetails); + getParticlePacketSender()->queueParticleEditMessages(addPacketType, 1, &addParticleDetails); } unsigned int ParticleScriptingInterface::queueParticleAdd(glm::vec3 position, float radius, diff --git a/libraries/particles/src/ParticleScriptingInterface.h b/libraries/particles/src/ParticleScriptingInterface.h index 0aaec977db..85dd0c6caf 100644 --- a/libraries/particles/src/ParticleScriptingInterface.h +++ b/libraries/particles/src/ParticleScriptingInterface.h @@ -12,86 +12,24 @@ #include #include +#include #include "ParticleEditPacketSender.h" /// handles scripting of Particle commands from JS passed to assigned clients -class ParticleScriptingInterface : public QObject { +class ParticleScriptingInterface : public OctreeScriptingInterface { Q_OBJECT public: - ParticleScriptingInterface(ParticleEditPacketSender* particleSender = NULL, - JurisdictionListener* particleJurisdictionListener = NULL); + ParticleEditPacketSender* getParticlePacketSender() const { return (ParticleEditPacketSender*)getPacketSender(); } + virtual NODE_TYPE getServerNodeType() const { return NODE_TYPE_PARTICLE_SERVER; } + virtual OctreeEditPacketSender* createPacketSender() { return new ParticleEditPacketSender(); } - ~ParticleScriptingInterface(); - - ParticleEditPacketSender* getParticlePacketSender() const { return _particlePacketSender; } - JurisdictionListener* getJurisdictionListener() const { return _jurisdictionListener; } - void setParticlePacketSender(ParticleEditPacketSender* particlePacketSender); - void setJurisdictionListener(JurisdictionListener* jurisdictionListener); - void init(); public slots: /// queues the creation of a Particle which will be sent by calling process on the PacketSender /// returns the creatorTokenID for the newly created particle unsigned int queueParticleAdd(glm::vec3 position, float radius, xColor color, glm::vec3 velocity, glm::vec3 gravity, float damping, QString updateScript); - - /// Set the desired max packet size in bytes that should be created - void setMaxPacketSize(int maxPacketSize) { return _particlePacketSender->setMaxPacketSize(maxPacketSize); } - - /// returns the current desired max packet size in bytes that will be created - int getMaxPacketSize() const { return _particlePacketSender->getMaxPacketSize(); } - - /// set the max packets per second send rate - void setPacketsPerSecond(int packetsPerSecond) { return _particlePacketSender->setPacketsPerSecond(packetsPerSecond); } - - /// get the max packets per second send rate - int getPacketsPerSecond() const { return _particlePacketSender->getPacketsPerSecond(); } - - /// does a particle server exist to send to - bool serversExist() const { return _particlePacketSender->serversExist(); } - - /// are there packets waiting in the send queue to be sent - bool hasPacketsToSend() const { return _particlePacketSender->hasPacketsToSend(); } - - /// how many packets are there in the send queue waiting to be sent - int packetsToSendCount() const { return _particlePacketSender->packetsToSendCount(); } - - /// returns the packets per second send rate of this object over its lifetime - float getLifetimePPS() const { return _particlePacketSender->getLifetimePPS(); } - - /// returns the bytes per second send rate of this object over its lifetime - float getLifetimeBPS() const { return _particlePacketSender->getLifetimeBPS(); } - - /// returns the packets per second queued rate of this object over its lifetime - float getLifetimePPSQueued() const { return _particlePacketSender->getLifetimePPSQueued(); } - - /// returns the bytes per second queued rate of this object over its lifetime - float getLifetimeBPSQueued() const { return _particlePacketSender->getLifetimeBPSQueued(); } - - /// returns lifetime of this object from first packet sent to now in usecs - long long unsigned int getLifetimeInUsecs() const { return _particlePacketSender->getLifetimeInUsecs(); } - - /// returns lifetime of this object from first packet sent to now in usecs - float getLifetimeInSeconds() const { return _particlePacketSender->getLifetimeInSeconds(); } - - /// returns the total packets sent by this object over its lifetime - long long unsigned int getLifetimePacketsSent() const { return _particlePacketSender->getLifetimePacketsSent(); } - - /// returns the total bytes sent by this object over its lifetime - long long unsigned int getLifetimeBytesSent() const { return _particlePacketSender->getLifetimeBytesSent(); } - - /// returns the total packets queued by this object over its lifetime - long long unsigned int getLifetimePacketsQueued() const { return _particlePacketSender->getLifetimePacketsQueued(); } - - /// returns the total bytes queued by this object over its lifetime - long long unsigned int getLifetimeBytesQueued() const { return _particlePacketSender->getLifetimeBytesQueued(); } private: - /// attached ParticleEditPacketSender that handles queuing and sending of packets to VS - ParticleEditPacketSender* _particlePacketSender; - JurisdictionListener* _jurisdictionListener; - bool _managedPacketSender; - bool _managedJuridiciontListerner; - void queueParticleAdd(PACKET_TYPE addPacketType, ParticleDetail& addParticleDetails); uint32_t _nextCreatorTokenID; diff --git a/libraries/voxels/src/VoxelEditPacketSender.h b/libraries/voxels/src/VoxelEditPacketSender.h index 1bfa4a2cec..d0ce018d95 100644 --- a/libraries/voxels/src/VoxelEditPacketSender.h +++ b/libraries/voxels/src/VoxelEditPacketSender.h @@ -14,7 +14,7 @@ #include /// Utility for processing, packing, queueing and sending of outbound edit voxel messages. -class VoxelEditPacketSender : public virtual OctreeEditPacketSender { +class VoxelEditPacketSender : public OctreeEditPacketSender { public: VoxelEditPacketSender(PacketSenderNotify* notify = NULL) : OctreeEditPacketSender(notify) { } ~VoxelEditPacketSender() { } diff --git a/libraries/voxels/src/VoxelScriptingInterface.cpp b/libraries/voxels/src/VoxelScriptingInterface.cpp index 90755f8c65..9c2ca45418 100644 --- a/libraries/voxels/src/VoxelScriptingInterface.cpp +++ b/libraries/voxels/src/VoxelScriptingInterface.cpp @@ -8,13 +8,8 @@ #include "VoxelScriptingInterface.h" -VoxelScriptingInterface::VoxelScriptingInterface() { - _jurisdictionListener.initialize(true); - _voxelPacketSender.setVoxelServerJurisdictions(_jurisdictionListener.getJurisdictions()); -} - void VoxelScriptingInterface::queueVoxelAdd(PACKET_TYPE addPacketType, VoxelDetail& addVoxelDetails) { - _voxelPacketSender.queueVoxelEditMessages(addPacketType, 1, &addVoxelDetails); + getVoxelPacketSender()->queueVoxelEditMessages(addPacketType, 1, &addVoxelDetails); } void VoxelScriptingInterface::queueVoxelAdd(float x, float y, float z, float scale, uchar red, uchar green, uchar blue) { @@ -39,6 +34,6 @@ void VoxelScriptingInterface::queueVoxelDelete(float x, float y, float z, float // setup a VoxelDetail struct with data VoxelDetail deleteVoxelDetail = {x, y, z, scale, 0, 0, 0}; - _voxelPacketSender.queueVoxelEditMessages(PACKET_TYPE_VOXEL_ERASE, 1, &deleteVoxelDetail); + getVoxelPacketSender()->queueVoxelEditMessages(PACKET_TYPE_VOXEL_ERASE, 1, &deleteVoxelDetail); } diff --git a/libraries/voxels/src/VoxelScriptingInterface.h b/libraries/voxels/src/VoxelScriptingInterface.h index aae05b8c70..db2835b7dd 100644 --- a/libraries/voxels/src/VoxelScriptingInterface.h +++ b/libraries/voxels/src/VoxelScriptingInterface.h @@ -12,16 +12,18 @@ #include #include +#include #include "VoxelEditPacketSender.h" /// handles scripting of voxel commands from JS passed to assigned clients -class VoxelScriptingInterface : public QObject { +class VoxelScriptingInterface : public OctreeScriptingInterface { Q_OBJECT public: - VoxelScriptingInterface(); - - VoxelEditPacketSender* getVoxelPacketSender() { return &_voxelPacketSender; } - JurisdictionListener* getJurisdictionListener() { return &_jurisdictionListener; } + VoxelEditPacketSender* getVoxelPacketSender() { return (VoxelEditPacketSender*)getPacketSender(); } + + virtual NODE_TYPE getServerNodeType() const { return NODE_TYPE_VOXEL_SERVER; } + virtual OctreeEditPacketSender* createPacketSender() { return new VoxelEditPacketSender(); } + public slots: /// queues the creation of a voxel which will be sent by calling process on the PacketSender /// \param x the x-coordinate of the voxel (in VS space) @@ -50,62 +52,7 @@ public slots: /// \param scale the scale of the voxel (in VS space) void queueVoxelDelete(float x, float y, float z, float scale); - /// Set the desired max packet size in bytes that should be created - void setMaxPacketSize(int maxPacketSize) { return _voxelPacketSender.setMaxPacketSize(maxPacketSize); } - - /// returns the current desired max packet size in bytes that will be created - int getMaxPacketSize() const { return _voxelPacketSender.getMaxPacketSize(); } - - /// set the max packets per second send rate - void setPacketsPerSecond(int packetsPerSecond) { return _voxelPacketSender.setPacketsPerSecond(packetsPerSecond); } - - /// get the max packets per second send rate - int getPacketsPerSecond() const { return _voxelPacketSender.getPacketsPerSecond(); } - - /// does a voxel server exist to send to - bool voxelServersExist() const { return _voxelPacketSender.voxelServersExist(); } - - /// are there packets waiting in the send queue to be sent - bool hasPacketsToSend() const { return _voxelPacketSender.hasPacketsToSend(); } - - /// how many packets are there in the send queue waiting to be sent - int packetsToSendCount() const { return _voxelPacketSender.packetsToSendCount(); } - - /// returns the packets per second send rate of this object over its lifetime - float getLifetimePPS() const { return _voxelPacketSender.getLifetimePPS(); } - - /// returns the bytes per second send rate of this object over its lifetime - float getLifetimeBPS() const { return _voxelPacketSender.getLifetimeBPS(); } - - /// returns the packets per second queued rate of this object over its lifetime - float getLifetimePPSQueued() const { return _voxelPacketSender.getLifetimePPSQueued(); } - - /// returns the bytes per second queued rate of this object over its lifetime - float getLifetimeBPSQueued() const { return _voxelPacketSender.getLifetimeBPSQueued(); } - - /// returns lifetime of this object from first packet sent to now in usecs - long long unsigned int getLifetimeInUsecs() const { return _voxelPacketSender.getLifetimeInUsecs(); } - - /// returns lifetime of this object from first packet sent to now in usecs - float getLifetimeInSeconds() const { return _voxelPacketSender.getLifetimeInSeconds(); } - - /// returns the total packets sent by this object over its lifetime - long long unsigned int getLifetimePacketsSent() const { return _voxelPacketSender.getLifetimePacketsSent(); } - - /// returns the total bytes sent by this object over its lifetime - long long unsigned int getLifetimeBytesSent() const { return _voxelPacketSender.getLifetimeBytesSent(); } - - /// returns the total packets queued by this object over its lifetime - long long unsigned int getLifetimePacketsQueued() const { return _voxelPacketSender.getLifetimePacketsQueued(); } - - /// returns the total bytes queued by this object over its lifetime - long long unsigned int getLifetimeBytesQueued() const { return _voxelPacketSender.getLifetimeBytesQueued(); } - private: - /// attached VoxelEditPacketSender that handles queuing and sending of packets to VS - VoxelEditPacketSender _voxelPacketSender; - JurisdictionListener _jurisdictionListener; - void queueVoxelAdd(PACKET_TYPE addPacketType, VoxelDetail& addVoxelDetails); }; From dacaade9ed45eae5cc306b1a85369a422720be4f Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 14 Dec 2013 13:54:25 -0800 Subject: [PATCH 04/17] first cut at client scripts working --- interface/src/Application.cpp | 16 +++++++++---- libraries/scriptengine/src/ScriptEngine.cpp | 26 ++++++++++++++++++++- libraries/scriptengine/src/ScriptEngine.h | 6 +++++ 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a93ba820dc..89170f94a6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4426,14 +4426,22 @@ void Application::loadScript() { // start the script on a new thread... _scriptEngine = new ScriptEngine(script); + // setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so + // we can use the same ones from the application. + _scriptEngine->getVoxelScriptingInterface()->setPacketSender(&_voxelEditSender); + _scriptEngine->getParticleScriptingInterface()->setPacketSender(&_particleEditSender); + + //_scriptEngine->getVoxelScriptingInterface()->setJurisdictionListener(); + //_scriptEngine->getParticleScriptingInterface()->setJurisdictionListener(); + QThread* workerThread = new QThread(this); connect(workerThread, SIGNAL(started()), _scriptEngine, SLOT(run())); - connect(_scriptEngine, SIGNAL(finished()), this, SLOT(assignmentCompleted())); - connect(_scriptEngine, SIGNAL(finished()), workerThread, SLOT(quit())); - connect(_scriptEngine, SIGNAL(finished()), _scriptEngine, SLOT(deleteLater())); - connect(_scriptEngine, SIGNAL(finished()), workerThread, SLOT(deleteLater())); + //connect(_scriptEngine, SIGNAL(finished()), this, SLOT(assignmentCompleted())); + //connect(_scriptEngine, SIGNAL(finished()), workerThread, SLOT(quit())); + //connect(_scriptEngine, SIGNAL(finished()), _scriptEngine, SLOT(deleteLater())); + //connect(_scriptEngine, SIGNAL(finished()), workerThread, SLOT(deleteLater())); _scriptEngine->moveToThread(workerThread); diff --git a/libraries/scriptengine/src/ScriptEngine.cpp b/libraries/scriptengine/src/ScriptEngine.cpp index 2768dd1ab5..d601ba6287 100644 --- a/libraries/scriptengine/src/ScriptEngine.cpp +++ b/libraries/scriptengine/src/ScriptEngine.cpp @@ -29,6 +29,9 @@ ScriptEngine::ScriptEngine(QString scriptContents) { void ScriptEngine::run() { QScriptEngine engine; + _voxelScriptingInterface.init(); + _particleScriptingInterface.init(); + // register meta-type for glm::vec3 conversions registerMetaTypes(&engine); @@ -76,7 +79,28 @@ void ScriptEngine::run() { QCoreApplication::processEvents(); - bool willSendVisualDataCallBack = true; + bool willSendVisualDataCallBack = false; + if (_voxelScriptingInterface.getVoxelPacketSender()->serversExist()) { + // allow the scripter's call back to setup visual data + willSendVisualDataCallBack = true; + + // release the queue of edit voxel messages. + _voxelScriptingInterface.getVoxelPacketSender()->releaseQueuedMessages(); + + // since we're in non-threaded mode, call process so that the packets are sent + //_voxelScriptingInterface.getVoxelPacketSender()->process(); + } + + if (_particleScriptingInterface.getParticlePacketSender()->serversExist()) { + // allow the scripter's call back to setup visual data + willSendVisualDataCallBack = true; + + // release the queue of edit voxel messages. + _particleScriptingInterface.getParticlePacketSender()->releaseQueuedMessages(); + + // since we're in non-threaded mode, call process so that the packets are sent + //_particleScriptingInterface.getParticlePacketSender()->process(); + } if (willSendVisualDataCallBack) { qDebug() << "willSendVisualDataCallback thisFrame:" << thisFrame << "\n"; diff --git a/libraries/scriptengine/src/ScriptEngine.h b/libraries/scriptengine/src/ScriptEngine.h index 21e9c9485c..725c920a8a 100644 --- a/libraries/scriptengine/src/ScriptEngine.h +++ b/libraries/scriptengine/src/ScriptEngine.h @@ -23,6 +23,12 @@ class ScriptEngine : public QObject { public: ScriptEngine(QString scriptContents); + /// Access the VoxelScriptingInterface in order to initialize it with a custom packet sender and jurisdiction listener + VoxelScriptingInterface* getVoxelScriptingInterface() { return &_voxelScriptingInterface; } + + /// Access the ParticleScriptingInterface in order to initialize it with a custom packet sender and jurisdiction listener + ParticleScriptingInterface* getParticleScriptingInterface() { return &_particleScriptingInterface; } + public slots: void run(); void stop() { From a220804fb0d22e807fa82c8a810f7830c0674c46 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 14 Dec 2013 14:23:33 -0800 Subject: [PATCH 05/17] properly connect signals and slots to shut down script properly, fix null termination in script file load --- interface/src/Application.cpp | 19 +++++++++++++------ libraries/scriptengine/src/ScriptEngine.cpp | 5 +++-- libraries/scriptengine/src/ScriptEngine.h | 1 - 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 89170f94a6..0804b3522c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4416,10 +4416,11 @@ void Application::loadScript() { file.seekg( 0, std::ios::beg ); // read the entire file into a buffer, WHAT!? Why not. - char* entireFile = new char[fileLength]; + char* entireFile = new char[fileLength+1]; file.read((char*)entireFile, fileLength); file.close(); + entireFile[fileLength] = 0;// null terminate QString script(entireFile); delete[] entireFile; @@ -4435,13 +4436,19 @@ void Application::loadScript() { //_scriptEngine->getParticleScriptingInterface()->setJurisdictionListener(); QThread* workerThread = new QThread(this); - + + // when the worker thread is started, call our engine's run.. connect(workerThread, SIGNAL(started()), _scriptEngine, SLOT(run())); - //connect(_scriptEngine, SIGNAL(finished()), this, SLOT(assignmentCompleted())); - //connect(_scriptEngine, SIGNAL(finished()), workerThread, SLOT(quit())); - //connect(_scriptEngine, SIGNAL(finished()), _scriptEngine, SLOT(deleteLater())); - //connect(_scriptEngine, SIGNAL(finished()), workerThread, SLOT(deleteLater())); + // when the engine emits finished, call our threads quit + connect(_scriptEngine, SIGNAL(finished()), workerThread, SLOT(quit())); + + // when the thread is terminated, add both _scriptEngine and thread to the deleteLater queue + connect(workerThread, SIGNAL(terminated()), _scriptEngine, SLOT(deleteLater())); + connect(workerThread, SIGNAL(terminated()), workerThread, SLOT(deleteLater())); + + // when the application is about to quit, stop our script engine so it unwinds properly + connect(this, SIGNAL(aboutToQuit()), _scriptEngine, SLOT(stop())); _scriptEngine->moveToThread(workerThread); diff --git a/libraries/scriptengine/src/ScriptEngine.cpp b/libraries/scriptengine/src/ScriptEngine.cpp index d601ba6287..0c486cb30f 100644 --- a/libraries/scriptengine/src/ScriptEngine.cpp +++ b/libraries/scriptengine/src/ScriptEngine.cpp @@ -52,6 +52,8 @@ void ScriptEngine::run() { // let the VoxelPacketSender know how frequently we plan to call it _voxelScriptingInterface.getVoxelPacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS); _particleScriptingInterface.getParticlePacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS); + + qDebug() << "Script:\n" << _scriptContents << "\n"; QScriptValue result = engine.evaluate(_scriptContents); qDebug() << "Evaluated script.\n"; @@ -112,7 +114,6 @@ void ScriptEngine::run() { int line = engine.uncaughtExceptionLineNumber(); qDebug() << "Uncaught exception at line" << line << ":" << engine.uncaughtException().toString() << "\n"; } - - } + emit finished(); } diff --git a/libraries/scriptengine/src/ScriptEngine.h b/libraries/scriptengine/src/ScriptEngine.h index 725c920a8a..9be9a5e0c0 100644 --- a/libraries/scriptengine/src/ScriptEngine.h +++ b/libraries/scriptengine/src/ScriptEngine.h @@ -33,7 +33,6 @@ public slots: void run(); void stop() { _isFinished = true; - emit finished(); } signals: From 3ca9cde500396d6710045245a030e5e64cae659d Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Mon, 16 Dec 2013 11:03:49 -0600 Subject: [PATCH 06/17] Adding build sequence to Interface build --- interface/CMakeLists.txt | 11 +++++++++++ interface/InterfaceConfig.h.in | 1 - interface/InterfaceVersion.h.in | 9 +++++++++ interface/src/Application.cpp | 3 +++ 4 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 interface/InterfaceVersion.h.in diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 31f6e74e5a..6d0817b0a3 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -17,6 +17,16 @@ set(OPENCV_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/OpenCV) set(SIXENSE_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/Sixense) set(UVCCAMERACONTROL_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/UVCCameraControl) +if (DEFINED ENV{JOB_ID}) + set(BUILD_SEQ $ENV{JOB_ID}) +else () + set(BUILD_SEQ "0") +endif () + +message("BUILD_SEQ = ${BUILD_SEQ}") + +set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} $ENV{QT_CMAKE_PREFIX_PATH}) + if (APPLE) set(GL_HEADERS "#include \n#include ") else (APPLE) @@ -35,6 +45,7 @@ include_glm(${TARGET_NAME} ${ROOT_DIR}) # create the InterfaceConfig.h file based on GL_HEADERS above configure_file(InterfaceConfig.h.in ${PROJECT_BINARY_DIR}/includes/InterfaceConfig.h) +configure_file(InterfaceVersion.h.in ${PROJECT_BINARY_DIR}/includes/InterfaceVersion.h) # grab the implementation and header files from src dirs file(GLOB INTERFACE_SRCS src/*.cpp src/*.h) diff --git a/interface/InterfaceConfig.h.in b/interface/InterfaceConfig.h.in index 802574434c..0b570f622f 100644 --- a/interface/InterfaceConfig.h.in +++ b/interface/InterfaceConfig.h.in @@ -12,5 +12,4 @@ #define GL_GLEXT_PROTOTYPES 1 @GL_HEADERS@ - #endif diff --git a/interface/InterfaceVersion.h.in b/interface/InterfaceVersion.h.in new file mode 100644 index 0000000000..b13c14bda6 --- /dev/null +++ b/interface/InterfaceVersion.h.in @@ -0,0 +1,9 @@ +// +// InterfaceVersion.h +// Declaration of version and buidl variables +// +// Created by Leonardo Murillo on 12/16/13. +// Copyright (c) 2013 High Fidelity, Inc.. All rights reserved. +// + +const int BUILD_VERSION = @BUILD_SEQ@; diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 90d7fdb22a..bf7fef57a5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -49,6 +49,7 @@ #include "Application.h" #include "DataServerClient.h" +#include "InterfaceVersion.h" #include "LogDisplay.h" #include "Menu.h" #include "Swatch.h" @@ -144,6 +145,8 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _applicationStartupTime = startup_time; _window->setWindowTitle("Interface"); + qDebug( "[VERSION] Build sequence: %i", BUILD_VERSION); + qInstallMessageHandler(messageHandler); unsigned int listenPort = 0; // bind to an ephemeral port by default From 7b9147fb6c4f984e335accff0a0136a855decb0e Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Mon, 16 Dec 2013 11:05:08 -0600 Subject: [PATCH 07/17] Tidy up --- interface/CMakeLists.txt | 2 -- interface/InterfaceVersion.h.in | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 6d0817b0a3..52e91a1489 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -23,8 +23,6 @@ else () set(BUILD_SEQ "0") endif () -message("BUILD_SEQ = ${BUILD_SEQ}") - set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} $ENV{QT_CMAKE_PREFIX_PATH}) if (APPLE) diff --git a/interface/InterfaceVersion.h.in b/interface/InterfaceVersion.h.in index b13c14bda6..26b2260965 100644 --- a/interface/InterfaceVersion.h.in +++ b/interface/InterfaceVersion.h.in @@ -1,6 +1,6 @@ // // InterfaceVersion.h -// Declaration of version and buidl variables +// Declaration of version and build data // // Created by Leonardo Murillo on 12/16/13. // Copyright (c) 2013 High Fidelity, Inc.. All rights reserved. From 524a41468cae6a9ddb6039984352be6e1f1a47cf Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 16 Dec 2013 09:16:51 -0800 Subject: [PATCH 08/17] multiple scripts running at same time, menu interface for scripts --- interface/src/Application.cpp | 33 +++++++---------- interface/src/Application.h | 2 -- interface/src/Menu.cpp | 8 +++++ interface/src/Menu.h | 21 +++++++---- libraries/particles/src/Particle.cpp | 2 +- libraries/scriptengine/src/ScriptEngine.cpp | 37 ++++++++++++++++---- libraries/scriptengine/src/ScriptEngine.h | 14 ++++++-- libraries/shared/src/AbstractMenuInterface.h | 29 +++++++++++++++ 8 files changed, 106 insertions(+), 40 deletions(-) create mode 100644 libraries/shared/src/AbstractMenuInterface.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 0804b3522c..dc57730aa0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -139,8 +139,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _recentMaxPackets(0), _resetRecentMaxPacketsSoon(true), _swatch(NULL), - _pasteMode(false), - _scriptEngine(NULL) + _pasteMode(false) { _applicationStartupTime = startup_time; _window->setWindowTitle("Interface"); @@ -259,7 +258,7 @@ Application::~Application() { _sharedVoxelSystem.changeTree(new VoxelTree); VoxelTreeElement::removeDeleteHook(&_voxels); // we don't need to do this processing on shutdown - delete Menu::getInstance(); + Menu::getInstance()->deleteLater(); delete _settings; delete _followMode; @@ -4388,12 +4387,6 @@ void Application::packetSentNotification(ssize_t length) { void Application::loadScript() { // shut down and stop any existing script - if (_scriptEngine) { - _scriptEngine->stop(); - _scriptEngine = NULL; - } - - QString desktopLocation = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); QString suggestedName = desktopLocation.append("/script.js"); @@ -4425,32 +4418,30 @@ void Application::loadScript() { delete[] entireFile; // start the script on a new thread... - _scriptEngine = new ScriptEngine(script); + bool wantMenuItems = true; // tells the ScriptEngine object to add menu items for itself + ScriptEngine* scriptEngine = new ScriptEngine(script, wantMenuItems, fileName, Menu::getInstance()); // setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so // we can use the same ones from the application. - _scriptEngine->getVoxelScriptingInterface()->setPacketSender(&_voxelEditSender); - _scriptEngine->getParticleScriptingInterface()->setPacketSender(&_particleEditSender); + scriptEngine->getVoxelScriptingInterface()->setPacketSender(&_voxelEditSender); + scriptEngine->getParticleScriptingInterface()->setPacketSender(&_particleEditSender); - //_scriptEngine->getVoxelScriptingInterface()->setJurisdictionListener(); - //_scriptEngine->getParticleScriptingInterface()->setJurisdictionListener(); - QThread* workerThread = new QThread(this); // when the worker thread is started, call our engine's run.. - connect(workerThread, SIGNAL(started()), _scriptEngine, SLOT(run())); + connect(workerThread, SIGNAL(started()), scriptEngine, SLOT(run())); // when the engine emits finished, call our threads quit - connect(_scriptEngine, SIGNAL(finished()), workerThread, SLOT(quit())); + connect(scriptEngine, SIGNAL(finished()), workerThread, SLOT(quit())); - // when the thread is terminated, add both _scriptEngine and thread to the deleteLater queue - connect(workerThread, SIGNAL(terminated()), _scriptEngine, SLOT(deleteLater())); + // when the thread is terminated, add both scriptEngine and thread to the deleteLater queue + connect(workerThread, SIGNAL(terminated()), scriptEngine, SLOT(deleteLater())); connect(workerThread, SIGNAL(terminated()), workerThread, SLOT(deleteLater())); // when the application is about to quit, stop our script engine so it unwinds properly - connect(this, SIGNAL(aboutToQuit()), _scriptEngine, SLOT(stop())); + connect(this, SIGNAL(aboutToQuit()), scriptEngine, SLOT(stop())); - _scriptEngine->moveToThread(workerThread); + scriptEngine->moveToThread(workerThread); // Starts an event loop, and emits workerThread->started() workerThread->start(); diff --git a/interface/src/Application.h b/interface/src/Application.h index 8b9127032f..df1e4bdeae 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -497,8 +497,6 @@ private: std::vector _voxelFades; std::vector _avatarFades; - - ScriptEngine* _scriptEngine; }; #endif /* defined(__interface__Application__) */ diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 44c04b685d..37dbbde6a3 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -92,6 +92,7 @@ Menu::Menu() : addDisabledActionAndSeparator(fileMenu, "Scripts"); addActionToQMenuAndActionHash(fileMenu, MenuOption::LoadScript, Qt::CTRL | Qt::Key_O, appInstance, SLOT(loadScript())); + _activeScriptsMenu = fileMenu->addMenu("Running Scripts"); addDisabledActionAndSeparator(fileMenu, "Voxels"); addActionToQMenuAndActionHash(fileMenu, MenuOption::ExportVoxels, Qt::CTRL | Qt::Key_E, appInstance, SLOT(exportVoxels())); @@ -709,6 +710,13 @@ QAction* Menu::addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu, return action; } +void Menu::removeAction(QMenu* menu, const QString& actionName) { +qDebug() << "removeAction() menu=" << menu << " actionName=" << actionName << "\n"; + + menu->removeAction(_actionHash.value(actionName)); +} + + bool Menu::isOptionChecked(const QString& menuOption) { return _actionHash.value(menuOption)->isChecked(); } diff --git a/interface/src/Menu.h b/interface/src/Menu.h index a1dce998bd..38a1a5e06e 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -13,6 +13,8 @@ #include #include +#include + enum FrustumDrawMode { FRUSTUM_DRAW_MODE_ALL, FRUSTUM_DRAW_MODE_VECTORS, @@ -37,7 +39,7 @@ class BandwidthDialog; class VoxelStatsDialog; class LodToolsDialog; -class Menu : public QMenuBar { +class Menu : public QMenuBar, public AbstractMenuInterface { Q_OBJECT public: static Menu* getInstance(); @@ -71,6 +73,15 @@ public: // User Tweakable PPS from Voxel Server int getMaxVoxelPacketsPerSecond() const { return _maxVoxelPacketsPerSecond; } + virtual QMenu* getActiveScriptsMenu() { return _activeScriptsMenu;} + virtual QAction* addActionToQMenuAndActionHash(QMenu* destinationMenu, + const QString actionName, + const QKeySequence& shortcut = 0, + const QObject* receiver = NULL, + const char* member = NULL, + QAction::MenuRole role = QAction::NoRole); + virtual void removeAction(QMenu* menu, const QString& actionName); + public slots: void bandwidthDetails(); void voxelStatsDetails(); @@ -110,12 +121,6 @@ private: /// helper method to have separators with labels that are also compatible with OS X void addDisabledActionAndSeparator(QMenu* destinationMenu, const QString& actionName); - QAction* addActionToQMenuAndActionHash(QMenu* destinationMenu, - const QString actionName, - const QKeySequence& shortcut = 0, - const QObject* receiver = NULL, - const char* member = NULL, - QAction::MenuRole role = QAction::NoRole); QAction* addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu, const QString actionName, @@ -141,6 +146,8 @@ private: int _boundaryLevelAdjust; QAction* _useVoxelShader; int _maxVoxelPacketsPerSecond; + + QMenu* _activeScriptsMenu; }; namespace MenuOption { diff --git a/libraries/particles/src/Particle.cpp b/libraries/particles/src/Particle.cpp index f66a05608a..d23815da3a 100644 --- a/libraries/particles/src/Particle.cpp +++ b/libraries/particles/src/Particle.cpp @@ -416,7 +416,7 @@ void Particle::update() { void Particle::runScript() { if (!_updateScript.isEmpty()) { - qDebug() << "Script: " << _updateScript << "\n"; + //qDebug() << "Script: " << _updateScript << "\n"; QScriptEngine engine; diff --git a/libraries/scriptengine/src/ScriptEngine.cpp b/libraries/scriptengine/src/ScriptEngine.cpp index 0c486cb30f..24c72aaf65 100644 --- a/libraries/scriptengine/src/ScriptEngine.cpp +++ b/libraries/scriptengine/src/ScriptEngine.cpp @@ -21,12 +21,40 @@ #include "ScriptEngine.h" -ScriptEngine::ScriptEngine(QString scriptContents) { +int ScriptEngine::_scriptNumber = 1; + +ScriptEngine::ScriptEngine(QString scriptContents, bool wantMenuItems, + const char* scriptMenuName, AbstractMenuInterface* menu) { _scriptContents = scriptContents; _isFinished = false; + _wantMenuItems = wantMenuItems; + if (scriptMenuName) { + _scriptMenuName = "Stop "; + _scriptMenuName.append(scriptMenuName); + } else { + _scriptMenuName = "Stop Script "; + _scriptNumber++; + _scriptMenuName.append(_scriptNumber); + } + _menu = menu; +} + +void ScriptEngine::setupMenuItems() { + if (_menu && _wantMenuItems) { + _menu->addActionToQMenuAndActionHash(_menu->getActiveScriptsMenu(), _scriptMenuName, 0, this, SLOT(stop())); + } +} + +void ScriptEngine::cleanMenuItems() { + if (_menu && _wantMenuItems) { + _menu->removeAction(_menu->getActiveScriptsMenu(), _scriptMenuName); + } } void ScriptEngine::run() { + + setupMenuItems(); + QScriptEngine engine; _voxelScriptingInterface.init(); @@ -68,12 +96,7 @@ void ScriptEngine::run() { int thisFrame = 0; - qDebug() << "before while... thisFrame:" << thisFrame << "\n"; - while (!_isFinished) { - - qDebug() << "while... thisFrame:" << thisFrame << "\n"; - int usecToSleep = usecTimestamp(&startTime) + (thisFrame++ * VISUAL_DATA_CALLBACK_USECS) - usecTimestampNow(); if (usecToSleep > 0) { usleep(usecToSleep); @@ -105,7 +128,6 @@ void ScriptEngine::run() { } if (willSendVisualDataCallBack) { - qDebug() << "willSendVisualDataCallback thisFrame:" << thisFrame << "\n"; emit willSendVisualDataCallback(); } @@ -115,5 +137,6 @@ void ScriptEngine::run() { qDebug() << "Uncaught exception at line" << line << ":" << engine.uncaughtException().toString() << "\n"; } } + cleanMenuItems(); emit finished(); } diff --git a/libraries/scriptengine/src/ScriptEngine.h b/libraries/scriptengine/src/ScriptEngine.h index 9be9a5e0c0..9047399c79 100644 --- a/libraries/scriptengine/src/ScriptEngine.h +++ b/libraries/scriptengine/src/ScriptEngine.h @@ -15,13 +15,15 @@ #include #include -#include +#include #include +#include class ScriptEngine : public QObject { Q_OBJECT public: - ScriptEngine(QString scriptContents); + ScriptEngine(QString scriptContents, bool wantMenuItems = false, + const char* scriptMenuName = NULL, AbstractMenuInterface* menu = NULL); /// Access the VoxelScriptingInterface in order to initialize it with a custom packet sender and jurisdiction listener VoxelScriptingInterface* getVoxelScriptingInterface() { return &_voxelScriptingInterface; } @@ -42,9 +44,17 @@ signals: protected: QString _scriptContents; bool _isFinished; + + void setupMenuItems(); + void cleanMenuItems(); + private: VoxelScriptingInterface _voxelScriptingInterface; ParticleScriptingInterface _particleScriptingInterface; + bool _wantMenuItems; + QString _scriptMenuName; + AbstractMenuInterface* _menu; + static int _scriptNumber; }; #endif /* defined(__hifi__ScriptEngine__) */ diff --git a/libraries/shared/src/AbstractMenuInterface.h b/libraries/shared/src/AbstractMenuInterface.h new file mode 100644 index 0000000000..6af0ea2d00 --- /dev/null +++ b/libraries/shared/src/AbstractMenuInterface.h @@ -0,0 +1,29 @@ +// +// AbstractMenuInterface.h +// hifi +// +// Created by Brad Hefta-Gaub on 12/16/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// +// + +#ifndef __hifi__AbstractMenuInterface__ +#define __hifi__AbstractMenuInterface__ + +#include +//#include +//#include + +class AbstractMenuInterface { +public: + virtual QMenu* getActiveScriptsMenu() = 0; + virtual QAction* addActionToQMenuAndActionHash(QMenu* destinationMenu, + const QString actionName, + const QKeySequence& shortcut = 0, + const QObject* receiver = NULL, + const char* member = NULL, + QAction::MenuRole role = QAction::NoRole) = 0; + virtual void removeAction(QMenu* menu, const QString& actionName) = 0; +}; + +#endif /* defined(__hifi__AbstractMenuInterface__) */ \ No newline at end of file From af52be78600054cc8468f10ab18b167bfbce8b8e Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 16 Dec 2013 09:32:01 -0800 Subject: [PATCH 09/17] tweaks to script engine shutdown behavior --- interface/src/Application.cpp | 6 ++++-- libraries/scriptengine/src/ScriptEngine.cpp | 9 +++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index dc57730aa0..a004f19238 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -263,6 +263,8 @@ Application::~Application() { delete _settings; delete _followMode; delete _glWidget; + + qDebug() << "DONE... Application::~Application()\n"; } void Application::restoreSizeAndPosition() { @@ -4435,8 +4437,8 @@ void Application::loadScript() { connect(scriptEngine, SIGNAL(finished()), workerThread, SLOT(quit())); // when the thread is terminated, add both scriptEngine and thread to the deleteLater queue - connect(workerThread, SIGNAL(terminated()), scriptEngine, SLOT(deleteLater())); - connect(workerThread, SIGNAL(terminated()), workerThread, SLOT(deleteLater())); + connect(workerThread, SIGNAL(finished()), scriptEngine, SLOT(deleteLater())); + connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater())); // when the application is about to quit, stop our script engine so it unwinds properly connect(this, SIGNAL(aboutToQuit()), scriptEngine, SLOT(stop())); diff --git a/libraries/scriptengine/src/ScriptEngine.cpp b/libraries/scriptengine/src/ScriptEngine.cpp index 24c72aaf65..62b729a1df 100644 --- a/libraries/scriptengine/src/ScriptEngine.cpp +++ b/libraries/scriptengine/src/ScriptEngine.cpp @@ -102,7 +102,15 @@ void ScriptEngine::run() { usleep(usecToSleep); } + if (_isFinished) { + break; + } + QCoreApplication::processEvents(); + + if (_isFinished) { + break; + } bool willSendVisualDataCallBack = false; if (_voxelScriptingInterface.getVoxelPacketSender()->serversExist()) { @@ -138,5 +146,6 @@ void ScriptEngine::run() { } } cleanMenuItems(); + qDebug() << "About to emit finished...\n"; emit finished(); } From f9b7c2385799caa19becc9b64188eae23614d1fe Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 16 Dec 2013 11:26:30 -0800 Subject: [PATCH 10/17] correct handleing of app shutdown and scripting enging termination --- interface/src/Application.cpp | 27 ++++++++++++----- interface/src/Menu.cpp | 2 -- .../octree/src/OctreeEditPacketSender.cpp | 2 ++ libraries/octree/src/OctreeEditPacketSender.h | 2 +- .../octree/src/OctreeScriptingInterface.cpp | 10 +++++++ libraries/scriptengine/src/ScriptEngine.cpp | 29 +++++++++++++++++-- libraries/scriptengine/src/ScriptEngine.h | 12 ++++---- libraries/shared/src/HifiSockAddr.cpp | 7 +++-- libraries/shared/src/PacketSender.cpp | 6 ++++ libraries/shared/src/PacketSender.h | 1 + 10 files changed, 79 insertions(+), 19 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a004f19238..1120b9d640 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -240,9 +240,15 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : // probably not the right long term solution. But for now, we're going to do this to // allow you to move a particle around in your hand _particleEditSender.setPacketsPerSecond(3000); // super high!! + + + printf("Application::Application() _voxelEditSender=%p\n", &_voxelEditSender); + printf("Application::Application() _particleEditSender=%p\n", &_particleEditSender); + } Application::~Application() { + qDebug() << "START Application::~Application()...\n"; // make sure we don't call the idle timer any more delete idleTimer; @@ -263,8 +269,7 @@ Application::~Application() { delete _settings; delete _followMode; delete _glWidget; - - qDebug() << "DONE... Application::~Application()\n"; + qDebug() << "DONE Application::~Application()...\n"; } void Application::restoreSizeAndPosition() { @@ -1395,6 +1400,7 @@ void Application::terminate() { pthread_join(_networkReceiveThread, NULL); } + printf(""); _voxelProcessor.terminate(); _voxelHideShowThread.terminate(); _voxelEditSender.terminate(); @@ -4421,33 +4427,40 @@ void Application::loadScript() { // start the script on a new thread... bool wantMenuItems = true; // tells the ScriptEngine object to add menu items for itself + + + qDebug("about to create ScriptEngine\n"); ScriptEngine* scriptEngine = new ScriptEngine(script, wantMenuItems, fileName, Menu::getInstance()); + qDebug("scriptEngine=%p\n",scriptEngine); + scriptEngine->setupMenuItems(); // setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so // we can use the same ones from the application. scriptEngine->getVoxelScriptingInterface()->setPacketSender(&_voxelEditSender); scriptEngine->getParticleScriptingInterface()->setPacketSender(&_particleEditSender); + qDebug("about to create workerThread\n"); QThread* workerThread = new QThread(this); + qDebug("workerThread=%p\n",workerThread); // when the worker thread is started, call our engine's run.. connect(workerThread, SIGNAL(started()), scriptEngine, SLOT(run())); - - // when the engine emits finished, call our threads quit - connect(scriptEngine, SIGNAL(finished()), workerThread, SLOT(quit())); // when the thread is terminated, add both scriptEngine and thread to the deleteLater queue - connect(workerThread, SIGNAL(finished()), scriptEngine, SLOT(deleteLater())); + connect(scriptEngine, SIGNAL(finished()), scriptEngine, SLOT(deleteLater())); connect(workerThread, SIGNAL(finished()), workerThread, SLOT(deleteLater())); // when the application is about to quit, stop our script engine so it unwinds properly connect(this, SIGNAL(aboutToQuit()), scriptEngine, SLOT(stop())); + qDebug("about to scriptEngine->moveToThread(workerThread)\n"); scriptEngine->moveToThread(workerThread); + qDebug("after scriptEngine->moveToThread(workerThread)\n"); // Starts an event loop, and emits workerThread->started() + qDebug("about to workerThread->start()\n"); workerThread->start(); - + qDebug("after workerThread->start()\n"); // restore the main window's active state diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 37dbbde6a3..97c83129ef 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -711,8 +711,6 @@ QAction* Menu::addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu, } void Menu::removeAction(QMenu* menu, const QString& actionName) { -qDebug() << "removeAction() menu=" << menu << " actionName=" << actionName << "\n"; - menu->removeAction(_actionHash.value(actionName)); } diff --git a/libraries/octree/src/OctreeEditPacketSender.cpp b/libraries/octree/src/OctreeEditPacketSender.cpp index 2d20e378cd..4333e18684 100644 --- a/libraries/octree/src/OctreeEditPacketSender.cpp +++ b/libraries/octree/src/OctreeEditPacketSender.cpp @@ -35,6 +35,7 @@ OctreeEditPacketSender::OctreeEditPacketSender(PacketSenderNotify* notify) : _serverJurisdictions(NULL), _sequenceNumber(0), _maxPacketSize(MAX_PACKET_SIZE) { + printf("OctreeEditPacketSender::OctreeEditPacketSender() [%p] created... \n", this); } OctreeEditPacketSender::~OctreeEditPacketSender() { @@ -48,6 +49,7 @@ OctreeEditPacketSender::~OctreeEditPacketSender() { delete packet; _preServerPackets.erase(_preServerPackets.begin()); } + printf("OctreeEditPacketSender::~OctreeEditPacketSender() [%p] destroyed... \n", this); } diff --git a/libraries/octree/src/OctreeEditPacketSender.h b/libraries/octree/src/OctreeEditPacketSender.h index d9fabf04a0..825c786a48 100644 --- a/libraries/octree/src/OctreeEditPacketSender.h +++ b/libraries/octree/src/OctreeEditPacketSender.h @@ -27,7 +27,7 @@ public: }; /// Utility for processing, packing, queueing and sending of outbound edit messages. -class OctreeEditPacketSender : public virtual PacketSender { +class OctreeEditPacketSender : public PacketSender { public: OctreeEditPacketSender(PacketSenderNotify* notify = NULL); ~OctreeEditPacketSender(); diff --git a/libraries/octree/src/OctreeScriptingInterface.cpp b/libraries/octree/src/OctreeScriptingInterface.cpp index 383e7a3877..e67aa9bd1c 100644 --- a/libraries/octree/src/OctreeScriptingInterface.cpp +++ b/libraries/octree/src/OctreeScriptingInterface.cpp @@ -16,10 +16,17 @@ OctreeScriptingInterface::OctreeScriptingInterface(OctreeEditPacketSender* packe } OctreeScriptingInterface::~OctreeScriptingInterface() { + printf("OctreeScriptingInterface::~OctreeScriptingInterface()\n"); if (_managedJuridiciontListerner) { + printf("OctreeScriptingInterface::~OctreeScriptingInterface() _managedJuridiciontListerner... _jurisdictionListener->terminate()\n"); + _jurisdictionListener->terminate(); + printf("OctreeScriptingInterface::~OctreeScriptingInterface() _managedJuridiciontListerner... deleting _jurisdictionListener\n"); delete _jurisdictionListener; } if (_managedPacketSender) { + printf("OctreeScriptingInterface::~OctreeScriptingInterface() _managedJuridiciontListerner... _packetSender->terminate()\n"); + _packetSender->terminate(); + printf("OctreeScriptingInterface::~OctreeScriptingInterface() _managedPacketSender... deleting _packetSender\n"); delete _packetSender; } } @@ -33,11 +40,13 @@ void OctreeScriptingInterface::setJurisdictionListener(JurisdictionListener* jur } void OctreeScriptingInterface::init() { + printf("OctreeScriptingInterface::init()\n"); if (_jurisdictionListener) { _managedJuridiciontListerner = false; } else { _managedJuridiciontListerner = true; _jurisdictionListener = new JurisdictionListener(getServerNodeType()); + printf("OctreeScriptingInterface::init() _managedJuridiciontListerner=true, creating _jurisdictionListener=%p\n", _jurisdictionListener); _jurisdictionListener->initialize(true); } @@ -46,6 +55,7 @@ void OctreeScriptingInterface::init() { } else { _managedPacketSender = true; _packetSender = createPacketSender(); + printf("OctreeScriptingInterface::init() _managedPacketSender=true, creating _packetSender=%p\n", _packetSender); _packetSender->setServerJurisdictions(_jurisdictionListener->getJurisdictions()); } } diff --git a/libraries/scriptengine/src/ScriptEngine.cpp b/libraries/scriptengine/src/ScriptEngine.cpp index 62b729a1df..c8df387e49 100644 --- a/libraries/scriptengine/src/ScriptEngine.cpp +++ b/libraries/scriptengine/src/ScriptEngine.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -39,6 +40,11 @@ ScriptEngine::ScriptEngine(QString scriptContents, bool wantMenuItems, _menu = menu; } +ScriptEngine::~ScriptEngine() { + printf("ScriptEngine::~ScriptEngine()...\n"); +} + + void ScriptEngine::setupMenuItems() { if (_menu && _wantMenuItems) { _menu->addActionToQMenuAndActionHash(_menu->getActiveScriptsMenu(), _scriptMenuName, 0, this, SLOT(stop())); @@ -53,7 +59,7 @@ void ScriptEngine::cleanMenuItems() { void ScriptEngine::run() { - setupMenuItems(); + //setupMenuItems(); QScriptEngine engine; @@ -103,12 +109,14 @@ void ScriptEngine::run() { } if (_isFinished) { + qDebug() << "line: " << __LINE__ << " _isFinished... breaking loop\n"; break; } QCoreApplication::processEvents(); if (_isFinished) { + qDebug() << "line: " << __LINE__ << " _isFinished... breaking loop\n"; break; } @@ -146,6 +154,23 @@ void ScriptEngine::run() { } } cleanMenuItems(); - qDebug() << "About to emit finished...\n"; + + // If we were on a thread, then wait till it's done + if (thread()) { + qDebug() << "line: " << __LINE__ << " calling quit()...\n"; + thread()->quit(); + } + + qDebug() << "line: " << __LINE__ << " emitting finished()...\n"; emit finished(); } + +void ScriptEngine::stop() { + _isFinished = true; + qDebug() << "line: " << __LINE__ << " ScriptEngine::stop().. setting _isFinished = true...\n"; +} + +void ScriptEngine::applicationAboutToQuit() { + qDebug() << "line: " << __LINE__ << " ScriptEngine::applicationAboutToQuit().. setting _isFinished = true...\n"; + stop(); +} diff --git a/libraries/scriptengine/src/ScriptEngine.h b/libraries/scriptengine/src/ScriptEngine.h index 9047399c79..03734f6820 100644 --- a/libraries/scriptengine/src/ScriptEngine.h +++ b/libraries/scriptengine/src/ScriptEngine.h @@ -24,18 +24,22 @@ class ScriptEngine : public QObject { public: ScriptEngine(QString scriptContents, bool wantMenuItems = false, const char* scriptMenuName = NULL, AbstractMenuInterface* menu = NULL); + + ~ScriptEngine(); /// Access the VoxelScriptingInterface in order to initialize it with a custom packet sender and jurisdiction listener VoxelScriptingInterface* getVoxelScriptingInterface() { return &_voxelScriptingInterface; } /// Access the ParticleScriptingInterface in order to initialize it with a custom packet sender and jurisdiction listener ParticleScriptingInterface* getParticleScriptingInterface() { return &_particleScriptingInterface; } + + void setupMenuItems(); + void cleanMenuItems(); public slots: void run(); - void stop() { - _isFinished = true; - } + void stop(); + void applicationAboutToQuit(); signals: void willSendAudioDataCallback(); @@ -45,8 +49,6 @@ protected: QString _scriptContents; bool _isFinished; - void setupMenuItems(); - void cleanMenuItems(); private: VoxelScriptingInterface _voxelScriptingInterface; diff --git a/libraries/shared/src/HifiSockAddr.cpp b/libraries/shared/src/HifiSockAddr.cpp index 0fdc8919ed..0a6f5dce2d 100644 --- a/libraries/shared/src/HifiSockAddr.cpp +++ b/libraries/shared/src/HifiSockAddr.cpp @@ -42,8 +42,11 @@ HifiSockAddr::HifiSockAddr(const QString& hostname, quint16 hostOrderPort) { } HifiSockAddr& HifiSockAddr::operator=(const HifiSockAddr& rhsSockAddr) { - HifiSockAddr temp(rhsSockAddr); - swap(temp); + //HifiSockAddr temp(rhsSockAddr); + //swap(temp); + _address = rhsSockAddr._address; + _port = rhsSockAddr._port; + return *this; } diff --git a/libraries/shared/src/PacketSender.cpp b/libraries/shared/src/PacketSender.cpp index f829a80ac0..45274a2a26 100644 --- a/libraries/shared/src/PacketSender.cpp +++ b/libraries/shared/src/PacketSender.cpp @@ -41,6 +41,11 @@ PacketSender::PacketSender(PacketSenderNotify* notify, int packetsPerSecond) : _totalPacketsQueued(0), _totalBytesQueued(0) { + printf("PacketSender[%p] created... \n", this); +} + +PacketSender::~PacketSender() { + printf("PacketSender::~PacketSender[%p] destroyed... \n", this); } @@ -328,6 +333,7 @@ bool PacketSender::nonThreadedProcess() { while ((packetsSentThisCall < packetsToSendThisCall) && (packetsLeft > 0)) { lock(); NetworkPacket& packet = _packets.front(); + printf("PacketSender[%p], copying packet... \n", this); NetworkPacket temporary = packet; // make a copy _packets.erase(_packets.begin()); packetsLeft = _packets.size(); diff --git a/libraries/shared/src/PacketSender.h b/libraries/shared/src/PacketSender.h index b05e42d11b..32b8c2c3a7 100644 --- a/libraries/shared/src/PacketSender.h +++ b/libraries/shared/src/PacketSender.h @@ -36,6 +36,7 @@ public: static const int MINIMAL_SLEEP_INTERVAL; PacketSender(PacketSenderNotify* notify = NULL, int packetsPerSecond = DEFAULT_PACKETS_PER_SECOND); + ~PacketSender(); /// Add packet to outbound queue. /// \param HifiSockAddr& address the destination address From 06d14436bd986b77a04594f2cb6f56fa81690885 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Mon, 16 Dec 2013 13:29:17 -0600 Subject: [PATCH 11/17] Printing build version on title --- interface/src/Application.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index bf7fef57a5..291086a478 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4106,12 +4106,14 @@ void Application::attachNewHeadToNode(Node* newNode) { void Application::updateWindowTitle(){ QString title = ""; + QString buildVersion = " (build " + QString::number(BUILD_VERSION) + ")"; QString username = _profile.getUsername(); if(!username.isEmpty()){ - title += _profile.getUsername(); + title += _profile.getUsername();s title += " @ "; } title += _profile.getLastDomain(); + title += buildVersion; qDebug("Application title set to: %s.\n", title.toStdString().c_str()); _window->setWindowTitle(title); From 5ac125fdd88f64dab4c848602d6c221c0ca2375b Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Mon, 16 Dec 2013 13:32:12 -0600 Subject: [PATCH 12/17] Typo fix --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 291086a478..942cf998d9 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4109,7 +4109,7 @@ void Application::updateWindowTitle(){ QString buildVersion = " (build " + QString::number(BUILD_VERSION) + ")"; QString username = _profile.getUsername(); if(!username.isEmpty()){ - title += _profile.getUsername();s + title += _profile.getUsername(); title += " @ "; } title += _profile.getLastDomain(); From 32c2aef29bb50b01e52789d9de1de4275756752f Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 16 Dec 2013 11:36:19 -0800 Subject: [PATCH 13/17] temp remove debug verbosity --- interface/src/Application.cpp | 11 ----------- libraries/octree/src/OctreeEditPacketSender.cpp | 4 ++-- .../octree/src/OctreeScriptingInterface.cpp | 16 ++++++++-------- libraries/scriptengine/src/ScriptEngine.cpp | 15 ++++----------- libraries/scriptengine/src/ScriptEngine.h | 1 - libraries/shared/src/PacketSender.cpp | 5 ++--- 6 files changed, 16 insertions(+), 36 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1120b9d640..eff2af5c1c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -248,7 +248,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : } Application::~Application() { - qDebug() << "START Application::~Application()...\n"; // make sure we don't call the idle timer any more delete idleTimer; @@ -269,7 +268,6 @@ Application::~Application() { delete _settings; delete _followMode; delete _glWidget; - qDebug() << "DONE Application::~Application()...\n"; } void Application::restoreSizeAndPosition() { @@ -4429,9 +4427,7 @@ void Application::loadScript() { bool wantMenuItems = true; // tells the ScriptEngine object to add menu items for itself - qDebug("about to create ScriptEngine\n"); ScriptEngine* scriptEngine = new ScriptEngine(script, wantMenuItems, fileName, Menu::getInstance()); - qDebug("scriptEngine=%p\n",scriptEngine); scriptEngine->setupMenuItems(); // setup the packet senders and jurisdiction listeners of the script engine's scripting interfaces so @@ -4439,9 +4435,7 @@ void Application::loadScript() { scriptEngine->getVoxelScriptingInterface()->setPacketSender(&_voxelEditSender); scriptEngine->getParticleScriptingInterface()->setPacketSender(&_particleEditSender); - qDebug("about to create workerThread\n"); QThread* workerThread = new QThread(this); - qDebug("workerThread=%p\n",workerThread); // when the worker thread is started, call our engine's run.. connect(workerThread, SIGNAL(started()), scriptEngine, SLOT(run())); @@ -4453,15 +4447,10 @@ void Application::loadScript() { // when the application is about to quit, stop our script engine so it unwinds properly connect(this, SIGNAL(aboutToQuit()), scriptEngine, SLOT(stop())); - qDebug("about to scriptEngine->moveToThread(workerThread)\n"); scriptEngine->moveToThread(workerThread); - qDebug("after scriptEngine->moveToThread(workerThread)\n"); // Starts an event loop, and emits workerThread->started() - qDebug("about to workerThread->start()\n"); workerThread->start(); - qDebug("after workerThread->start()\n"); - // restore the main window's active state _window->activateWindow(); diff --git a/libraries/octree/src/OctreeEditPacketSender.cpp b/libraries/octree/src/OctreeEditPacketSender.cpp index 4333e18684..752f7870df 100644 --- a/libraries/octree/src/OctreeEditPacketSender.cpp +++ b/libraries/octree/src/OctreeEditPacketSender.cpp @@ -35,7 +35,7 @@ OctreeEditPacketSender::OctreeEditPacketSender(PacketSenderNotify* notify) : _serverJurisdictions(NULL), _sequenceNumber(0), _maxPacketSize(MAX_PACKET_SIZE) { - printf("OctreeEditPacketSender::OctreeEditPacketSender() [%p] created... \n", this); + //printf("OctreeEditPacketSender::OctreeEditPacketSender() [%p] created... \n", this); } OctreeEditPacketSender::~OctreeEditPacketSender() { @@ -49,7 +49,7 @@ OctreeEditPacketSender::~OctreeEditPacketSender() { delete packet; _preServerPackets.erase(_preServerPackets.begin()); } - printf("OctreeEditPacketSender::~OctreeEditPacketSender() [%p] destroyed... \n", this); + //printf("OctreeEditPacketSender::~OctreeEditPacketSender() [%p] destroyed... \n", this); } diff --git a/libraries/octree/src/OctreeScriptingInterface.cpp b/libraries/octree/src/OctreeScriptingInterface.cpp index e67aa9bd1c..c324b94b3b 100644 --- a/libraries/octree/src/OctreeScriptingInterface.cpp +++ b/libraries/octree/src/OctreeScriptingInterface.cpp @@ -16,17 +16,17 @@ OctreeScriptingInterface::OctreeScriptingInterface(OctreeEditPacketSender* packe } OctreeScriptingInterface::~OctreeScriptingInterface() { - printf("OctreeScriptingInterface::~OctreeScriptingInterface()\n"); + //printf("OctreeScriptingInterface::~OctreeScriptingInterface()\n"); if (_managedJuridiciontListerner) { - printf("OctreeScriptingInterface::~OctreeScriptingInterface() _managedJuridiciontListerner... _jurisdictionListener->terminate()\n"); + //printf("OctreeScriptingInterface::~OctreeScriptingInterface() _managedJuridiciontListerner... _jurisdictionListener->terminate()\n"); _jurisdictionListener->terminate(); - printf("OctreeScriptingInterface::~OctreeScriptingInterface() _managedJuridiciontListerner... deleting _jurisdictionListener\n"); + //printf("OctreeScriptingInterface::~OctreeScriptingInterface() _managedJuridiciontListerner... deleting _jurisdictionListener\n"); delete _jurisdictionListener; } if (_managedPacketSender) { - printf("OctreeScriptingInterface::~OctreeScriptingInterface() _managedJuridiciontListerner... _packetSender->terminate()\n"); + //printf("OctreeScriptingInterface::~OctreeScriptingInterface() _managedJuridiciontListerner... _packetSender->terminate()\n"); _packetSender->terminate(); - printf("OctreeScriptingInterface::~OctreeScriptingInterface() _managedPacketSender... deleting _packetSender\n"); + //printf("OctreeScriptingInterface::~OctreeScriptingInterface() _managedPacketSender... deleting _packetSender\n"); delete _packetSender; } } @@ -40,13 +40,13 @@ void OctreeScriptingInterface::setJurisdictionListener(JurisdictionListener* jur } void OctreeScriptingInterface::init() { - printf("OctreeScriptingInterface::init()\n"); + //printf("OctreeScriptingInterface::init()\n"); if (_jurisdictionListener) { _managedJuridiciontListerner = false; } else { _managedJuridiciontListerner = true; _jurisdictionListener = new JurisdictionListener(getServerNodeType()); - printf("OctreeScriptingInterface::init() _managedJuridiciontListerner=true, creating _jurisdictionListener=%p\n", _jurisdictionListener); + //printf("OctreeScriptingInterface::init() _managedJuridiciontListerner=true, creating _jurisdictionListener=%p\n", _jurisdictionListener); _jurisdictionListener->initialize(true); } @@ -55,7 +55,7 @@ void OctreeScriptingInterface::init() { } else { _managedPacketSender = true; _packetSender = createPacketSender(); - printf("OctreeScriptingInterface::init() _managedPacketSender=true, creating _packetSender=%p\n", _packetSender); + //printf("OctreeScriptingInterface::init() _managedPacketSender=true, creating _packetSender=%p\n", _packetSender); _packetSender->setServerJurisdictions(_jurisdictionListener->getJurisdictions()); } } diff --git a/libraries/scriptengine/src/ScriptEngine.cpp b/libraries/scriptengine/src/ScriptEngine.cpp index c8df387e49..fe86924e57 100644 --- a/libraries/scriptengine/src/ScriptEngine.cpp +++ b/libraries/scriptengine/src/ScriptEngine.cpp @@ -41,7 +41,7 @@ ScriptEngine::ScriptEngine(QString scriptContents, bool wantMenuItems, } ScriptEngine::~ScriptEngine() { - printf("ScriptEngine::~ScriptEngine()...\n"); + //printf("ScriptEngine::~ScriptEngine()...\n"); } @@ -87,7 +87,7 @@ void ScriptEngine::run() { _voxelScriptingInterface.getVoxelPacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS); _particleScriptingInterface.getParticlePacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS); - qDebug() << "Script:\n" << _scriptContents << "\n"; + //qDebug() << "Script:\n" << _scriptContents << "\n"; QScriptValue result = engine.evaluate(_scriptContents); qDebug() << "Evaluated script.\n"; @@ -109,14 +109,14 @@ void ScriptEngine::run() { } if (_isFinished) { - qDebug() << "line: " << __LINE__ << " _isFinished... breaking loop\n"; + //qDebug() << "line: " << __LINE__ << " _isFinished... breaking loop\n"; break; } QCoreApplication::processEvents(); if (_isFinished) { - qDebug() << "line: " << __LINE__ << " _isFinished... breaking loop\n"; + //qDebug() << "line: " << __LINE__ << " _isFinished... breaking loop\n"; break; } @@ -157,20 +157,13 @@ void ScriptEngine::run() { // If we were on a thread, then wait till it's done if (thread()) { - qDebug() << "line: " << __LINE__ << " calling quit()...\n"; thread()->quit(); } - qDebug() << "line: " << __LINE__ << " emitting finished()...\n"; emit finished(); } void ScriptEngine::stop() { _isFinished = true; - qDebug() << "line: " << __LINE__ << " ScriptEngine::stop().. setting _isFinished = true...\n"; } -void ScriptEngine::applicationAboutToQuit() { - qDebug() << "line: " << __LINE__ << " ScriptEngine::applicationAboutToQuit().. setting _isFinished = true...\n"; - stop(); -} diff --git a/libraries/scriptengine/src/ScriptEngine.h b/libraries/scriptengine/src/ScriptEngine.h index 03734f6820..74c9b55559 100644 --- a/libraries/scriptengine/src/ScriptEngine.h +++ b/libraries/scriptengine/src/ScriptEngine.h @@ -39,7 +39,6 @@ public: public slots: void run(); void stop(); - void applicationAboutToQuit(); signals: void willSendAudioDataCallback(); diff --git a/libraries/shared/src/PacketSender.cpp b/libraries/shared/src/PacketSender.cpp index 45274a2a26..08049a9904 100644 --- a/libraries/shared/src/PacketSender.cpp +++ b/libraries/shared/src/PacketSender.cpp @@ -41,11 +41,11 @@ PacketSender::PacketSender(PacketSenderNotify* notify, int packetsPerSecond) : _totalPacketsQueued(0), _totalBytesQueued(0) { - printf("PacketSender[%p] created... \n", this); + //printf("PacketSender[%p] created... \n", this); } PacketSender::~PacketSender() { - printf("PacketSender::~PacketSender[%p] destroyed... \n", this); + //printf("PacketSender::~PacketSender[%p] destroyed... \n", this); } @@ -333,7 +333,6 @@ bool PacketSender::nonThreadedProcess() { while ((packetsSentThisCall < packetsToSendThisCall) && (packetsLeft > 0)) { lock(); NetworkPacket& packet = _packets.front(); - printf("PacketSender[%p], copying packet... \n", this); NetworkPacket temporary = packet; // make a copy _packets.erase(_packets.begin()); packetsLeft = _packets.size(); From 4f1ff5b56683a7da6da97446eb73ebbc78ab0217 Mon Sep 17 00:00:00 2001 From: Leonardo Murillo Date: Mon, 16 Dec 2013 13:55:04 -0600 Subject: [PATCH 14/17] Using QStandardPaths for cache directory --- interface/src/Application.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 942cf998d9..267786edb9 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -218,9 +218,11 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : connect(silentNodeTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes())); silentNodeTimer->start(NODE_SILENCE_THRESHOLD_USECS / 1000); + QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation); + _networkAccessManager = new QNetworkAccessManager(this); QNetworkDiskCache* cache = new QNetworkDiskCache(_networkAccessManager); - cache->setCacheDirectory("interfaceCache"); + cache->setCacheDirectory(!cachePath.isEmpty() ? cachePath : "interfaceCache"); _networkAccessManager->setCache(cache); _window->setCentralWidget(_glWidget); From f8830ed9b123f105836783e1ae2da0136fa2f865 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 16 Dec 2013 12:04:16 -0800 Subject: [PATCH 15/17] cleaned up hand target code a bit --- interface/src/Menu.cpp | 10 +++--- interface/src/Menu.h | 2 ++ interface/src/avatar/Hand.cpp | 66 +++++++++++++++++++++++------------ 3 files changed, 52 insertions(+), 26 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 97c83129ef..15b5b0d365 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -361,11 +361,13 @@ Menu::Menu() : appInstance->getWebcam()->getGrabber(), SLOT(setDepthOnly(bool))); - QMenu* raveGloveOptionsMenu = developerMenu->addMenu("Hand Options"); + QMenu* handOptionsMenu = developerMenu->addMenu("Hand Options"); - addCheckableActionToQMenuAndActionHash(raveGloveOptionsMenu, MenuOption::SimulateLeapHand); - addCheckableActionToQMenuAndActionHash(raveGloveOptionsMenu, MenuOption::DisplayLeapHands, 0, true); - addCheckableActionToQMenuAndActionHash(raveGloveOptionsMenu, MenuOption::LeapDrive, 0, false); + addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::SimulateLeapHand); + addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayLeapHands, 0, true); + addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::LeapDrive, 0, false); + addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false); + addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::BallFromHand, 0, false); QMenu* trackingOptionsMenu = developerMenu->addMenu("Tracking Options"); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 38a1a5e06e..80775738bb 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -156,6 +156,7 @@ namespace MenuOption { const QString Avatars = "Avatars"; const QString Atmosphere = "Atmosphere"; const QString AutomaticallyAuditTree = "Automatically Audit Tree Stats"; + const QString BallFromHand = "Ball from Hand"; const QString Bandwidth = "Bandwidth Display"; const QString BandwidthDetails = "Bandwidth Details"; const QString ChatCircling = "Chat Circling"; @@ -174,6 +175,7 @@ namespace MenuOption { const QString DisableLowRes = "Disable Lower Resolution While Moving"; const QString DisplayFrustum = "Display Frustum"; const QString DisplayLeapHands = "Display Leap Hands"; + const QString DisplayHandTargets = "Display Hand Targets"; const QString DontRenderVoxels = "Don't call _voxels.render()"; const QString DontCallOpenGLForVoxels = "Don't call glDrawRangeElementsEXT() for Voxels"; const QString EnableOcclusionCulling = "Enable Occlusion Culling"; diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index ad1c3fbf50..0f503f6ad1 100755 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -72,10 +72,11 @@ void Hand::reset() { } void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, float deltaTime) { + bool ballFromHand = Menu::getInstance()->isOptionChecked(MenuOption::BallFromHand); int handID = palm.getSixenseID(); glm::vec3 targetPosition = palm.getPosition() / (float)TREE_SCALE; - float targetRadius = 0.25f / (float)TREE_SCALE; // (TOY_BALL_RADIUS * 4.0f) / (float)TREE_SCALE; + float targetRadius = (TOY_BALL_RADIUS * 4.0f) / (float)TREE_SCALE; const Particle* closestParticle = Application::getInstance()->getParticles() ->getTree()->findClosestParticle(targetPosition, targetRadius); @@ -100,8 +101,18 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f printf("particle ID:%d with TIP velocity=%f,%f,%f\n", closestParticle->getID(), newVelocity.x, newVelocity.y, newVelocity.z); + + + printf("particle ID:%d OLD position=%f,%f,%f\n", closestParticle->getID(), + closestParticle->getPosition().x, closestParticle->getPosition().y, closestParticle->getPosition().z); + glm::vec3 newPosition = closestParticle->getPosition(); + + newPosition += newVelocity; // move it as if it's already been moving in new direction + + printf("particle ID:%d NEW position=%f,%f,%f\n", closestParticle->getID(), + newPosition.x, newPosition.y, newPosition.z); - caughtParticle->updateParticle(closestParticle->getPosition(), + caughtParticle->updateParticle(newPosition, closestParticle->getRadius(), closestParticle->getXColor(), newVelocity, @@ -143,7 +154,7 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f // create the ball, call MakeParticle, and use the resulting ParticleEditHandle to // manage the newly created particle. // Create a particle on the particle server - glm::vec3 ballPosition = palm.getPosition(); + glm::vec3 ballPosition = ballFromHand ? palm.getPosition() : fingerTipPosition; _ballParticleEditHandles[handID] = Application::getInstance()->makeParticle( ballPosition / (float)TREE_SCALE, TOY_BALL_RADIUS / (float) TREE_SCALE, @@ -155,7 +166,7 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f } } else { // Ball is in hand - glm::vec3 ballPosition = palm.getPosition(); + glm::vec3 ballPosition = ballFromHand ? palm.getPosition() : fingerTipPosition; _ballParticleEditHandles[handID]->updateParticle(ballPosition / (float)TREE_SCALE, TOY_BALL_RADIUS / (float) TREE_SCALE, TOY_BALL_ON_SERVER_COLOR[_whichBallColor[handID]], @@ -169,7 +180,7 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f if (_toyBallInHand[handID]) { _toyBallInHand[handID] = false; - glm::vec3 ballPosition = palm.getPosition(); + glm::vec3 ballPosition = ballFromHand ? palm.getPosition() : fingerTipPosition; glm::vec3 handVelocity = palm.getRawVelocity(); glm::vec3 fingerTipVelocity = palm.getTipVelocity(); glm::quat avatarRotation = _owningAvatar->getOrientation(); @@ -439,20 +450,32 @@ void Hand::renderLeapHands() { glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); - for (size_t i = 0; i < getNumPalms(); ++i) { - PalmData& palm = getPalms()[i]; - if (!palm.isActive()) { - continue; + if (Menu::getInstance()->isOptionChecked(MenuOption::DisplayHandTargets)) { + for (size_t i = 0; i < getNumPalms(); ++i) { + PalmData& palm = getPalms()[i]; + if (!palm.isActive()) { + continue; + } + glm::vec3 targetPosition = palm.getPosition(); + float targetRadius = (TOY_BALL_RADIUS * 4.0f); + glPushMatrix(); + + const Particle* closestParticle = Application::getInstance()->getParticles() + ->getTree()->findClosestParticle(targetPosition / (float)TREE_SCALE, + targetRadius / (float)TREE_SCALE); + + // If we are hitting a particle then draw the target green, otherwise yellow + if (closestParticle) { + glColor4f(0,1,0, alpha); + } else { + glColor4f(1,1,0, alpha); + } + glTranslatef(targetPosition.x, targetPosition.y, targetPosition.z); + glutWireSphere(targetRadius, 20.0f, 20.0f); + glPopMatrix(); } - glm::vec3 targetPosition = palm.getPosition(); - float targetRadius = 0.25f; - glPushMatrix(); - glColor4f(1,1,0, alpha); - glTranslatef(targetPosition.x, targetPosition.y, targetPosition.z); - glutWireSphere(targetRadius, 20.0f, 20.0f); - glPopMatrix(); } - + glPushMatrix(); // Draw the leap balls for (size_t i = 0; i < _leapFingerTipBalls.size(); i++) { @@ -489,13 +512,12 @@ void Hand::renderLeapHands() { for (size_t i = 0; i < getNumPalms(); ++i) { PalmData& palm = getPalms()[i]; if (palm.isActive()) { - const float palmThickness = 0.05f; //0.02f; - //glColor4f(handColor.r, handColor.g, handColor.b, 0.25); - glColor4f(1.0, 0.0, 0.0, 0.25); + const float palmThickness = 0.02f; + glColor4f(handColor.r, handColor.g, handColor.b, 0.25); glm::vec3 tip = palm.getPosition(); glm::vec3 root = palm.getPosition() + palm.getNormal() * palmThickness; - const float radiusA = 0.25f; // 0.05f; - const float radiusB = 0.23f; // 0.03f; + const float radiusA = 0.05f; + const float radiusB = 0.03f; Avatar::renderJointConnectingCone(root, tip, radiusA, radiusB); } } From 540c2a77f9146953b9d7eba9c0e9318dedb96fc3 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 16 Dec 2013 12:13:36 -0800 Subject: [PATCH 16/17] fixed file banner --- libraries/scriptengine/src/ScriptEngine.cpp | 2 +- libraries/scriptengine/src/ScriptEngine.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/scriptengine/src/ScriptEngine.cpp b/libraries/scriptengine/src/ScriptEngine.cpp index fe86924e57..7e5f414dee 100644 --- a/libraries/scriptengine/src/ScriptEngine.cpp +++ b/libraries/scriptengine/src/ScriptEngine.cpp @@ -2,7 +2,7 @@ // Agent.cpp // hifi // -// Created by Stephen Birarda on 7/1/13. +// Created by Brad Hefta-Gaub on 12/14/13. // Copyright (c) 2013 HighFidelity, Inc. All rights reserved. // diff --git a/libraries/scriptengine/src/ScriptEngine.h b/libraries/scriptengine/src/ScriptEngine.h index 74c9b55559..772b0a146f 100644 --- a/libraries/scriptengine/src/ScriptEngine.h +++ b/libraries/scriptengine/src/ScriptEngine.h @@ -2,7 +2,7 @@ // ScriptEngine.h // hifi // -// Created by Stephen Birarda on 7/1/13. +// Created by Brad Hefta-Gaub on 12/14/13. // Copyright (c) 2013 HighFidelity, Inc. All rights reserved. // From 8f3997da192e545650569fcd400818fba3c38512 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 16 Dec 2013 15:03:45 -0800 Subject: [PATCH 17/17] use findSpherePenetration() which fixes target zone detection of particles --- libraries/particles/src/ParticleTree.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/particles/src/ParticleTree.cpp b/libraries/particles/src/ParticleTree.cpp index 2a0b261bef..e0fc3e972e 100644 --- a/libraries/particles/src/ParticleTree.cpp +++ b/libraries/particles/src/ParticleTree.cpp @@ -78,9 +78,12 @@ bool ParticleTree::findNearPointOperation(OctreeElement* element, void* extraDat FindNearPointArgs* args = static_cast(extraData); ParticleTreeElement* particleTreeElement = static_cast(element); + glm::vec3 penetration; + bool sphereIntersection = particleTreeElement->getAABox().findSpherePenetration(args->position, + args->targetRadius, penetration); // If this particleTreeElement contains the point, then search it... - if (particleTreeElement->getAABox().contains(args->position)) { + if (sphereIntersection) { const Particle* thisClosestParticle = particleTreeElement->getClosestParticle(args->position); // we may have gotten NULL back, meaning no particle was available