Merge pull request #1386 from PhilipRosedale/slaps

Hand games are now menu options, hydra hands in fixed L/R orientation, added slaps game
This commit is contained in:
ZappoMan 2013-12-17 11:34:43 -08:00
commit 4852aca86c
9 changed files with 126 additions and 48 deletions

View file

@ -373,7 +373,10 @@ Menu::Menu() :
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayLeapHands, 0, true);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::LeapDrive, 0, false);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::BallFromHand, 0, false);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::BallFromHand, 0, false);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::VoxelDrumming, 0, false);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::PlaySlaps, 0, false);
QMenu* trackingOptionsMenu = developerMenu->addMenu("Tracking Options");

View file

@ -244,6 +244,8 @@ namespace MenuOption {
const QString ShowAllLocalVoxels = "Show All Local Voxels";
const QString ShowTrueColors = "Show TRUE Colors";
const QString SimulateLeapHand = "Simulate Leap Hand";
const QString VoxelDrumming = "Voxel Drumming";
const QString PlaySlaps = "Play Slaps";
const QString SkeletonTracking = "Skeleton Tracking";
const QString SuppressShortTimings = "Suppress Timings Less than 10ms";
const QString LEDTracking = "LED Tracking";

View file

@ -17,6 +17,8 @@
#include "Util.h"
#include "renderer/ProgramObject.h"
//#define DEBUG_HAND
using namespace std;
const float FINGERTIP_VOXEL_SIZE = 0.05;
@ -98,6 +100,9 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f
glm::vec3 newVelocity = NO_VELOCITY;
// update the particle with it's new state...
#ifdef DEBUG_HAND
qDebug("Update caught particle!\n");
#endif
caughtParticle->updateParticle(newPosition,
closestParticle->getRadius(),
closestParticle->getXColor(),
@ -143,6 +148,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
#ifdef DEBUG_HAND
qDebug("Created New Ball\n");
#endif
glm::vec3 ballPosition = ballFromHand ? palm.getPosition() : fingerTipPosition;
_ballParticleEditHandles[handID] = Application::getInstance()->makeParticle(
ballPosition / (float)TREE_SCALE,
@ -156,6 +164,9 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f
}
} else {
// Ball is in hand
#ifdef DEBUG_HAND
qDebug("Ball in hand\n");
#endif
glm::vec3 ballPosition = ballFromHand ? palm.getPosition() : fingerTipPosition;
_ballParticleEditHandles[handID]->updateParticle(ballPosition / (float)TREE_SCALE,
TOY_BALL_RADIUS / (float) TREE_SCALE,
@ -172,16 +183,18 @@ void Hand::simulateToyBall(PalmData& palm, const glm::vec3& fingerTipPosition, f
_toyBallInHand[handID] = false;
glm::vec3 ballPosition = ballFromHand ? palm.getPosition() : fingerTipPosition;
glm::vec3 handVelocity = palm.getRawVelocity();
glm::vec3 fingerTipVelocity = palm.getTipVelocity();
glm::vec3 ballVelocity = ballFromHand ? palm.getRawVelocity() : palm.getTipVelocity();
glm::quat avatarRotation = _owningAvatar->getOrientation();
glm::vec3 toyBallVelocity = avatarRotation * fingerTipVelocity;
ballVelocity = avatarRotation * ballVelocity;
// ball is no longer in hand...
#ifdef DEBUG_HAND
qDebug("Threw ball, v = %.3f\n", glm::length(ballVelocity));
#endif
_ballParticleEditHandles[handID]->updateParticle(ballPosition / (float)TREE_SCALE,
TOY_BALL_RADIUS / (float) TREE_SCALE,
TOY_BALL_ON_SERVER_COLOR[_whichBallColor[handID]],
toyBallVelocity / (float)TREE_SCALE,
ballVelocity / (float)TREE_SCALE,
TOY_BALL_GRAVITY / (float) TREE_SCALE,
TOY_BALL_DAMPING,
NOT_IN_HAND,
@ -272,32 +285,35 @@ void Hand::simulate(float deltaTime, bool isMine) {
_lastFingerDeleteVoxel = fingerTipPosition;
}
}
// Check if the finger is intersecting with a voxel in the client voxel tree
VoxelTreeElement* fingerNode = Application::getInstance()->getVoxels()->getVoxelEnclosing(
glm::vec3(fingerTipPosition / (float)TREE_SCALE));
if (fingerNode) {
if (!palm.getIsCollidingWithVoxel()) {
// Collision has just started
palm.setIsCollidingWithVoxel(true);
handleVoxelCollision(&palm, fingerTipPosition, fingerNode, deltaTime);
// Set highlight voxel
VoxelDetail voxel;
glm::vec3 pos = fingerNode->getCorner();
voxel.x = pos.x;
voxel.y = pos.y;
voxel.z = pos.z;
voxel.s = fingerNode->getScale();
voxel.red = fingerNode->getColor()[0];
voxel.green = fingerNode->getColor()[1];
voxel.blue = fingerNode->getColor()[2];
Application::getInstance()->setHighlightVoxel(voxel);
Application::getInstance()->setIsHighlightVoxel(true);
}
} else {
if (palm.getIsCollidingWithVoxel()) {
// Collision has just ended
palm.setIsCollidingWithVoxel(false);
Application::getInstance()->setIsHighlightVoxel(false);
// Voxel Drumming with fingertips if enabled
if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelDrumming)) {
VoxelTreeElement* fingerNode = Application::getInstance()->getVoxels()->getVoxelEnclosing(
glm::vec3(fingerTipPosition / (float)TREE_SCALE));
if (fingerNode) {
if (!palm.getIsCollidingWithVoxel()) {
// Collision has just started
palm.setIsCollidingWithVoxel(true);
handleVoxelCollision(&palm, fingerTipPosition, fingerNode, deltaTime);
// Set highlight voxel
VoxelDetail voxel;
glm::vec3 pos = fingerNode->getCorner();
voxel.x = pos.x;
voxel.y = pos.y;
voxel.z = pos.z;
voxel.s = fingerNode->getScale();
voxel.red = fingerNode->getColor()[0];
voxel.green = fingerNode->getColor()[1];
voxel.blue = fingerNode->getColor()[2];
Application::getInstance()->setHighlightVoxel(voxel);
Application::getInstance()->setIsHighlightVoxel(true);
}
} else {
if (palm.getIsCollidingWithVoxel()) {
// Collision has just ended
palm.setIsCollidingWithVoxel(false);
Application::getInstance()->setIsHighlightVoxel(false);
}
}
}
}
@ -325,9 +341,37 @@ void Hand::updateCollisions() {
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
if (node->getLinkedData() && node->getType() == NODE_TYPE_AGENT) {
Avatar* otherAvatar = (Avatar*)node->getLinkedData();
if (Menu::getInstance()->isOptionChecked(MenuOption::PlaySlaps)) {
// Check for palm collisions
glm::vec3 myPalmPosition = palm.getPosition();
float palmCollisionDistance = 0.1f;
palm.setIsCollidingWithPalm(false);
// If 'Play Slaps' is enabled, look for palm-to-palm collisions and make sound
for (int j = 0; j < otherAvatar->getHand().getNumPalms(); j++) {
PalmData& otherPalm = otherAvatar->getHand().getPalms()[j];
if (!otherPalm.isActive()) {
continue;
}
glm::vec3 otherPalmPosition = otherPalm.getPosition();
if (glm::length(otherPalmPosition - myPalmPosition) < palmCollisionDistance) {
palm.setIsCollidingWithPalm(true);
const float PALM_COLLIDE_VOLUME = 1.f;
const float PALM_COLLIDE_FREQUENCY = 150.f;
const float PALM_COLLIDE_DURATION_MAX = 2.f;
const float PALM_COLLIDE_DECAY_PER_SAMPLE = 0.005f;
Application::getInstance()->getAudio()->startDrumSound(PALM_COLLIDE_VOLUME,
PALM_COLLIDE_FREQUENCY,
PALM_COLLIDE_DURATION_MAX,
PALM_COLLIDE_DECAY_PER_SAMPLE);
}
}
}
glm::vec3 avatarPenetration;
if (otherAvatar->findSpherePenetration(palm.getPosition(), scaledPalmRadius, avatarPenetration)) {
totalPenetration = addPenetrations(totalPenetration, avatarPenetration);
// Check for collisions with the other avatar's leap palms
}
}
}
@ -534,7 +578,11 @@ void Hand::renderLeapHands() {
PalmData& palm = getPalms()[i];
if (palm.isActive()) {
const float palmThickness = 0.02f;
glColor4f(handColor.r, handColor.g, handColor.b, 0.25);
if (palm.getIsCollidingWithPalm()) {
glColor4f(1, 0, 0, 0.50);
} else {
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.05f;

View file

@ -79,7 +79,6 @@ private:
std::vector<HandBall> _leapFingerRootBalls;
glm::vec3 _lastFingerAddVoxel, _lastFingerDeleteVoxel;
bool _isCollidingWithVoxel;
VoxelDetail _collidingVoxel;
glm::vec3 _collisionCenter;

View file

@ -426,6 +426,31 @@ static TextRenderer* textRenderer() {
return renderer;
}
void MyAvatar::renderDebugBodyPoints() {
glm::vec3 torsoPosition(getPosition());
glm::vec3 headPosition(getHead().getEyePosition());
float torsoToHead = glm::length(headPosition - torsoPosition);
glm::vec3 position;
printf("head-above-torso %.2f, scale = %0.2f\n", torsoToHead, getScale());
// Torso Sphere
position = torsoPosition;
glPushMatrix();
glColor4f(0, 1, 0, .5f);
glTranslatef(position.x, position.y, position.z);
glutSolidSphere(0.2, 10, 10);
glPopMatrix();
// Head Sphere
position = headPosition;
glPushMatrix();
glColor4f(0, 1, 0, .5f);
glTranslatef(position.x, position.y, position.z);
glutSolidSphere(0.15, 10, 10);
glPopMatrix();
}
void MyAvatar::render(bool forceRenderHead) {
// render body
@ -438,6 +463,9 @@ void MyAvatar::render(bool forceRenderHead) {
glPopMatrix();
}
//renderDebugBodyPoints();
if (!_chatMessage.empty()) {
int width = 0;
int lastWidth = 0;

View file

@ -30,6 +30,7 @@ public:
void simulate(float deltaTime, Transmitter* transmitter);
void updateFromGyrosAndOrWebcam(bool turnWithHead);
void render(bool forceRenderHead);
void renderDebugBodyPoints();
// setters
void setMousePressed(bool mousePressed) { _mousePressed = mousePressed; }

View file

@ -79,12 +79,6 @@ void SixenseManager::update(float deltaTime) {
palm->setTrigger(data.trigger);
palm->setJoystick(data.joystick_x, data.joystick_y);
// Vibrate if needed
if (palm->getIsCollidingWithVoxel()) {
//printf("vibrate!\n");
//vibrate(data.controller_index, 100, 1);
}
glm::vec3 position(data.pos[0], data.pos[1], data.pos[2]);
// Adjust for distance between acquisition 'orb' and the user's torso
// (distance to the right of body center, distance below torso, distance behind torso)

View file

@ -38,22 +38,20 @@ PalmData& HandData::addNewPalm() {
return _palms.back();
}
const int SIXENSE_CONTROLLER_ID_LEFT_HAND = 0;
const int SIXENSE_CONTROLLER_ID_RIGHT_HAND = 1;
void HandData::getLeftRightPalmIndices(int& leftPalmIndex, int& rightPalmIndex) const {
leftPalmIndex = -1;
float leftPalmX = FLT_MAX;
rightPalmIndex = -1;
float rightPalmX = -FLT_MAX;
rightPalmIndex = -1;
for (int i = 0; i < _palms.size(); i++) {
const PalmData& palm = _palms[i];
if (palm.isActive()) {
float x = palm.getRawPosition().x;
if (x < leftPalmX) {
if (palm.getSixenseID() == SIXENSE_CONTROLLER_ID_LEFT_HAND) {
leftPalmIndex = i;
leftPalmX = x;
}
if (x > rightPalmX) {
if (palm.getSixenseID() == SIXENSE_CONTROLLER_ID_RIGHT_HAND) {
rightPalmIndex = i;
rightPalmX = x;
}
}
}
@ -71,7 +69,8 @@ _leapID(LEAPID_INVALID),
_sixenseID(SIXENSEID_INVALID),
_numFramesWithoutData(0),
_owningHandData(owningHandData),
_isCollidingWithVoxel(false)
_isCollidingWithVoxel(false),
_isCollidingWithPalm(false)
{
for (int i = 0; i < NUM_FINGERS_PER_HAND; ++i) {
_fingers.push_back(FingerData(this, owningHandData));

View file

@ -182,6 +182,9 @@ public:
bool getIsCollidingWithVoxel() { return _isCollidingWithVoxel; }
void setIsCollidingWithVoxel(bool isCollidingWithVoxel) { _isCollidingWithVoxel = isCollidingWithVoxel; }
bool getIsCollidingWithPalm() { return _isCollidingWithPalm; }
void setIsCollidingWithPalm(bool isCollidingWithPalm) { _isCollidingWithPalm = isCollidingWithPalm; }
private:
std::vector<FingerData> _fingers;
glm::quat _rawRotation;
@ -205,6 +208,7 @@ private:
HandData* _owningHandData;
bool _isCollidingWithVoxel; /// Whether the finger of this palm is inside a leaf voxel
bool _isCollidingWithPalm;
};