mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:24:00 +02:00
Hand rework in preparation for adding send/receive hand data
- Added Hand.cpp, Hand.h, HandData.cpp, HandData.h, roughly matching the equivalent Head files - Cleaned up Avatar by moving hand work into Hand files - Added fixed-point data packing, for use in sending hand offsets
This commit is contained in:
parent
ddc85272b9
commit
1c797405da
10 changed files with 258 additions and 73 deletions
|
@ -1674,7 +1674,7 @@ void Application::update(float deltaTime) {
|
|||
|
||||
// Leap finger-sensing device
|
||||
LeapManager::nextFrame();
|
||||
_myAvatar.setLeapFingers(LeapManager::getFingerPositions());
|
||||
_myAvatar.getHand().setLeapFingers(LeapManager::getFingerPositions());
|
||||
|
||||
// Read serial port interface devices
|
||||
if (_serialHeadSensor.isActive()) {
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "world.h"
|
||||
#include "Application.h"
|
||||
#include "Avatar.h"
|
||||
#include "Hand.h"
|
||||
#include "Head.h"
|
||||
#include "Log.h"
|
||||
#include "ui/TextRenderer.h"
|
||||
|
@ -64,6 +65,7 @@ Avatar::Avatar(Agent* owningAgent) :
|
|||
AvatarData(owningAgent),
|
||||
_initialized(false),
|
||||
_head(this),
|
||||
_hand(this),
|
||||
_ballSpringsInitialized(false),
|
||||
_TEST_bigSphereRadius(0.5f),
|
||||
_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
|
||||
_headData = &_head;
|
||||
_handData = &_hand;
|
||||
|
||||
for (int i = 0; i < MAX_DRIVE_KEYS; i++) {
|
||||
_driveKeys[i] = false;
|
||||
|
@ -104,7 +107,6 @@ Avatar::Avatar(Agent* owningAgent) :
|
|||
_skeleton.initialize();
|
||||
|
||||
initializeBodyBalls();
|
||||
initializeLeapBalls();
|
||||
|
||||
_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() {
|
||||
_headData = NULL;
|
||||
_handData = NULL;
|
||||
delete _balls;
|
||||
}
|
||||
|
||||
void Avatar::init() {
|
||||
_head.init();
|
||||
_hand.init();
|
||||
_voxels.init();
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
void Avatar::reset() {
|
||||
_head.reset();
|
||||
_hand.reset();
|
||||
}
|
||||
|
||||
// Update avatar head rotation with sensor data
|
||||
|
@ -543,9 +532,6 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) {
|
|||
// update body balls
|
||||
updateBodyBalls(deltaTime);
|
||||
|
||||
// update leap balls
|
||||
updateLeapBalls(deltaTime);
|
||||
|
||||
// test for avatar collision response with the big sphere
|
||||
if (usingBigSphereCollisionTest) {
|
||||
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;
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
// determine the arm vector
|
||||
|
@ -1306,30 +1275,7 @@ void Avatar::renderBody(bool lookingInMirror, bool renderAvatarBalls) {
|
|||
}
|
||||
}
|
||||
}
|
||||
// Draw the leap balls
|
||||
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();
|
||||
}
|
||||
}
|
||||
_hand.render(lookingInMirror);
|
||||
} else {
|
||||
// Render the body's voxels
|
||||
float alpha = getBallRenderAlpha(BODY_BALL_HEAD_BASE, lookingInMirror);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "InterfaceConfig.h"
|
||||
#include "SerialInterface.h"
|
||||
#include "Balls.h"
|
||||
#include "Hand.h"
|
||||
#include "Head.h"
|
||||
#include "Skeleton.h"
|
||||
#include "Transmitter.h"
|
||||
|
@ -56,8 +57,6 @@ enum AvatarBodyBallID
|
|||
NUM_AVATAR_BODY_BALLS
|
||||
};
|
||||
|
||||
#define MAX_AVATAR_LEAP_BALLS 10
|
||||
|
||||
enum DriveKeys
|
||||
{
|
||||
FWD = 0,
|
||||
|
@ -105,7 +104,6 @@ public:
|
|||
void setGravity (glm::vec3 gravity);
|
||||
void setMouseRay (const glm::vec3 &origin, const glm::vec3 &direction);
|
||||
void setOrientation (const glm::quat& orientation);
|
||||
void setLeapFingers (const std::vector<glm::vec3>& fingerPositions);
|
||||
|
||||
//getters
|
||||
bool isInitialized () const { return _initialized;}
|
||||
|
@ -115,8 +113,6 @@ public:
|
|||
bool getIsNearInteractingOther () const { return _avatarTouch.getAbleToReachOtherAvatar();}
|
||||
const glm::vec3& getHeadJointPosition () const { return _skeleton.joint[ AVATAR_JOINT_HEAD_BASE ].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 getBodyUpDirection () const { return getOrientation() * IDENTITY_UP; }
|
||||
glm::vec3 getBodyFrontDirection () const { return getOrientation() * IDENTITY_FRONT; }
|
||||
|
@ -131,6 +127,7 @@ public:
|
|||
float getAbsoluteHeadYaw () const;
|
||||
float getAbsoluteHeadPitch () const;
|
||||
Head& getHead () {return _head; }
|
||||
Hand& getHand () {return _hand; }
|
||||
glm::quat getOrientation () const;
|
||||
glm::quat getWorldAlignedOrientation() const;
|
||||
|
||||
|
@ -180,6 +177,7 @@ private:
|
|||
|
||||
bool _initialized;
|
||||
Head _head;
|
||||
Hand _hand;
|
||||
Skeleton _skeleton;
|
||||
bool _ballSpringsInitialized;
|
||||
float _TEST_bigSphereRadius;
|
||||
|
@ -190,8 +188,6 @@ private:
|
|||
float _bodyRollDelta;
|
||||
glm::vec3 _movedHandOffset;
|
||||
AvatarBall _bodyBall[ NUM_AVATAR_BODY_BALLS ];
|
||||
AvatarBall _leapBall[ MAX_AVATAR_LEAP_BALLS ];
|
||||
int _numLeapBalls;
|
||||
AvatarMode _mode;
|
||||
glm::vec3 _handHoldingPosition;
|
||||
glm::vec3 _velocity;
|
||||
|
@ -226,10 +222,8 @@ private:
|
|||
float getBallRenderAlpha(int ball, bool lookingInMirror) const;
|
||||
void renderBody(bool lookingInMirror, bool renderAvatarBalls);
|
||||
void initializeBodyBalls();
|
||||
void initializeLeapBalls();
|
||||
void resetBodyBalls();
|
||||
void updateBodyBalls( float deltaTime );
|
||||
void updateLeapBalls( float deltaTime );
|
||||
void calculateBoneLengths();
|
||||
void readSensors();
|
||||
void updateHandMovementAndTouching(float deltaTime);
|
||||
|
|
94
interface/src/Hand.cpp
Executable file
94
interface/src/Hand.cpp
Executable file
|
@ -0,0 +1,94 @@
|
|||
//
|
||||
// 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.0f, 0.4f, 0.0f)
|
||||
{
|
||||
}
|
||||
|
||||
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() {
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
_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
|
||||
|
||||
Head& head = _owningAvatar->getHead();
|
||||
for (int b = 0; b < _numLeapBalls; b++) {
|
||||
glm::vec3 pos = unitScale * fingerPositions[b] + offset;
|
||||
_leapBall[b].rotation = head.getOrientation();
|
||||
_leapBall[b].position = head.getPosition() + head.getOrientation() * pos;
|
||||
}
|
||||
}
|
||||
|
||||
|
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 "Balls.h"
|
||||
#include "world.h"
|
||||
#include "InterfaceConfig.h"
|
||||
#include "SerialInterface.h"
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#define MAX_AVATAR_LEAP_BALLS 10
|
||||
|
||||
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 setFingerPositions(std::vector<glm::vec3> fingerPositions) { _fingerPositions = fingerPositions; }
|
||||
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;
|
||||
std::vector<glm::vec3> _fingerPositions;
|
||||
glm::vec3 _ballColor;
|
||||
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 getCameraOrientation (float pitchYawScale) const;
|
||||
|
||||
glm::vec3 getPosition() const { return _position; }
|
||||
glm::vec3 getRightDirection() const { return getOrientation() * IDENTITY_RIGHT; }
|
||||
glm::vec3 getUpDirection () const { return getOrientation() * IDENTITY_UP; }
|
||||
glm::vec3 getFrontDirection() const { return getOrientation() * IDENTITY_FRONT; }
|
||||
|
|
27
libraries/avatars/src/AvatarData.cpp
Normal file → Executable file
27
libraries/avatars/src/AvatarData.cpp
Normal file → Executable file
|
@ -36,13 +36,15 @@ AvatarData::AvatarData(Agent* owningAgent) :
|
|||
_wantColor(true),
|
||||
_wantDelta(false),
|
||||
_wantOcclusionCulling(false),
|
||||
_headData(NULL)
|
||||
_headData(NULL),
|
||||
_handData(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
AvatarData::~AvatarData() {
|
||||
delete _headData;
|
||||
delete _handData;
|
||||
}
|
||||
|
||||
int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
||||
|
@ -56,6 +58,10 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
|||
if (!_headData) {
|
||||
_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
|
||||
memcpy(destinationBuffer, &_position, sizeof(float) * 3);
|
||||
|
@ -128,7 +134,12 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
|||
if (!_headData) {
|
||||
_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
|
||||
sourceBuffer += sizeof(PACKET_HEADER_HEAD_DATA);
|
||||
|
||||
|
@ -214,6 +225,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) {
|
||||
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 "HeadData.h"
|
||||
#include "HandData.h"
|
||||
|
||||
const int WANT_RESIN_AT_BIT = 0;
|
||||
const int WANT_COLOR_AT_BIT = 1;
|
||||
|
@ -97,6 +98,7 @@ public:
|
|||
void setWantOcclusionCulling(bool wantOcclusionCulling) { _wantOcclusionCulling = wantOcclusionCulling; }
|
||||
|
||||
void setHeadData(HeadData* headData) { _headData = headData; }
|
||||
void setHandData(HandData* handData) { _handData = handData; }
|
||||
|
||||
protected:
|
||||
glm::vec3 _position;
|
||||
|
@ -131,6 +133,7 @@ protected:
|
|||
bool _wantOcclusionCulling;
|
||||
|
||||
HeadData* _headData;
|
||||
HandData* _handData;
|
||||
private:
|
||||
// privatize the copy constructor and assignment operator so they cannot be called
|
||||
AvatarData(const AvatarData&);
|
||||
|
@ -164,4 +167,8 @@ int unpackClipValueFromTwoByte(unsigned char* buffer, float& clipValue);
|
|||
int packFloatToByte(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__) */
|
||||
|
|
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)
|
||||
{
|
||||
|
||||
}
|
36
libraries/avatars/src/HandData.h
Executable file
36
libraries/avatars/src/HandData.h
Executable file
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// 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>
|
||||
|
||||
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