mirror of
https://github.com/overte-org/overte.git
synced 2025-07-23 06:44:07 +02:00
Merge pull request #592 from machinelevel/dev
Hand rework in preparation for adding send/receive hand data
This commit is contained in:
commit
c1d23f5f63
10 changed files with 293 additions and 73 deletions
|
@ -1674,7 +1674,7 @@ void Application::update(float deltaTime) {
|
||||||
|
|
||||||
// Leap finger-sensing device
|
// Leap finger-sensing device
|
||||||
LeapManager::nextFrame();
|
LeapManager::nextFrame();
|
||||||
_myAvatar.setLeapFingers(LeapManager::getFingerPositions());
|
_myAvatar.getHand().setLeapFingers(LeapManager::getFingerPositions());
|
||||||
|
|
||||||
// Read serial port interface devices
|
// Read serial port interface devices
|
||||||
if (_serialHeadSensor.isActive()) {
|
if (_serialHeadSensor.isActive()) {
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "world.h"
|
#include "world.h"
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "Avatar.h"
|
#include "Avatar.h"
|
||||||
|
#include "Hand.h"
|
||||||
#include "Head.h"
|
#include "Head.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "ui/TextRenderer.h"
|
#include "ui/TextRenderer.h"
|
||||||
|
@ -64,6 +65,7 @@ Avatar::Avatar(Agent* owningAgent) :
|
||||||
AvatarData(owningAgent),
|
AvatarData(owningAgent),
|
||||||
_initialized(false),
|
_initialized(false),
|
||||||
_head(this),
|
_head(this),
|
||||||
|
_hand(this),
|
||||||
_ballSpringsInitialized(false),
|
_ballSpringsInitialized(false),
|
||||||
_TEST_bigSphereRadius(0.5f),
|
_TEST_bigSphereRadius(0.5f),
|
||||||
_TEST_bigSpherePosition(5.0f, _TEST_bigSphereRadius, 5.0f),
|
_TEST_bigSpherePosition(5.0f, _TEST_bigSphereRadius, 5.0f),
|
||||||
|
@ -96,6 +98,7 @@ Avatar::Avatar(Agent* owningAgent) :
|
||||||
{
|
{
|
||||||
// give the pointer to our head to inherited _headData variable from AvatarData
|
// give the pointer to our head to inherited _headData variable from AvatarData
|
||||||
_headData = &_head;
|
_headData = &_head;
|
||||||
|
_handData = &_hand;
|
||||||
|
|
||||||
for (int i = 0; i < MAX_DRIVE_KEYS; i++) {
|
for (int i = 0; i < MAX_DRIVE_KEYS; i++) {
|
||||||
_driveKeys[i] = false;
|
_driveKeys[i] = false;
|
||||||
|
@ -104,7 +107,6 @@ Avatar::Avatar(Agent* owningAgent) :
|
||||||
_skeleton.initialize();
|
_skeleton.initialize();
|
||||||
|
|
||||||
initializeBodyBalls();
|
initializeBodyBalls();
|
||||||
initializeLeapBalls();
|
|
||||||
|
|
||||||
_height = _skeleton.getHeight() + _bodyBall[ BODY_BALL_LEFT_HEEL ].radius + _bodyBall[ BODY_BALL_HEAD_BASE ].radius;
|
_height = _skeleton.getHeight() + _bodyBall[ BODY_BALL_LEFT_HEEL ].radius + _bodyBall[ BODY_BALL_HEAD_BASE ].radius;
|
||||||
|
|
||||||
|
@ -264,35 +266,22 @@ void Avatar::initializeBodyBalls() {
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::initializeLeapBalls() {
|
|
||||||
|
|
||||||
_numLeapBalls = 0;
|
|
||||||
|
|
||||||
for (int b = 0; b < MAX_AVATAR_LEAP_BALLS; b++) {
|
|
||||||
_leapBall[b].parentJoint = AVATAR_JOINT_NULL;
|
|
||||||
_leapBall[b].parentOffset = glm::vec3(0.0, 0.0, 0.0);
|
|
||||||
_leapBall[b].position = glm::vec3(0.0, 0.0, 0.0);
|
|
||||||
_leapBall[b].velocity = glm::vec3(0.0, 0.0, 0.0);
|
|
||||||
_leapBall[b].radius = 0.01;
|
|
||||||
_leapBall[b].touchForce = 0.0;
|
|
||||||
_leapBall[b].isCollidable = true;
|
|
||||||
_leapBall[b].jointTightness = BODY_SPRING_DEFAULT_TIGHTNESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Avatar::~Avatar() {
|
Avatar::~Avatar() {
|
||||||
_headData = NULL;
|
_headData = NULL;
|
||||||
|
_handData = NULL;
|
||||||
delete _balls;
|
delete _balls;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::init() {
|
void Avatar::init() {
|
||||||
_head.init();
|
_head.init();
|
||||||
|
_hand.init();
|
||||||
_voxels.init();
|
_voxels.init();
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::reset() {
|
void Avatar::reset() {
|
||||||
_head.reset();
|
_head.reset();
|
||||||
|
_hand.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update avatar head rotation with sensor data
|
// Update avatar head rotation with sensor data
|
||||||
|
@ -543,9 +532,6 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
||||||
// update body balls
|
// update body balls
|
||||||
updateBodyBalls(deltaTime);
|
updateBodyBalls(deltaTime);
|
||||||
|
|
||||||
// update leap balls
|
|
||||||
updateLeapBalls(deltaTime);
|
|
||||||
|
|
||||||
// test for avatar collision response with the big sphere
|
// test for avatar collision response with the big sphere
|
||||||
if (usingBigSphereCollisionTest) {
|
if (usingBigSphereCollisionTest) {
|
||||||
updateCollisionWithSphere(_TEST_bigSpherePosition, _TEST_bigSphereRadius, deltaTime);
|
updateCollisionWithSphere(_TEST_bigSpherePosition, _TEST_bigSphereRadius, deltaTime);
|
||||||
|
@ -1167,23 +1153,6 @@ void Avatar::updateBodyBalls(float deltaTime) {
|
||||||
_bodyBall[BODY_BALL_HEAD_TOP].rotation * _skeleton.joint[BODY_BALL_HEAD_TOP].bindPosePosition;
|
_bodyBall[BODY_BALL_HEAD_TOP].rotation * _skeleton.joint[BODY_BALL_HEAD_TOP].bindPosePosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::setLeapFingers(const std::vector<glm::vec3>& fingerPositions) {
|
|
||||||
_numLeapBalls = fingerPositions.size(); // just to test
|
|
||||||
|
|
||||||
float unitScale = 0.001; // convert mm to meters
|
|
||||||
glm::vec3 offset(0.2, -0.2, -0.3); // place the hand in front of the face where we can see it
|
|
||||||
|
|
||||||
for (int b = 0; b < _numLeapBalls; b++) {
|
|
||||||
glm::vec3 pos = unitScale * fingerPositions[b] + offset;
|
|
||||||
_leapBall[b].rotation = _head.getOrientation();
|
|
||||||
_leapBall[b].position = _bodyBall[BODY_BALL_HEAD_BASE].position +
|
|
||||||
_head.getOrientation() * pos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Avatar::updateLeapBalls(float deltaTime) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void Avatar::updateArmIKAndConstraints(float deltaTime) {
|
void Avatar::updateArmIKAndConstraints(float deltaTime) {
|
||||||
|
|
||||||
// determine the arm vector
|
// determine the arm vector
|
||||||
|
@ -1306,30 +1275,7 @@ void Avatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Draw the leap balls
|
_hand.render(lookingInMirror);
|
||||||
for (int b = 0; b < _numLeapBalls; b++) {
|
|
||||||
float alpha = 1.0f;
|
|
||||||
|
|
||||||
if (alpha > 0.0f) {
|
|
||||||
// Render the body ball sphere
|
|
||||||
if (_owningAgent || true) {
|
|
||||||
glColor3f(SKIN_COLOR[0] + _leapBall[b].touchForce * 0.3f,
|
|
||||||
SKIN_COLOR[1] - _leapBall[b].touchForce * 0.2f,
|
|
||||||
SKIN_COLOR[2] - _leapBall[b].touchForce * 0.1f);
|
|
||||||
} else {
|
|
||||||
glColor4f(SKIN_COLOR[0] + _leapBall[b].touchForce * 0.3f,
|
|
||||||
SKIN_COLOR[1] - _leapBall[b].touchForce * 0.2f,
|
|
||||||
SKIN_COLOR[2] - _leapBall[b].touchForce * 0.1f,
|
|
||||||
alpha);
|
|
||||||
}
|
|
||||||
glColor4f(0.0, 0.4, 0.0, 1.0); // Just to test
|
|
||||||
|
|
||||||
glPushMatrix();
|
|
||||||
glTranslatef(_leapBall[b].position.x, _leapBall[b].position.y, _leapBall[b].position.z);
|
|
||||||
glutSolidSphere(_leapBall[b].radius, 20.0f, 20.0f);
|
|
||||||
glPopMatrix();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Render the body's voxels
|
// Render the body's voxels
|
||||||
float alpha = getBallRenderAlpha(BODY_BALL_HEAD_BASE, lookingInMirror);
|
float alpha = getBallRenderAlpha(BODY_BALL_HEAD_BASE, lookingInMirror);
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "InterfaceConfig.h"
|
#include "InterfaceConfig.h"
|
||||||
#include "SerialInterface.h"
|
#include "SerialInterface.h"
|
||||||
#include "Balls.h"
|
#include "Balls.h"
|
||||||
|
#include "Hand.h"
|
||||||
#include "Head.h"
|
#include "Head.h"
|
||||||
#include "Skeleton.h"
|
#include "Skeleton.h"
|
||||||
#include "Transmitter.h"
|
#include "Transmitter.h"
|
||||||
|
@ -56,8 +57,6 @@ enum AvatarBodyBallID
|
||||||
NUM_AVATAR_BODY_BALLS
|
NUM_AVATAR_BODY_BALLS
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_AVATAR_LEAP_BALLS 10
|
|
||||||
|
|
||||||
enum DriveKeys
|
enum DriveKeys
|
||||||
{
|
{
|
||||||
FWD = 0,
|
FWD = 0,
|
||||||
|
@ -105,7 +104,6 @@ public:
|
||||||
void setGravity (glm::vec3 gravity);
|
void setGravity (glm::vec3 gravity);
|
||||||
void setMouseRay (const glm::vec3 &origin, const glm::vec3 &direction);
|
void setMouseRay (const glm::vec3 &origin, const glm::vec3 &direction);
|
||||||
void setOrientation (const glm::quat& orientation);
|
void setOrientation (const glm::quat& orientation);
|
||||||
void setLeapFingers (const std::vector<glm::vec3>& fingerPositions);
|
|
||||||
|
|
||||||
//getters
|
//getters
|
||||||
bool isInitialized () const { return _initialized;}
|
bool isInitialized () const { return _initialized;}
|
||||||
|
@ -115,8 +113,6 @@ public:
|
||||||
bool getIsNearInteractingOther () const { return _avatarTouch.getAbleToReachOtherAvatar();}
|
bool getIsNearInteractingOther () const { return _avatarTouch.getAbleToReachOtherAvatar();}
|
||||||
const glm::vec3& getHeadJointPosition () const { return _skeleton.joint[ AVATAR_JOINT_HEAD_BASE ].position;}
|
const glm::vec3& getHeadJointPosition () const { return _skeleton.joint[ AVATAR_JOINT_HEAD_BASE ].position;}
|
||||||
const glm::vec3& getBallPosition (AvatarJointID j) const { return _bodyBall[j].position;}
|
const glm::vec3& getBallPosition (AvatarJointID j) const { return _bodyBall[j].position;}
|
||||||
int getNumLeapBalls () const { return _numLeapBalls;}
|
|
||||||
const glm::vec3& getLeapBallPosition (int which) const { return _leapBall[which].position;}
|
|
||||||
glm::vec3 getBodyRightDirection () const { return getOrientation() * IDENTITY_RIGHT; }
|
glm::vec3 getBodyRightDirection () const { return getOrientation() * IDENTITY_RIGHT; }
|
||||||
glm::vec3 getBodyUpDirection () const { return getOrientation() * IDENTITY_UP; }
|
glm::vec3 getBodyUpDirection () const { return getOrientation() * IDENTITY_UP; }
|
||||||
glm::vec3 getBodyFrontDirection () const { return getOrientation() * IDENTITY_FRONT; }
|
glm::vec3 getBodyFrontDirection () const { return getOrientation() * IDENTITY_FRONT; }
|
||||||
|
@ -131,6 +127,7 @@ public:
|
||||||
float getAbsoluteHeadYaw () const;
|
float getAbsoluteHeadYaw () const;
|
||||||
float getAbsoluteHeadPitch () const;
|
float getAbsoluteHeadPitch () const;
|
||||||
Head& getHead () {return _head; }
|
Head& getHead () {return _head; }
|
||||||
|
Hand& getHand () {return _hand; }
|
||||||
glm::quat getOrientation () const;
|
glm::quat getOrientation () const;
|
||||||
glm::quat getWorldAlignedOrientation() const;
|
glm::quat getWorldAlignedOrientation() const;
|
||||||
|
|
||||||
|
@ -180,6 +177,7 @@ private:
|
||||||
|
|
||||||
bool _initialized;
|
bool _initialized;
|
||||||
Head _head;
|
Head _head;
|
||||||
|
Hand _hand;
|
||||||
Skeleton _skeleton;
|
Skeleton _skeleton;
|
||||||
bool _ballSpringsInitialized;
|
bool _ballSpringsInitialized;
|
||||||
float _TEST_bigSphereRadius;
|
float _TEST_bigSphereRadius;
|
||||||
|
@ -190,8 +188,6 @@ private:
|
||||||
float _bodyRollDelta;
|
float _bodyRollDelta;
|
||||||
glm::vec3 _movedHandOffset;
|
glm::vec3 _movedHandOffset;
|
||||||
AvatarBall _bodyBall[ NUM_AVATAR_BODY_BALLS ];
|
AvatarBall _bodyBall[ NUM_AVATAR_BODY_BALLS ];
|
||||||
AvatarBall _leapBall[ MAX_AVATAR_LEAP_BALLS ];
|
|
||||||
int _numLeapBalls;
|
|
||||||
AvatarMode _mode;
|
AvatarMode _mode;
|
||||||
glm::vec3 _handHoldingPosition;
|
glm::vec3 _handHoldingPosition;
|
||||||
glm::vec3 _velocity;
|
glm::vec3 _velocity;
|
||||||
|
@ -226,10 +222,8 @@ private:
|
||||||
float getBallRenderAlpha(int ball, bool lookingInMirror) const;
|
float getBallRenderAlpha(int ball, bool lookingInMirror) const;
|
||||||
void renderBody(bool lookingInMirror, bool renderAvatarBalls);
|
void renderBody(bool lookingInMirror, bool renderAvatarBalls);
|
||||||
void initializeBodyBalls();
|
void initializeBodyBalls();
|
||||||
void initializeLeapBalls();
|
|
||||||
void resetBodyBalls();
|
void resetBodyBalls();
|
||||||
void updateBodyBalls( float deltaTime );
|
void updateBodyBalls( float deltaTime );
|
||||||
void updateLeapBalls( float deltaTime );
|
|
||||||
void calculateBoneLengths();
|
void calculateBoneLengths();
|
||||||
void readSensors();
|
void readSensors();
|
||||||
void updateHandMovementAndTouching(float deltaTime);
|
void updateHandMovementAndTouching(float deltaTime);
|
||||||
|
|
100
interface/src/Hand.cpp
Executable file
100
interface/src/Hand.cpp
Executable file
|
@ -0,0 +1,100 @@
|
||||||
|
//
|
||||||
|
// Hand.cpp
|
||||||
|
// interface
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
|
|
||||||
|
#include <QImage>
|
||||||
|
|
||||||
|
#include <AgentList.h>
|
||||||
|
|
||||||
|
#include "Application.h"
|
||||||
|
#include "Avatar.h"
|
||||||
|
#include "Hand.h"
|
||||||
|
#include "Util.h"
|
||||||
|
#include "renderer/ProgramObject.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
Hand::Hand(Avatar* owningAvatar) :
|
||||||
|
HandData((AvatarData*)owningAvatar),
|
||||||
|
_owningAvatar(owningAvatar),
|
||||||
|
_renderAlpha(1.0),
|
||||||
|
_lookingInMirror(false),
|
||||||
|
_ballColor(0.0, 0.4, 0.0),
|
||||||
|
_position(0.0, 0.4, 0.0),
|
||||||
|
_orientation(0.0, 0.0, 0.0, 1.0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hand::init() {
|
||||||
|
_numLeapBalls = 0;
|
||||||
|
for (int b = 0; b < MAX_AVATAR_LEAP_BALLS; b++) {
|
||||||
|
_leapBall[b].position = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_leapBall[b].velocity = glm::vec3(0.0, 0.0, 0.0);
|
||||||
|
_leapBall[b].radius = 0.01;
|
||||||
|
_leapBall[b].touchForce = 0.0;
|
||||||
|
_leapBall[b].isCollidable = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hand::reset() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hand::simulate(float deltaTime, bool isMine) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hand::calculateGeometry() {
|
||||||
|
glm::vec3 offset(0.1, -0.1, -0.15); // place the hand in front of the face where we can see it
|
||||||
|
|
||||||
|
Head& head = _owningAvatar->getHead();
|
||||||
|
_position = head.getPosition() + head.getOrientation() * offset;
|
||||||
|
_orientation = head.getOrientation();
|
||||||
|
|
||||||
|
_numLeapBalls = _fingerPositions.size();
|
||||||
|
|
||||||
|
float unitScale = 0.001; // convert mm to meters
|
||||||
|
for (int b = 0; b < _numLeapBalls; b++) {
|
||||||
|
glm::vec3 pos = unitScale * _fingerPositions[b] + offset;
|
||||||
|
_leapBall[b].rotation = _orientation;
|
||||||
|
_leapBall[b].position = _position + _orientation * pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Hand::render(bool lookingInMirror) {
|
||||||
|
|
||||||
|
_renderAlpha = 1.0;
|
||||||
|
_lookingInMirror = lookingInMirror;
|
||||||
|
|
||||||
|
calculateGeometry();
|
||||||
|
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glEnable(GL_RESCALE_NORMAL);
|
||||||
|
|
||||||
|
renderHandSpheres();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hand::renderHandSpheres() {
|
||||||
|
glPushMatrix();
|
||||||
|
// Draw the leap balls
|
||||||
|
for (int b = 0; b < _numLeapBalls; b++) {
|
||||||
|
float alpha = 1.0f;
|
||||||
|
|
||||||
|
if (alpha > 0.0f) {
|
||||||
|
glColor4f(_ballColor.r, _ballColor.g, _ballColor.b, alpha); // Just to test
|
||||||
|
|
||||||
|
glPushMatrix();
|
||||||
|
glTranslatef(_leapBall[b].position.x, _leapBall[b].position.y, _leapBall[b].position.z);
|
||||||
|
glutSolidSphere(_leapBall[b].radius, 20.0f, 20.0f);
|
||||||
|
glPopMatrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
glPopMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hand::setLeapFingers(const std::vector<glm::vec3>& fingerPositions) {
|
||||||
|
_fingerPositions = fingerPositions;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
69
interface/src/Hand.h
Executable file
69
interface/src/Hand.h
Executable file
|
@ -0,0 +1,69 @@
|
||||||
|
//
|
||||||
|
// Hand.h
|
||||||
|
// interface
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_Hand_h
|
||||||
|
#define hifi_Hand_h
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <AvatarData.h>
|
||||||
|
#include <HandData.h>
|
||||||
|
#include "Balls.h"
|
||||||
|
#include "world.h"
|
||||||
|
#include "InterfaceConfig.h"
|
||||||
|
#include "SerialInterface.h"
|
||||||
|
#include <SharedUtil.h>
|
||||||
|
|
||||||
|
|
||||||
|
class Avatar;
|
||||||
|
class ProgramObject;
|
||||||
|
|
||||||
|
class Hand : public HandData {
|
||||||
|
public:
|
||||||
|
Hand(Avatar* owningAvatar);
|
||||||
|
|
||||||
|
struct HandBall
|
||||||
|
{
|
||||||
|
glm::vec3 position; // the actual dynamic position of the ball at any given time
|
||||||
|
glm::quat rotation; // the rotation of the ball
|
||||||
|
glm::vec3 velocity; // the velocity of the ball
|
||||||
|
float radius; // the radius of the ball
|
||||||
|
bool isCollidable; // whether or not the ball responds to collisions
|
||||||
|
float touchForce; // a scalar determining the amount that the cursor (or hand) is penetrating the ball
|
||||||
|
};
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void reset();
|
||||||
|
void simulate(float deltaTime, bool isMine);
|
||||||
|
void render(bool lookingInMirror);
|
||||||
|
|
||||||
|
void setBallColor (glm::vec3 ballColor ) { _ballColor = ballColor; }
|
||||||
|
void setLeapFingers (const std::vector<glm::vec3>& fingerPositions);
|
||||||
|
|
||||||
|
// getters
|
||||||
|
int getNumLeapBalls () const { return _numLeapBalls;}
|
||||||
|
const glm::vec3& getLeapBallPosition (int which) const { return _leapBall[which].position;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// disallow copies of the Hand, copy of owning Avatar is disallowed too
|
||||||
|
Hand(const Hand&);
|
||||||
|
Hand& operator= (const Hand&);
|
||||||
|
|
||||||
|
Avatar* _owningAvatar;
|
||||||
|
float _renderAlpha;
|
||||||
|
bool _lookingInMirror;
|
||||||
|
glm::vec3 _ballColor;
|
||||||
|
glm::vec3 _position;
|
||||||
|
glm::quat _orientation;
|
||||||
|
int _numLeapBalls;
|
||||||
|
HandBall _leapBall[ MAX_AVATAR_LEAP_BALLS ];
|
||||||
|
|
||||||
|
// private methods
|
||||||
|
void renderHandSpheres();
|
||||||
|
void calculateGeometry();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -51,6 +51,7 @@ public:
|
||||||
glm::quat getOrientation() const;
|
glm::quat getOrientation() const;
|
||||||
glm::quat getCameraOrientation (float pitchYawScale) const;
|
glm::quat getCameraOrientation (float pitchYawScale) const;
|
||||||
|
|
||||||
|
glm::vec3 getPosition() const { return _position; }
|
||||||
glm::vec3 getRightDirection() const { return getOrientation() * IDENTITY_RIGHT; }
|
glm::vec3 getRightDirection() const { return getOrientation() * IDENTITY_RIGHT; }
|
||||||
glm::vec3 getUpDirection () const { return getOrientation() * IDENTITY_UP; }
|
glm::vec3 getUpDirection () const { return getOrientation() * IDENTITY_UP; }
|
||||||
glm::vec3 getFrontDirection() const { return getOrientation() * IDENTITY_FRONT; }
|
glm::vec3 getFrontDirection() const { return getOrientation() * IDENTITY_FRONT; }
|
||||||
|
|
54
libraries/avatars/src/AvatarData.cpp
Normal file → Executable file
54
libraries/avatars/src/AvatarData.cpp
Normal file → Executable file
|
@ -36,13 +36,15 @@ AvatarData::AvatarData(Agent* owningAgent) :
|
||||||
_wantColor(true),
|
_wantColor(true),
|
||||||
_wantDelta(false),
|
_wantDelta(false),
|
||||||
_wantOcclusionCulling(false),
|
_wantOcclusionCulling(false),
|
||||||
_headData(NULL)
|
_headData(NULL),
|
||||||
|
_handData(NULL)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AvatarData::~AvatarData() {
|
AvatarData::~AvatarData() {
|
||||||
delete _headData;
|
delete _headData;
|
||||||
|
delete _handData;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
||||||
|
@ -56,6 +58,10 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
||||||
if (!_headData) {
|
if (!_headData) {
|
||||||
_headData = new HeadData(this);
|
_headData = new HeadData(this);
|
||||||
}
|
}
|
||||||
|
// lazily allocate memory for HeadData in case we're not an Avatar instance
|
||||||
|
if (!_handData) {
|
||||||
|
_handData = new HandData(this);
|
||||||
|
}
|
||||||
|
|
||||||
// Body world position
|
// Body world position
|
||||||
memcpy(destinationBuffer, &_position, sizeof(float) * 3);
|
memcpy(destinationBuffer, &_position, sizeof(float) * 3);
|
||||||
|
@ -118,6 +124,16 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
||||||
setSemiNibbleAt(bitItems,HAND_STATE_START_BIT,_handState);
|
setSemiNibbleAt(bitItems,HAND_STATE_START_BIT,_handState);
|
||||||
*destinationBuffer++ = bitItems;
|
*destinationBuffer++ = bitItems;
|
||||||
|
|
||||||
|
// leap hand data
|
||||||
|
const std::vector<glm::vec3>& fingerPositions = _handData->getFingerPositions();
|
||||||
|
*destinationBuffer++ = (unsigned char)fingerPositions.size();
|
||||||
|
for (size_t i = 0; i < fingerPositions.size(); ++i)
|
||||||
|
{
|
||||||
|
destinationBuffer += packFloatScalarToSignedTwoByteFixed(destinationBuffer, fingerPositions[i].x, 4);
|
||||||
|
destinationBuffer += packFloatScalarToSignedTwoByteFixed(destinationBuffer, fingerPositions[i].y, 4);
|
||||||
|
destinationBuffer += packFloatScalarToSignedTwoByteFixed(destinationBuffer, fingerPositions[i].z, 4);
|
||||||
|
}
|
||||||
|
|
||||||
return destinationBuffer - bufferStart;
|
return destinationBuffer - bufferStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +144,12 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||||
if (!_headData) {
|
if (!_headData) {
|
||||||
_headData = new HeadData(this);
|
_headData = new HeadData(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// lazily allocate memory for HandData in case we're not an Avatar instance
|
||||||
|
if (!_handData) {
|
||||||
|
_handData = new HandData(this);
|
||||||
|
}
|
||||||
|
|
||||||
// increment to push past the packet header
|
// increment to push past the packet header
|
||||||
sourceBuffer += sizeof(PACKET_HEADER_HEAD_DATA);
|
sourceBuffer += sizeof(PACKET_HEADER_HEAD_DATA);
|
||||||
|
|
||||||
|
@ -205,6 +226,23 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||||
// hand state, stored as a semi-nibble in the bitItems
|
// hand state, stored as a semi-nibble in the bitItems
|
||||||
_handState = getSemiNibbleAt(bitItems,HAND_STATE_START_BIT);
|
_handState = getSemiNibbleAt(bitItems,HAND_STATE_START_BIT);
|
||||||
|
|
||||||
|
// leap hand data
|
||||||
|
if (sourceBuffer - startPosition < numBytes) // safety check
|
||||||
|
{
|
||||||
|
std::vector<glm::vec3> fingerPositions = _handData->getFingerPositions();
|
||||||
|
unsigned int numFingers = *sourceBuffer++;
|
||||||
|
if (numFingers > MAX_AVATAR_LEAP_BALLS) // safety check
|
||||||
|
numFingers = 0;
|
||||||
|
fingerPositions.resize(numFingers);
|
||||||
|
for (size_t i = 0; i < numFingers; ++i)
|
||||||
|
{
|
||||||
|
sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((uint16_t*) sourceBuffer, &(fingerPositions[i].x), 4);
|
||||||
|
sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((uint16_t*) sourceBuffer, &(fingerPositions[i].y), 4);
|
||||||
|
sourceBuffer += unpackFloatScalarFromSignedTwoByteFixed((uint16_t*) sourceBuffer, &(fingerPositions[i].z), 4);
|
||||||
|
}
|
||||||
|
_handData->setFingerPositions(fingerPositions);
|
||||||
|
}
|
||||||
|
|
||||||
return sourceBuffer - startPosition;
|
return sourceBuffer - startPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,6 +252,18 @@ glm::vec3 AvatarData::calculateCameraDirection() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Allows sending of fixed-point numbers: radix 1 makes 15.1 number, radix 8 makes 8.8 number, etc
|
||||||
|
int packFloatScalarToSignedTwoByteFixed(unsigned char* buffer, float scalar, int radix) {
|
||||||
|
int16_t outVal = (int16_t)(scalar * (float)(1 << radix));
|
||||||
|
memcpy(buffer, &outVal, sizeof(uint16_t));
|
||||||
|
return sizeof(uint16_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
int unpackFloatScalarFromSignedTwoByteFixed(uint16_t* byteFixedPointer, float* destinationPointer, int radix) {
|
||||||
|
*destinationPointer = *byteFixedPointer / (float)(1 << radix);
|
||||||
|
return sizeof(uint16_t);
|
||||||
|
}
|
||||||
|
|
||||||
int packFloatAngleToTwoByte(unsigned char* buffer, float angle) {
|
int packFloatAngleToTwoByte(unsigned char* buffer, float angle) {
|
||||||
const float ANGLE_CONVERSION_RATIO = (std::numeric_limits<uint16_t>::max() / 360.0);
|
const float ANGLE_CONVERSION_RATIO = (std::numeric_limits<uint16_t>::max() / 360.0);
|
||||||
|
|
||||||
|
|
7
libraries/avatars/src/AvatarData.h
Normal file → Executable file
7
libraries/avatars/src/AvatarData.h
Normal file → Executable file
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include <AgentData.h>
|
#include <AgentData.h>
|
||||||
#include "HeadData.h"
|
#include "HeadData.h"
|
||||||
|
#include "HandData.h"
|
||||||
|
|
||||||
const int WANT_RESIN_AT_BIT = 0;
|
const int WANT_RESIN_AT_BIT = 0;
|
||||||
const int WANT_COLOR_AT_BIT = 1;
|
const int WANT_COLOR_AT_BIT = 1;
|
||||||
|
@ -97,6 +98,7 @@ public:
|
||||||
void setWantOcclusionCulling(bool wantOcclusionCulling) { _wantOcclusionCulling = wantOcclusionCulling; }
|
void setWantOcclusionCulling(bool wantOcclusionCulling) { _wantOcclusionCulling = wantOcclusionCulling; }
|
||||||
|
|
||||||
void setHeadData(HeadData* headData) { _headData = headData; }
|
void setHeadData(HeadData* headData) { _headData = headData; }
|
||||||
|
void setHandData(HandData* handData) { _handData = handData; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
glm::vec3 _position;
|
glm::vec3 _position;
|
||||||
|
@ -131,6 +133,7 @@ protected:
|
||||||
bool _wantOcclusionCulling;
|
bool _wantOcclusionCulling;
|
||||||
|
|
||||||
HeadData* _headData;
|
HeadData* _headData;
|
||||||
|
HandData* _handData;
|
||||||
private:
|
private:
|
||||||
// privatize the copy constructor and assignment operator so they cannot be called
|
// privatize the copy constructor and assignment operator so they cannot be called
|
||||||
AvatarData(const AvatarData&);
|
AvatarData(const AvatarData&);
|
||||||
|
@ -164,4 +167,8 @@ int unpackClipValueFromTwoByte(unsigned char* buffer, float& clipValue);
|
||||||
int packFloatToByte(unsigned char* buffer, float value, float scaleBy);
|
int packFloatToByte(unsigned char* buffer, float value, float scaleBy);
|
||||||
int unpackFloatFromByte(unsigned char* buffer, float& value, float scaleBy);
|
int unpackFloatFromByte(unsigned char* buffer, float& value, float scaleBy);
|
||||||
|
|
||||||
|
// Allows sending of fixed-point numbers: radix 1 makes 15.1 number, radix 8 makes 8.8 number, etc
|
||||||
|
int packFloatScalarToSignedTwoByteFixed(unsigned char* buffer, float scalar, int radix);
|
||||||
|
int unpackFloatScalarFromSignedTwoByteFixed(uint16_t* byteFixedPointer, float* destinationPointer, int radix);
|
||||||
|
|
||||||
#endif /* defined(__hifi__AvatarData__) */
|
#endif /* defined(__hifi__AvatarData__) */
|
||||||
|
|
15
libraries/avatars/src/HandData.cpp
Executable file
15
libraries/avatars/src/HandData.cpp
Executable file
|
@ -0,0 +1,15 @@
|
||||||
|
//
|
||||||
|
// HandData.cpp
|
||||||
|
// hifi
|
||||||
|
//
|
||||||
|
// Created by Stephen Birarda on 5/20/13.
|
||||||
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "HandData.h"
|
||||||
|
|
||||||
|
HandData::HandData(AvatarData* owningAvatar) :
|
||||||
|
_owningAvatarData(owningAvatar)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
38
libraries/avatars/src/HandData.h
Executable file
38
libraries/avatars/src/HandData.h
Executable file
|
@ -0,0 +1,38 @@
|
||||||
|
//
|
||||||
|
// HandData.h
|
||||||
|
// hifi
|
||||||
|
//
|
||||||
|
// Created by Eric Johnston on 6/26/13.
|
||||||
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __hifi__HandData__
|
||||||
|
#define __hifi__HandData__
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
#define MAX_AVATAR_LEAP_BALLS 10
|
||||||
|
|
||||||
|
class AvatarData;
|
||||||
|
|
||||||
|
class HandData {
|
||||||
|
public:
|
||||||
|
HandData(AvatarData* owningAvatar);
|
||||||
|
|
||||||
|
const std::vector<glm::vec3>& getFingerPositions() const { return _fingerPositions; }
|
||||||
|
void setFingerPositions(const std::vector<glm::vec3>& fingerPositions) { _fingerPositions = fingerPositions; }
|
||||||
|
|
||||||
|
friend class AvatarData;
|
||||||
|
protected:
|
||||||
|
std::vector<glm::vec3> _fingerPositions;
|
||||||
|
AvatarData* _owningAvatarData;
|
||||||
|
private:
|
||||||
|
// privatize copy ctor and assignment operator so copies of this object cannot be made
|
||||||
|
HandData(const HandData&);
|
||||||
|
HandData& operator= (const HandData&);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* defined(__hifi__HandData__) */
|
Loading…
Reference in a new issue