Merge branch 'master' of https://github.com/worklist/hifi into metavoxels

This commit is contained in:
Andrzej Kapolka 2013-12-16 13:44:44 -08:00
commit 6888dc4eeb
18 changed files with 215 additions and 81 deletions

View file

@ -17,6 +17,14 @@ set(OPENCV_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/OpenCV)
set(SIXENSE_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/Sixense) set(SIXENSE_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/Sixense)
set(UVCCAMERACONTROL_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/UVCCameraControl) 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 ()
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} $ENV{QT_CMAKE_PREFIX_PATH})
if (APPLE) if (APPLE)
set(GL_HEADERS "#include <GLUT/glut.h>\n#include <OpenGL/glext.h>") set(GL_HEADERS "#include <GLUT/glut.h>\n#include <OpenGL/glext.h>")
else (APPLE) else (APPLE)
@ -35,6 +43,7 @@ include_glm(${TARGET_NAME} ${ROOT_DIR})
# create the InterfaceConfig.h file based on GL_HEADERS above # create the InterfaceConfig.h file based on GL_HEADERS above
configure_file(InterfaceConfig.h.in ${PROJECT_BINARY_DIR}/includes/InterfaceConfig.h) 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 # grab the implementation and header files from src dirs
file(GLOB INTERFACE_SRCS src/*.cpp src/*.h) file(GLOB INTERFACE_SRCS src/*.cpp src/*.h)

View file

@ -12,5 +12,4 @@
#define GL_GLEXT_PROTOTYPES 1 #define GL_GLEXT_PROTOTYPES 1
@GL_HEADERS@ @GL_HEADERS@
#endif #endif

View file

@ -0,0 +1,9 @@
//
// InterfaceVersion.h
// Declaration of version and build data
//
// Created by Leonardo Murillo on 12/16/13.
// Copyright (c) 2013 High Fidelity, Inc.. All rights reserved.
//
const int BUILD_VERSION = @BUILD_SEQ@;

View file

@ -49,6 +49,7 @@
#include "Application.h" #include "Application.h"
#include "DataServerClient.h" #include "DataServerClient.h"
#include "InterfaceVersion.h"
#include "LogDisplay.h" #include "LogDisplay.h"
#include "Menu.h" #include "Menu.h"
#include "Swatch.h" #include "Swatch.h"
@ -144,6 +145,8 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
_applicationStartupTime = startup_time; _applicationStartupTime = startup_time;
_window->setWindowTitle("Interface"); _window->setWindowTitle("Interface");
qDebug( "[VERSION] Build sequence: %i", BUILD_VERSION);
qInstallMessageHandler(messageHandler); qInstallMessageHandler(messageHandler);
unsigned int listenPort = 0; // bind to an ephemeral port by default unsigned int listenPort = 0; // bind to an ephemeral port by default
@ -215,9 +218,11 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
connect(silentNodeTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes())); connect(silentNodeTimer, SIGNAL(timeout()), nodeList, SLOT(removeSilentNodes()));
silentNodeTimer->start(NODE_SILENCE_THRESHOLD_USECS / 1000); silentNodeTimer->start(NODE_SILENCE_THRESHOLD_USECS / 1000);
QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
_networkAccessManager = new QNetworkAccessManager(this); _networkAccessManager = new QNetworkAccessManager(this);
QNetworkDiskCache* cache = new QNetworkDiskCache(_networkAccessManager); QNetworkDiskCache* cache = new QNetworkDiskCache(_networkAccessManager);
cache->setCacheDirectory("interfaceCache"); cache->setCacheDirectory(!cachePath.isEmpty() ? cachePath : "interfaceCache");
_networkAccessManager->setCache(cache); _networkAccessManager->setCache(cache);
_window->setCentralWidget(_glWidget); _window->setCentralWidget(_glWidget);
@ -240,6 +245,9 @@ 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 // 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 // allow you to move a particle around in your hand
_particleEditSender.setPacketsPerSecond(3000); // super high!! _particleEditSender.setPacketsPerSecond(3000); // super high!!
// Set the sixense filtering
_sixenseManager.setFilter(Menu::getInstance()->isOptionChecked(MenuOption::FilterSixense));
} }
Application::~Application() { Application::~Application() {
@ -4119,12 +4127,14 @@ void Application::attachNewHeadToNode(Node* newNode) {
void Application::updateWindowTitle(){ void Application::updateWindowTitle(){
QString title = ""; QString title = "";
QString buildVersion = " (build " + QString::number(BUILD_VERSION) + ")";
QString username = _profile.getUsername(); QString username = _profile.getUsername();
if(!username.isEmpty()){ if(!username.isEmpty()){
title += _profile.getUsername(); title += _profile.getUsername();
title += " @ "; title += " @ ";
} }
title += _profile.getLastDomain(); title += _profile.getLastDomain();
title += buildVersion;
qDebug("Application title set to: %s.\n", title.toStdString().c_str()); qDebug("Application title set to: %s.\n", title.toStdString().c_str());
_window->setWindowTitle(title); _window->setWindowTitle(title);

View file

@ -152,6 +152,7 @@ public:
SerialInterface* getSerialHeadSensor() { return &_serialHeadSensor; } SerialInterface* getSerialHeadSensor() { return &_serialHeadSensor; }
Webcam* getWebcam() { return &_webcam; } Webcam* getWebcam() { return &_webcam; }
Faceshift* getFaceshift() { return &_faceshift; } Faceshift* getFaceshift() { return &_faceshift; }
SixenseManager* getSixenseManager() { return &_sixenseManager; }
BandwidthMeter* getBandwidthMeter() { return &_bandwidthMeter; } BandwidthMeter* getBandwidthMeter() { return &_bandwidthMeter; }
QSettings* getSettings() { return _settings; } QSettings* getSettings() { return _settings; }
Swatch* getSwatch() { return &_swatch; } Swatch* getSwatch() { return &_swatch; }

View file

@ -358,11 +358,17 @@ Menu::Menu() :
appInstance->getWebcam()->getGrabber(), appInstance->getWebcam()->getGrabber(),
SLOT(setDepthOnly(bool))); SLOT(setDepthOnly(bool)));
QMenu* raveGloveOptionsMenu = developerMenu->addMenu("Hand Options"); QMenu* handOptionsMenu = developerMenu->addMenu("Hand Options");
addCheckableActionToQMenuAndActionHash(raveGloveOptionsMenu, MenuOption::SimulateLeapHand); addCheckableActionToQMenuAndActionHash(handOptionsMenu,
addCheckableActionToQMenuAndActionHash(raveGloveOptionsMenu, MenuOption::DisplayLeapHands, 0, true); MenuOption::FilterSixense,
addCheckableActionToQMenuAndActionHash(raveGloveOptionsMenu, MenuOption::LeapDrive, 0, false); 0,
true,
appInstance->getSixenseManager(),
SLOT(setFilter(bool)));
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::SimulateLeapHand);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayLeapHands, 0, true);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::LeapDrive, 0, false);
QMenu* trackingOptionsMenu = developerMenu->addMenu("Tracking Options"); QMenu* trackingOptionsMenu = developerMenu->addMenu("Tracking Options");

View file

@ -167,6 +167,7 @@ namespace MenuOption {
const QString DisableLowRes = "Disable Lower Resolution While Moving"; const QString DisableLowRes = "Disable Lower Resolution While Moving";
const QString DisplayFrustum = "Display Frustum"; const QString DisplayFrustum = "Display Frustum";
const QString DisplayLeapHands = "Display Leap Hands"; const QString DisplayLeapHands = "Display Leap Hands";
const QString FilterSixense = "Smooth Sixense Movement";
const QString DontRenderVoxels = "Don't call _voxels.render()"; const QString DontRenderVoxels = "Don't call _voxels.render()";
const QString DontCallOpenGLForVoxels = "Don't call glDrawRangeElementsEXT() for Voxels"; const QString DontCallOpenGLForVoxels = "Don't call glDrawRangeElementsEXT() for Voxels";
const QString EnableOcclusionCulling = "Enable Occlusion Culling"; const QString EnableOcclusionCulling = "Enable Occlusion Culling";

View file

@ -24,11 +24,20 @@ const int TOY_BALL_HAND = 1;
const float TOY_BALL_RADIUS = 0.05f; const float TOY_BALL_RADIUS = 0.05f;
const float TOY_BALL_DAMPING = 0.99f; const float TOY_BALL_DAMPING = 0.99f;
const glm::vec3 NO_GRAVITY = glm::vec3(0,0,0); const glm::vec3 NO_GRAVITY = glm::vec3(0,0,0);
const glm::vec3 NO_VELOCITY = glm::vec3(0,0,0);
const glm::vec3 TOY_BALL_GRAVITY = glm::vec3(0,-1,0); const glm::vec3 TOY_BALL_GRAVITY = glm::vec3(0,-1,0);
const QString TOY_BALL_UPDATE_SCRIPT(""); const QString TOY_BALL_UPDATE_SCRIPT("");
const QString TOY_BALL_DONT_DIE_SCRIPT("Particle.setShouldDie(false);"); const QString TOY_BALL_DONT_DIE_SCRIPT("Particle.setShouldDie(false);");
const float PALM_COLLISION_RADIUS = 0.03f; const float PALM_COLLISION_RADIUS = 0.03f;
const xColor TOY_BALL_ON_SERVER_COLOR = { 255, 255, 0 }; const xColor TOY_BALL_ON_SERVER_COLOR[] =
{
{ 255, 0, 0 },
{ 0, 255, 0 },
{ 0, 0, 255 },
{ 255, 255, 0 },
{ 0, 255, 255 },
{ 255, 0, 255 },
};
Hand::Hand(Avatar* owningAvatar) : Hand::Hand(Avatar* owningAvatar) :
HandData((AvatarData*)owningAvatar), HandData((AvatarData*)owningAvatar),
@ -39,13 +48,16 @@ Hand::Hand(Avatar* owningAvatar) :
_collisionCenter(0,0,0), _collisionCenter(0,0,0),
_collisionAge(0), _collisionAge(0),
_collisionDuration(0), _collisionDuration(0),
_toyBallPosition(0), _pitchUpdate(0),
_toyBallVelocity(0), _grabDelta(0, 0, 0),
_toyBallInHand(false), _grabDeltaVelocity(0, 0, 0)
_hasToyBall(false),
_ballParticleEditHandle(NULL),
_pitchUpdate(0)
{ {
for (int i = 0; i < MAX_HANDS; i++) {
_toyBallInHand[i] = false;
_ballParticleEditHandles[i] = NULL;
_whichBallColor[i] = 0;
}
_lastControllerButtons = 0;
} }
void Hand::init() { void Hand::init() {
@ -62,14 +74,13 @@ void Hand::reset() {
} }
void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, float deltaTime) { void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, float deltaTime) {
glm::vec3 targetPosition = fingerTipPosition / (float)TREE_SCALE; glm::vec3 targetPosition = fingerTipPosition / (float)TREE_SCALE;
float targetRadius = (TOY_BALL_RADIUS * 2.0f) / (float)TREE_SCALE; float targetRadius = (TOY_BALL_RADIUS * 2.0f) / (float)TREE_SCALE;
const Particle* closestParticle = Application::getInstance()->getParticles() const Particle* closestParticle = Application::getInstance()->getParticles()
->getTree()->findClosestParticle(targetPosition, targetRadius); ->getTree()->findClosestParticle(targetPosition, targetRadius);
if (closestParticle) { if (closestParticle) {
printf("potentially caught... particle ID:%d\n", closestParticle->getID()); //printf("potentially caught... particle ID:%d\n", closestParticle->getID());
// you can create a ParticleEditHandle by doing this... // you can create a ParticleEditHandle by doing this...
ParticleEditHandle* caughtParticle = Application::getInstance()->newParticleEditHandle(closestParticle->getID()); ParticleEditHandle* caughtParticle = Application::getInstance()->newParticleEditHandle(closestParticle->getID());
@ -77,13 +88,22 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f
// but make sure you clean it up, when you're done // but make sure you clean it up, when you're done
delete caughtParticle; 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();
if (currentControllerButtons != _lastControllerButtons && (currentControllerButtons & BUTTON_0)) {
_whichBallColor[handID]++;
if (_whichBallColor[handID] >= sizeof(TOY_BALL_ON_SERVER_COLOR)/sizeof(TOY_BALL_ON_SERVER_COLOR[0])) {
_whichBallColor[handID] = 0;
}
}
// Is the controller button being held down.... // Is the controller button being held down....
if (palm.getControllerButtons() & BUTTON_FWD) { if (palm.getControllerButtons() & BUTTON_FWD) {
// If grabbing toy ball, add forces to it.
// If we don't currently have a ball in hand, then create it... // If we don't currently have a ball in hand, then create it...
if (!_toyBallInHand) { if (!_toyBallInHand[handID]) {
// Test for whether close enough to catch and catch.... // Test for whether close enough to catch and catch....
// isCaught is also used as "creating" a new ball... for now, this section is the // isCaught is also used as "creating" a new ball... for now, this section is the
@ -92,76 +112,78 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f
// If we didn't catch something, then create a new ball.... // If we didn't catch something, then create a new ball....
if (!isCaught) { if (!isCaught) {
_toyBallInHand = true; _toyBallInHand[handID] = true;
_hasToyBall = true;
// create the ball, call MakeParticle, and use the resulting ParticleEditHandle to // create the ball, call MakeParticle, and use the resulting ParticleEditHandle to
// manage the newly created particle. // manage the newly created particle.
// Create a particle on the particle server // Create a particle on the particle server
_ballParticleEditHandle = Application::getInstance()->makeParticle(fingerTipPosition / (float)TREE_SCALE, _ballParticleEditHandles[handID] = Application::getInstance()->makeParticle(
TOY_BALL_RADIUS / (float) TREE_SCALE, fingerTipPosition / (float)TREE_SCALE,
TOY_BALL_ON_SERVER_COLOR, TOY_BALL_RADIUS / (float) TREE_SCALE,
_toyBallVelocity / (float)TREE_SCALE, TOY_BALL_ON_SERVER_COLOR[_whichBallColor[handID]],
NO_GRAVITY / (float) TREE_SCALE, NO_VELOCITY / (float)TREE_SCALE,
TOY_BALL_DAMPING, NO_GRAVITY / (float) TREE_SCALE,
TOY_BALL_DONT_DIE_SCRIPT); TOY_BALL_DAMPING,
TOY_BALL_DONT_DIE_SCRIPT);
} }
} } else {
if (_toyBallInHand) {
// Ball is in hand // Ball is in hand
_toyBallPosition = fingerTipPosition; _ballParticleEditHandles[handID]->updateParticle(fingerTipPosition / (float)TREE_SCALE,
_toyBallVelocity = glm::vec3(0);
_ballParticleEditHandle->updateParticle(fingerTipPosition / (float)TREE_SCALE,
TOY_BALL_RADIUS / (float) TREE_SCALE, TOY_BALL_RADIUS / (float) TREE_SCALE,
TOY_BALL_ON_SERVER_COLOR, TOY_BALL_ON_SERVER_COLOR[_whichBallColor[handID]],
_toyBallVelocity / (float)TREE_SCALE, NO_VELOCITY / (float)TREE_SCALE,
NO_GRAVITY / (float) TREE_SCALE, NO_GRAVITY / (float) TREE_SCALE,
TOY_BALL_DAMPING, TOY_BALL_DAMPING,
TOY_BALL_DONT_DIE_SCRIPT); TOY_BALL_DONT_DIE_SCRIPT);
} }
} else { } else {
// If toy ball just released, add velocity to it! // If toy ball just released, add velocity to it!
if (_toyBallInHand) { if (_toyBallInHand[handID]) {
_toyBallInHand = false; _toyBallInHand[handID] = false;
glm::vec3 handVelocity = palm.getRawVelocity(); glm::vec3 handVelocity = palm.getRawVelocity();
glm::vec3 fingerTipVelocity = palm.getTipVelocity(); glm::vec3 fingerTipVelocity = palm.getTipVelocity();
glm::quat avatarRotation = _owningAvatar->getOrientation(); glm::quat avatarRotation = _owningAvatar->getOrientation();
//printVector(avatarRotation * handVelocity); glm::vec3 toyBallVelocity = avatarRotation * fingerTipVelocity;
_toyBallVelocity += avatarRotation * fingerTipVelocity;
// ball is no longer in hand... // ball is no longer in hand...
_ballParticleEditHandle->updateParticle(fingerTipPosition / (float)TREE_SCALE, _ballParticleEditHandles[handID]->updateParticle(fingerTipPosition / (float)TREE_SCALE,
TOY_BALL_RADIUS / (float) TREE_SCALE, TOY_BALL_RADIUS / (float) TREE_SCALE,
TOY_BALL_ON_SERVER_COLOR, TOY_BALL_ON_SERVER_COLOR[_whichBallColor[handID]],
_toyBallVelocity / (float)TREE_SCALE, toyBallVelocity / (float)TREE_SCALE,
TOY_BALL_GRAVITY / (float) TREE_SCALE, TOY_BALL_GRAVITY / (float) TREE_SCALE,
TOY_BALL_DAMPING, TOY_BALL_DAMPING,
TOY_BALL_UPDATE_SCRIPT); TOY_BALL_UPDATE_SCRIPT);
// after releasing the ball, we free our ParticleEditHandle so we can't edit it further // after releasing the ball, we free our ParticleEditHandle so we can't edit it further
// note: deleting the edit handle doesn't effect the actual particle // note: deleting the edit handle doesn't effect the actual particle
delete _ballParticleEditHandle; delete _ballParticleEditHandles[handID];
_ballParticleEditHandle = NULL; _ballParticleEditHandles[handID] = NULL;
} }
} }
// Simulate toy ball
_toyBallPosition += _toyBallVelocity * deltaTime;
if (!_toyBallInHand) { // remember the last pressed button state
_toyBallVelocity += TOY_BALL_GRAVITY * deltaTime; if (currentControllerButtons != 0) {
} _lastControllerButtons = currentControllerButtons;
if (_toyBallPosition.y < 0.f) {
_toyBallPosition.y = 0.f;
_toyBallVelocity.y *= -1.f;
} }
}
glm::vec3 Hand::getAndResetGrabDelta() {
const float HAND_GRAB_SCALE_DISTANCE = 5.f;
glm::vec3 delta = _grabDelta * _owningAvatar->getScale() * HAND_GRAB_SCALE_DISTANCE;
_grabDelta = glm::vec3(0,0,0);
glm::quat avatarRotation = _owningAvatar->getOrientation();
return avatarRotation * -delta;
}
glm::vec3 Hand::getAndResetGrabDeltaVelocity() {
const float HAND_GRAB_SCALE_VELOCITY = 5.f;
glm::vec3 delta = _grabDeltaVelocity * _owningAvatar->getScale() * HAND_GRAB_SCALE_VELOCITY;
_grabDeltaVelocity = glm::vec3(0,0,0);
glm::quat avatarRotation = _owningAvatar->getOrientation();
return avatarRotation * -delta;
if (_hasToyBall) {
_toyBallVelocity -= (_toyBallVelocity * TOY_BALL_DAMPING) * deltaTime;
//printf("applying damping to TOY_BALL deltaTime=%f\n",deltaTime);
}
} }
void Hand::simulate(float deltaTime, bool isMine) { void Hand::simulate(float deltaTime, bool isMine) {
@ -192,8 +214,13 @@ void Hand::simulate(float deltaTime, bool isMine) {
FingerData& finger = palm.getFingers()[0]; // Sixense has only one finger FingerData& finger = palm.getFingers()[0]; // Sixense has only one finger
glm::vec3 fingerTipPosition = finger.getTipPosition(); glm::vec3 fingerTipPosition = finger.getTipPosition();
if (palm.getSixenseID() == TOY_BALL_HAND) { simulateToyBall(palm, fingerTipPosition, deltaTime);
simulateToyBall(palm, fingerTipPosition, deltaTime);
if (palm.getControllerButtons() & BUTTON_4) {
_grabDelta += palm.getRawVelocity() * deltaTime;
}
if ((palm.getLastControllerButtons() & BUTTON_4) && !(palm.getControllerButtons() & BUTTON_4)) {
_grabDeltaVelocity = palm.getRawVelocity();
} }
if (palm.getControllerButtons() & BUTTON_1) { if (palm.getControllerButtons() & BUTTON_1) {
@ -242,6 +269,7 @@ void Hand::simulate(float deltaTime, bool isMine) {
} }
} }
} }
palm.setLastControllerButtons(palm.getControllerButtons());
} }
} }
} }
@ -376,15 +404,6 @@ void Hand::render( bool isMine) {
renderLeapHands(); renderLeapHands();
} }
// Render toy ball
if (isMine && _hasToyBall) {
glPushMatrix();
glColor3f(1, 0, 0);
glTranslatef(_toyBallPosition.x, _toyBallPosition.y, _toyBallPosition.z);
glutWireSphere(TOY_BALL_RADIUS, 10, 10);
glPopMatrix();
}
if (isMine) { if (isMine) {
// If hand/voxel collision has happened, render a little expanding sphere // If hand/voxel collision has happened, render a little expanding sphere
if (_collisionAge > 0.f) { if (_collisionAge > 0.f) {

View file

@ -61,6 +61,10 @@ public:
const float getPitchUpdate() const { return _pitchUpdate; } const float getPitchUpdate() const { return _pitchUpdate; }
void setPitchUpdate(float pitchUpdate) { _pitchUpdate = pitchUpdate; } void setPitchUpdate(float pitchUpdate) { _pitchUpdate = pitchUpdate; }
// Get the drag distance to move
glm::vec3 getAndResetGrabDelta();
glm::vec3 getAndResetGrabDeltaVelocity();
private: private:
// disallow copies of the Hand, copy of owning Avatar is disallowed too // disallow copies of the Hand, copy of owning Avatar is disallowed too
Hand(const Hand&); Hand(const Hand&);
@ -95,14 +99,18 @@ private:
void handleVoxelCollision(PalmData* palm, const glm::vec3& fingerTipPosition, VoxelTreeElement* voxel, float deltaTime); void handleVoxelCollision(PalmData* palm, const glm::vec3& fingerTipPosition, VoxelTreeElement* voxel, float deltaTime);
void simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, float deltaTime); void simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, float deltaTime);
glm::vec3 _toyBallPosition; #define MAX_HANDS 2
glm::vec3 _toyBallVelocity; bool _toyBallInHand[MAX_HANDS];
bool _toyBallInHand; int _whichBallColor[MAX_HANDS];
bool _hasToyBall; ParticleEditHandle* _ballParticleEditHandles[MAX_HANDS];
ParticleEditHandle* _ballParticleEditHandle; int _lastControllerButtons;
float _pitchUpdate; float _pitchUpdate;
glm::vec3 _grabDelta;
glm::vec3 _grabDeltaVelocity;
}; };

View file

@ -271,6 +271,14 @@ void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) {
updateChatCircle(deltaTime); updateChatCircle(deltaTime);
// Get any position or velocity update from Grab controller
glm::vec3 moveFromGrab = _hand.getAndResetGrabDelta();
if (glm::length(moveFromGrab) > EPSILON) {
_position += moveFromGrab;
_velocity = glm::vec3(0, 0, 0);
}
_velocity += _hand.getAndResetGrabDeltaVelocity();
_position += _velocity * deltaTime; _position += _velocity * deltaTime;
// update avatar skeleton and simulate hand and head // update avatar skeleton and simulate hand and head

View file

@ -16,7 +16,6 @@
SixenseManager::SixenseManager() { SixenseManager::SixenseManager() {
#ifdef HAVE_SIXENSE #ifdef HAVE_SIXENSE
sixenseInit(); sixenseInit();
sixenseSetFilterEnabled(1);
#endif #endif
} }
@ -26,6 +25,18 @@ SixenseManager::~SixenseManager() {
#endif #endif
} }
void SixenseManager::setFilter(bool filter) {
#ifdef HAVE_SIXENSE
if (filter) {
qDebug("Sixense Filter ON\n");
sixenseSetFilterEnabled(1);
} else {
qDebug("Sixense Filter OFF\n");
sixenseSetFilterEnabled(0);
}
#endif
}
void SixenseManager::update(float deltaTime) { void SixenseManager::update(float deltaTime) {
#ifdef HAVE_SIXENSE #ifdef HAVE_SIXENSE
if (sixenseGetNumActiveControllers() == 0) { if (sixenseGetNumActiveControllers() == 0) {

View file

@ -10,13 +10,19 @@
#define __interface__SixenseManager__ #define __interface__SixenseManager__
/// Handles interaction with the Sixense SDK (e.g., Razer Hydra). /// Handles interaction with the Sixense SDK (e.g., Razer Hydra).
class SixenseManager { class SixenseManager : public QObject {
Q_OBJECT
public: public:
SixenseManager(); SixenseManager();
~SixenseManager(); ~SixenseManager();
void update(float deltaTime); void update(float deltaTime);
public slots:
void setFilter(bool filter);
}; };
#endif /* defined(__interface__SixenseManager__) */ #endif /* defined(__interface__SixenseManager__) */

View file

@ -26,6 +26,7 @@ const int NUM_FINGERS = NUM_HANDS * NUM_FINGERS_PER_HAND;
const int LEAPID_INVALID = -1; const int LEAPID_INVALID = -1;
const int SIXENSEID_INVALID = -1; const int SIXENSEID_INVALID = -1;
const int BUTTON_0 = 1; // the skinny button between 1 and 2
const int BUTTON_1 = 32; const int BUTTON_1 = 32;
const int BUTTON_2 = 64; const int BUTTON_2 = 64;
const int BUTTON_3 = 8; const int BUTTON_3 = 8;
@ -157,8 +158,11 @@ public:
// Controller buttons // Controller buttons
void setControllerButtons(int controllerButtons) { _controllerButtons = controllerButtons; } void setControllerButtons(int controllerButtons) { _controllerButtons = controllerButtons; }
int getControllerButtons() { return _controllerButtons; } void setLastControllerButtons(int controllerButtons) { _lastControllerButtons = controllerButtons; }
int getControllerButtons() { return _controllerButtons; }
int getLastControllerButtons() { return _lastControllerButtons; }
void setTrigger(float trigger) { _trigger = trigger; } void setTrigger(float trigger) { _trigger = trigger; }
float getTrigger() { return _trigger; } float getTrigger() { return _trigger; }
void setJoystick(float joystickX, float joystickY) { _joystickX = joystickX; _joystickY = joystickY; } void setJoystick(float joystickX, float joystickY) { _joystickX = joystickX; _joystickY = joystickY; }
@ -180,6 +184,7 @@ private:
glm::vec3 _tipPosition; glm::vec3 _tipPosition;
glm::vec3 _tipVelocity; glm::vec3 _tipVelocity;
int _controllerButtons; int _controllerButtons;
int _lastControllerButtons;
float _trigger; float _trigger;
float _joystickX, _joystickY; float _joystickX, _joystickY;

View file

@ -35,6 +35,7 @@ Particle::~Particle() {
void Particle::init(glm::vec3 position, float radius, rgbColor color, glm::vec3 velocity, void Particle::init(glm::vec3 position, float radius, rgbColor color, glm::vec3 velocity,
float damping, glm::vec3 gravity, QString updateScript, uint32_t id) { float damping, glm::vec3 gravity, QString updateScript, uint32_t id) {
if (id == NEW_PARTICLE) { if (id == NEW_PARTICLE) {
_created = usecTimestampNow();
_id = _nextID; _id = _nextID;
_nextID++; _nextID++;
} else { } else {
@ -58,6 +59,9 @@ bool Particle::appendParticleData(OctreePacketData* packetData) const {
//printf("Particle::appendParticleData()... getID()=%d\n", getID()); //printf("Particle::appendParticleData()... getID()=%d\n", getID());
if (success) {
success = packetData->appendValue(getCreated());
}
if (success) { if (success) {
success = packetData->appendValue(getLastUpdated()); success = packetData->appendValue(getLastUpdated());
} }
@ -90,7 +94,7 @@ bool Particle::appendParticleData(OctreePacketData* packetData) const {
} }
int Particle::expectedBytes() { int Particle::expectedBytes() {
int expectedBytes = sizeof(uint32_t) + sizeof(uint64_t) + sizeof(float) + int expectedBytes = sizeof(uint32_t) + sizeof(uint64_t) + sizeof(uint64_t) + sizeof(float) +
sizeof(glm::vec3) + sizeof(rgbColor) + sizeof(glm::vec3) + sizeof(glm::vec3) + sizeof(rgbColor) + sizeof(glm::vec3) +
sizeof(glm::vec3) + sizeof(float); sizeof(glm::vec3) + sizeof(float);
return expectedBytes; return expectedBytes;
@ -106,6 +110,11 @@ int Particle::readParticleDataFromBuffer(const unsigned char* data, int bytesLef
dataAt += sizeof(_id); dataAt += sizeof(_id);
bytesRead += sizeof(_id); bytesRead += sizeof(_id);
// created
memcpy(&_created, dataAt, sizeof(_created));
dataAt += sizeof(_created);
bytesRead += sizeof(_created);
// lastupdated // lastupdated
memcpy(&_lastUpdated, dataAt, sizeof(_lastUpdated)); memcpy(&_lastUpdated, dataAt, sizeof(_lastUpdated));
dataAt += sizeof(_lastUpdated); dataAt += sizeof(_lastUpdated);
@ -191,6 +200,11 @@ Particle Particle::fromEditPacket(unsigned char* data, int length, int& processe
newParticle._newlyCreated = false; newParticle._newlyCreated = false;
} }
// created
memcpy(&newParticle._created, dataAt, sizeof(newParticle._created));
dataAt += sizeof(newParticle._created);
processedBytes += sizeof(newParticle._created);
// lastUpdated // lastUpdated
memcpy(&newParticle._lastUpdated, dataAt, sizeof(newParticle._lastUpdated)); memcpy(&newParticle._lastUpdated, dataAt, sizeof(newParticle._lastUpdated));
dataAt += sizeof(newParticle._lastUpdated); dataAt += sizeof(newParticle._lastUpdated);
@ -248,6 +262,7 @@ Particle Particle::fromEditPacket(unsigned char* data, int length, int& processe
void Particle::debugDump() const { void Particle::debugDump() const {
printf("Particle id :%u\n", _id); printf("Particle id :%u\n", _id);
printf(" created:%llu\n", _created);
printf(" last updated:%llu\n", _lastUpdated); printf(" last updated:%llu\n", _lastUpdated);
printf(" position:%f,%f,%f\n", _position.x, _position.y, _position.z); printf(" position:%f,%f,%f\n", _position.x, _position.y, _position.z);
printf(" velocity:%f,%f,%f\n", _velocity.x, _velocity.y, _velocity.z); printf(" velocity:%f,%f,%f\n", _velocity.x, _velocity.y, _velocity.z);
@ -280,7 +295,8 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, int count,
sizeOut += lengthOfOctcode; sizeOut += lengthOfOctcode;
// Now add our edit content details... // Now add our edit content details...
uint64_t created = usecTimestampNow();
// id // id
memcpy(copyAt, &details[i].id, sizeof(details[i].id)); memcpy(copyAt, &details[i].id, sizeof(details[i].id));
copyAt += sizeof(details[i].id); copyAt += sizeof(details[i].id);
@ -292,8 +308,15 @@ bool Particle::encodeParticleEditMessageDetails(PACKET_TYPE command, int count,
memcpy(copyAt, &details[i].creatorTokenID, sizeof(details[i].creatorTokenID)); memcpy(copyAt, &details[i].creatorTokenID, sizeof(details[i].creatorTokenID));
copyAt += sizeof(details[i].creatorTokenID); copyAt += sizeof(details[i].creatorTokenID);
sizeOut += sizeof(details[i].creatorTokenID); sizeOut += sizeof(details[i].creatorTokenID);
} } else {
created = 0;
}
// created
memcpy(copyAt, &created, sizeof(created));
copyAt += sizeof(created);
sizeOut += sizeof(created);
// lastUpdated // lastUpdated
memcpy(copyAt, &details[i].lastUpdated, sizeof(details[i].lastUpdated)); memcpy(copyAt, &details[i].lastUpdated, sizeof(details[i].lastUpdated));
copyAt += sizeof(details[i].lastUpdated); copyAt += sizeof(details[i].lastUpdated);
@ -363,7 +386,11 @@ void Particle::update() {
// calculate our default shouldDie state... then allow script to change it if it wants... // calculate our default shouldDie state... then allow script to change it if it wants...
float velocityScalar = glm::length(getVelocity()); float velocityScalar = glm::length(getVelocity());
const float STILL_MOVING = 0.05 / TREE_SCALE; const float STILL_MOVING = 0.05 / TREE_SCALE;
setShouldDie(velocityScalar < STILL_MOVING); bool isStillMoving = (velocityScalar > STILL_MOVING);
const uint64_t REALLY_OLD = 30 * 1000 * 1000;
bool isReallyOld = (getLifetime() > REALLY_OLD);
bool shouldDie = !isStillMoving && isReallyOld;
setShouldDie(shouldDie);
runScript(); // allow the javascript to alter our state runScript(); // allow the javascript to alter our state

View file

@ -62,6 +62,8 @@ public:
const glm::vec3& getVelocity() const { return _velocity; } const glm::vec3& getVelocity() const { return _velocity; }
const glm::vec3& getGravity() const { return _gravity; } const glm::vec3& getGravity() const { return _gravity; }
float getDamping() const { return _damping; } float getDamping() const { return _damping; }
uint64_t getCreated() const { return _created; }
uint64_t getLifetime() const { return usecTimestampNow() - _created; }
uint64_t getLastUpdated() const { return _lastUpdated; } uint64_t getLastUpdated() const { return _lastUpdated; }
uint32_t getID() const { return _id; } uint32_t getID() const { return _id; }
bool getShouldDie() const { return _shouldDie; } bool getShouldDie() const { return _shouldDie; }
@ -83,6 +85,7 @@ public:
void setShouldDie(bool shouldDie) { _shouldDie = shouldDie; } void setShouldDie(bool shouldDie) { _shouldDie = shouldDie; }
void setUpdateScript(QString updateScript) { _updateScript = updateScript; } void setUpdateScript(QString updateScript) { _updateScript = updateScript; }
void setCreatorTokenID(uint32_t creatorTokenID) { _creatorTokenID = creatorTokenID; } void setCreatorTokenID(uint32_t creatorTokenID) { _creatorTokenID = creatorTokenID; }
void setCreated(uint64_t created) { _created = created; }
bool appendParticleData(OctreePacketData* packetData) const; bool appendParticleData(OctreePacketData* packetData) const;
int readParticleDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args); int readParticleDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args);
@ -106,6 +109,7 @@ protected:
float _radius; float _radius;
glm::vec3 _velocity; glm::vec3 _velocity;
uint64_t _lastUpdated; uint64_t _lastUpdated;
uint64_t _created;
uint32_t _id; uint32_t _id;
static uint32_t _nextID; static uint32_t _nextID;
bool _shouldDie; bool _shouldDie;
@ -129,8 +133,11 @@ public slots:
glm::vec3 getGravity() const { return _particle->getGravity(); } glm::vec3 getGravity() const { return _particle->getGravity(); }
float getDamping() const { return _particle->getDamping(); } float getDamping() const { return _particle->getDamping(); }
float getRadius() const { return _particle->getRadius(); } float getRadius() const { return _particle->getRadius(); }
bool setShouldDie() { return _particle->getShouldDie(); } bool getShouldDie() { return _particle->getShouldDie(); }
float getCreated() const { return ((float)_particle->getCreated() / (float)USECS_PER_SECOND); }
float getLifetime() const { return ((float)_particle->getLifetime() / (float)USECS_PER_SECOND); }
void setPosition(glm::vec3 value) { _particle->setPosition(value); } void setPosition(glm::vec3 value) { _particle->setPosition(value); }
void setVelocity(glm::vec3 value) { _particle->setVelocity(value); } void setVelocity(glm::vec3 value) { _particle->setVelocity(value); }
void setGravity(glm::vec3 value) { _particle->setGravity(value); } void setGravity(glm::vec3 value) { _particle->setGravity(value); }

View file

@ -110,7 +110,9 @@ bool ParticleTree::findNearPointOperation(OctreeElement* element, void* extraDat
const Particle* ParticleTree::findClosestParticle(glm::vec3 position, float targetRadius) { const Particle* ParticleTree::findClosestParticle(glm::vec3 position, float targetRadius) {
// First, look for the existing particle in the tree.. // First, look for the existing particle in the tree..
FindNearPointArgs args = { position, targetRadius, false, NULL, FLT_MAX }; FindNearPointArgs args = { position, targetRadius, false, NULL, FLT_MAX };
lockForRead();
recurseTreeWithOperation(findNearPointOperation, &args); recurseTreeWithOperation(findNearPointOperation, &args);
unlock();
return args.closestParticle; return args.closestParticle;
} }

View file

@ -118,7 +118,12 @@ bool ParticleTreeElement::updateParticle(const Particle& particle) {
uint16_t numberOfParticles = _particles.size(); uint16_t numberOfParticles = _particles.size();
for (uint16_t i = 0; i < numberOfParticles; i++) { for (uint16_t i = 0; i < numberOfParticles; i++) {
if (_particles[i].getID() == particle.getID()) { if (_particles[i].getID() == particle.getID()) {
uint64_t actuallyCreated = particle.getCreated();
if (!particle.isNewlyCreated()) {
actuallyCreated = _particles[i].getCreated();
}
_particles[i] = particle; _particles[i] = particle;
_particles[i].setCreated(actuallyCreated);
return true; return true;
} }
} }

View file

@ -52,6 +52,7 @@ static const float METER = 1.0f;
static const float DECIMETER = 0.1f; static const float DECIMETER = 0.1f;
static const float CENTIMETER = 0.01f; static const float CENTIMETER = 0.01f;
static const float MILLIIMETER = 0.001f; static const float MILLIIMETER = 0.001f;
static const uint64_t USECS_PER_SECOND = 1000 * 1000;
uint64_t usecTimestamp(const timeval *time); uint64_t usecTimestamp(const timeval *time);
uint64_t usecTimestampNow(); uint64_t usecTimestampNow();