mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 18:25:52 +02:00
Merge pull request #361 from birarda/head-changes
add a HeadData class to reduce redundancy for head member variables
This commit is contained in:
commit
d1554e0150
9 changed files with 204 additions and 167 deletions
|
@ -298,8 +298,9 @@ void Application::paintGL() {
|
||||||
_myCamera.setDistance (0.0f);
|
_myCamera.setDistance (0.0f);
|
||||||
_myCamera.setTightness (100.0f);
|
_myCamera.setTightness (100.0f);
|
||||||
_myCamera.setTargetPosition(_myAvatar.getHeadPosition());
|
_myCamera.setTargetPosition(_myAvatar.getHeadPosition());
|
||||||
_myCamera.setTargetRotation(_myAvatar.getBodyYaw() + _myAvatar.getHeadYaw(),
|
_myCamera.setTargetRotation(_myAvatar.getBodyYaw() + _myAvatar.getHead().getYaw(),
|
||||||
-_myAvatar.getHeadPitch(), _myAvatar.getHeadRoll());
|
-_myAvatar.getHead().getPitch(),
|
||||||
|
_myAvatar.getHead().getRoll());
|
||||||
|
|
||||||
} else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
|
} else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||||
_myCamera.setTightness (100.0f);
|
_myCamera.setTightness (100.0f);
|
||||||
|
@ -1364,29 +1365,13 @@ void Application::updateAvatar(float deltaTime) {
|
||||||
_headMouseY = max(_headMouseY, 0);
|
_headMouseY = max(_headMouseY, 0);
|
||||||
_headMouseY = min(_headMouseY, _glWidget->height());
|
_headMouseY = min(_headMouseY, _glWidget->height());
|
||||||
|
|
||||||
// Update head and body pitch and yaw based on measured gyro rates
|
|
||||||
if (_gyroLook->isChecked()) {
|
|
||||||
// Render Yaw
|
|
||||||
/* NOTE: PER - Leave here until I get back and can modify to couple gyros to head pitch, yaw
|
|
||||||
float renderYawSpring = fabs(_headMouseX - _glWidget->width() / 2.f) / (_glWidget->width() / 2.f);
|
|
||||||
const float RENDER_YAW_MULTIPLY = 4.f;
|
|
||||||
_myAvatar.setRenderYaw((1.f - renderYawSpring * deltaTime) * _myAvatar.getRenderYaw() +
|
|
||||||
renderYawSpring * deltaTime * -_myAvatar.getHeadYaw() * RENDER_YAW_MULTIPLY);
|
|
||||||
// Render Pitch
|
|
||||||
float renderPitchSpring = fabs(_headMouseY - _glWidget->height() / 2.f) / (_glWidget->height() / 2.f);
|
|
||||||
const float RENDER_PITCH_MULTIPLY = 4.f;
|
|
||||||
_myAvatar.setRenderPitch((1.f - renderPitchSpring * deltaTime) * _myAvatar.getRenderPitch() +
|
|
||||||
renderPitchSpring * deltaTime * -_myAvatar.getHeadPitch() * RENDER_PITCH_MULTIPLY);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OculusManager::isConnected()) {
|
if (OculusManager::isConnected()) {
|
||||||
float yaw, pitch, roll;
|
float yaw, pitch, roll;
|
||||||
OculusManager::getEulerAngles(yaw, pitch, roll);
|
OculusManager::getEulerAngles(yaw, pitch, roll);
|
||||||
|
|
||||||
_myAvatar.setHeadYaw(-yaw);
|
_myAvatar.getHead().setYaw(-yaw);
|
||||||
_myAvatar.setHeadPitch(pitch);
|
_myAvatar.getHead().setPitch(pitch);
|
||||||
_myAvatar.setHeadRoll(roll);
|
_myAvatar.getHead().setRoll(roll);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get audio loudness data from audio input device
|
// Get audio loudness data from audio input device
|
||||||
|
|
|
@ -59,57 +59,68 @@ bool usingBigSphereCollisionTest = true;
|
||||||
float chatMessageScale = 0.0015;
|
float chatMessageScale = 0.0015;
|
||||||
float chatMessageHeight = 0.45;
|
float chatMessageHeight = 0.45;
|
||||||
|
|
||||||
|
Avatar::Avatar(bool isMine) :
|
||||||
Avatar::Avatar(bool isMine) {
|
_isMine(isMine),
|
||||||
_orientation.setToIdentity();
|
_TEST_bigSphereRadius(0.4f),
|
||||||
|
_TEST_bigSpherePosition(5.0f, _TEST_bigSphereRadius, 5.0f),
|
||||||
|
_mousePressed(false),
|
||||||
|
_bodyPitchDelta(0.0f),
|
||||||
|
_bodyYawDelta(0.0f),
|
||||||
|
_bodyRollDelta(0.0f),
|
||||||
|
_movedHandOffset(0.0f, 0.0f, 0.0f),
|
||||||
|
_rotation(0.0f, 0.0f, 0.0f, 0.0f),
|
||||||
|
_mode(AVATAR_MODE_STANDING),
|
||||||
|
_handHoldingPosition(0.0f, 0.0f, 0.0f),
|
||||||
|
_velocity(0.0f, 0.0f, 0.0f),
|
||||||
|
_thrust(0.0f, 0.0f, 0.0f),
|
||||||
|
_speed(0.0f),
|
||||||
|
_maxArmLength(0.0f),
|
||||||
|
_orientation(),
|
||||||
|
_transmitterIsFirstData(true),
|
||||||
|
_transmitterHz(0.0f),
|
||||||
|
_transmitterPackets(0),
|
||||||
|
_transmitterInitialReading(0.0f, 0.0f, 0.0f),
|
||||||
|
_isTransmitterV2Connected(false),
|
||||||
|
_pelvisStandingHeight(0.0f),
|
||||||
|
_displayingHead(true),
|
||||||
|
_distanceToNearestAvatar(std::numeric_limits<float>::max()),
|
||||||
|
_gravity(0.0f, -1.0f, 0.0f),
|
||||||
|
_mouseRayOrigin(0.0f, 0.0f, 0.0f),
|
||||||
|
_mouseRayDirection(0.0f, 0.0f, 0.0f),
|
||||||
|
_cameraPosition(0.0f, 0.0f, 0.0f),
|
||||||
|
_interactingOther(NULL),
|
||||||
|
_cumulativeMouseYaw(0.0f),
|
||||||
|
_isMouseTurningRight(false)
|
||||||
|
{
|
||||||
|
|
||||||
_velocity = glm::vec3(0.0f, 0.0f, 0.0f);
|
// give the pointer to our head to inherited _headData variable from AvatarData
|
||||||
_thrust = glm::vec3(0.0f, 0.0f, 0.0f);
|
_headData = &_head;
|
||||||
_rotation = glm::quat(0.0f, 0.0f, 0.0f, 0.0f);
|
|
||||||
_bodyYaw = -90.0;
|
|
||||||
_bodyPitch = 0.0;
|
|
||||||
_bodyRoll = 0.0;
|
|
||||||
_bodyPitchDelta = 0.0;
|
|
||||||
_bodyYawDelta = 0.0;
|
|
||||||
_bodyRollDelta = 0.0;
|
|
||||||
_mousePressed = false;
|
|
||||||
_mode = AVATAR_MODE_STANDING;
|
|
||||||
_isMine = isMine;
|
|
||||||
_maxArmLength = 0.0;
|
|
||||||
_transmitterHz = 0.0;
|
|
||||||
_transmitterPackets = 0;
|
|
||||||
_transmitterIsFirstData = true;
|
|
||||||
_transmitterInitialReading = glm::vec3(0.f, 0.f, 0.f);
|
|
||||||
_isTransmitterV2Connected = false;
|
|
||||||
_speed = 0.0;
|
|
||||||
_pelvisStandingHeight = 0.0f;
|
|
||||||
_displayingHead = true;
|
|
||||||
_TEST_bigSphereRadius = 0.4f;
|
|
||||||
_TEST_bigSpherePosition = glm::vec3(5.0f, _TEST_bigSphereRadius, 5.0f);
|
|
||||||
_mouseRayOrigin = glm::vec3(0.0f, 0.0f, 0.0f);
|
|
||||||
_mouseRayDirection = glm::vec3(0.0f, 0.0f, 0.0f);
|
|
||||||
_cameraPosition = glm::vec3(0.0f, 0.0f, 0.0f);
|
|
||||||
_interactingOther = NULL;
|
|
||||||
|
|
||||||
for (int i = 0; i < MAX_DRIVE_KEYS; i++) _driveKeys[i] = false;
|
|
||||||
|
for (int i = 0; i < MAX_DRIVE_KEYS; i++) {
|
||||||
_movedHandOffset = glm::vec3(0.0f, 0.0f, 0.0f);
|
_driveKeys[i] = false;
|
||||||
_handHoldingPosition = glm::vec3(0.0f, 0.0f, 0.0f);
|
}
|
||||||
_distanceToNearestAvatar = std::numeric_limits<float>::max();
|
|
||||||
_gravity = glm::vec3(0.0f, -1.0f, 0.0f);
|
|
||||||
_cumulativeMouseYaw = 0.f;
|
|
||||||
_isMouseTurningRight = false;
|
|
||||||
|
|
||||||
initializeSkeleton();
|
initializeSkeleton();
|
||||||
|
|
||||||
_avatarTouch.setReachableRadius(PERIPERSONAL_RADIUS);
|
_avatarTouch.setReachableRadius(PERIPERSONAL_RADIUS);
|
||||||
|
|
||||||
if (BALLS_ON) { _balls = new Balls(100); }
|
if (BALLS_ON) {
|
||||||
else { _balls = NULL; }
|
_balls = new Balls(100);
|
||||||
|
} else {
|
||||||
|
_balls = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Avatar::~Avatar() {
|
||||||
|
_headData = NULL;
|
||||||
|
delete _balls;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::reset() {
|
void Avatar::reset() {
|
||||||
_headPitch = _headYaw = _headRoll = 0;
|
_head.setYaw(0.0f);
|
||||||
|
_head.setRoll(0.0f);
|
||||||
|
_head.setPitch(0.0f);
|
||||||
_head.leanForward = _head.leanSideways = 0;
|
_head.leanForward = _head.leanSideways = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,23 +135,16 @@ void Avatar::updateHeadFromGyros(float deltaTime, SerialInterface* serialInterfa
|
||||||
measuredRollRate = serialInterface->getLastRollRate();
|
measuredRollRate = serialInterface->getLastRollRate();
|
||||||
|
|
||||||
// Update avatar head position based on measured gyro rates
|
// Update avatar head position based on measured gyro rates
|
||||||
const float MAX_YAW = 85;
|
|
||||||
const float MIN_YAW = -85;
|
|
||||||
const float MAX_ROLL = 50;
|
|
||||||
const float MIN_ROLL = -50;
|
|
||||||
|
|
||||||
addHeadPitch(measuredPitchRate * deltaTime);
|
_head.addPitch(measuredPitchRate * deltaTime);
|
||||||
addHeadYaw(measuredYawRate * deltaTime);
|
_head.addYaw(measuredYawRate * deltaTime);
|
||||||
addHeadRoll(measuredRollRate * deltaTime);
|
_head.addRoll(measuredRollRate * deltaTime);
|
||||||
|
|
||||||
setHeadYaw(glm::clamp(getHeadYaw(), MIN_YAW, MAX_YAW));
|
|
||||||
setHeadRoll(glm::clamp(getHeadRoll(), MIN_ROLL, MAX_ROLL));
|
|
||||||
|
|
||||||
// Update head lean distance based on accelerometer data
|
// Update head lean distance based on accelerometer data
|
||||||
const float LEAN_SENSITIVITY = 0.15;
|
const float LEAN_SENSITIVITY = 0.15;
|
||||||
const float LEAN_MAX = 0.45;
|
const float LEAN_MAX = 0.45;
|
||||||
const float LEAN_AVERAGING = 10.0;
|
const float LEAN_AVERAGING = 10.0;
|
||||||
glm::vec3 headRotationRates(getHeadPitch(), getHeadYaw(), getHeadRoll());
|
glm::vec3 headRotationRates(_head.getPitch(), _head.getYaw(), _head.getRoll());
|
||||||
float headRateMax = 50.f;
|
float headRateMax = 50.f;
|
||||||
|
|
||||||
|
|
||||||
|
@ -159,11 +163,11 @@ void Avatar::updateHeadFromGyros(float deltaTime, SerialInterface* serialInterfa
|
||||||
}
|
}
|
||||||
|
|
||||||
float Avatar::getAbsoluteHeadYaw() const {
|
float Avatar::getAbsoluteHeadYaw() const {
|
||||||
return _bodyYaw + _headYaw;
|
return _bodyYaw + _head.getYaw();
|
||||||
}
|
}
|
||||||
|
|
||||||
float Avatar::getAbsoluteHeadPitch() const {
|
float Avatar::getAbsoluteHeadPitch() const {
|
||||||
return _bodyPitch + _headPitch;
|
return _bodyPitch + _head.getPitch();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::addLean(float x, float z) {
|
void Avatar::addLean(float x, float z) {
|
||||||
|
@ -221,7 +225,7 @@ void Avatar::updateFromMouse(int mouseX, int mouseY, int screenWidth, int scree
|
||||||
if (fabs(mouseLocationY) > MOUSE_MOVE_RADIUS) {
|
if (fabs(mouseLocationY) > MOUSE_MOVE_RADIUS) {
|
||||||
float mousePitchAdd = (fabs(mouseLocationY) - MOUSE_MOVE_RADIUS) / (0.5f - MOUSE_MOVE_RADIUS) * MOUSE_PITCH_SPEED;
|
float mousePitchAdd = (fabs(mouseLocationY) - MOUSE_MOVE_RADIUS) / (0.5f - MOUSE_MOVE_RADIUS) * MOUSE_PITCH_SPEED;
|
||||||
bool downPitching = (mouseLocationY > 0.f);
|
bool downPitching = (mouseLocationY > 0.f);
|
||||||
setHeadPitch(getHeadPitch() + (downPitching ? mousePitchAdd : -mousePitchAdd));
|
_head.setPitch(_head.getPitch() + (downPitching ? mousePitchAdd : -mousePitchAdd));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -354,7 +358,7 @@ void Avatar::simulate(float deltaTime) {
|
||||||
// Decay HeadPitch as a function of acceleration, so that you look straight ahead when
|
// Decay HeadPitch as a function of acceleration, so that you look straight ahead when
|
||||||
// you start moving, but don't do this with an HMD like the Oculus.
|
// you start moving, but don't do this with an HMD like the Oculus.
|
||||||
if (!OculusManager::isConnected()) {
|
if (!OculusManager::isConnected()) {
|
||||||
setHeadPitch(getHeadPitch() * (1.f - acceleration * ACCELERATION_PITCH_DECAY * deltaTime));
|
_head.setPitch(_head.getPitch() * (1.f - acceleration * ACCELERATION_PITCH_DECAY * deltaTime));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get head position data from network for other people
|
// Get head position data from network for other people
|
||||||
|
@ -389,26 +393,21 @@ void Avatar::simulate(float deltaTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// update head state
|
// update head state
|
||||||
_head.setPositionRotationAndScale(
|
_head.setPositionAndScale(_joint[AVATAR_JOINT_HEAD_BASE].springyPosition, _joint[AVATAR_JOINT_HEAD_BASE].radius);
|
||||||
_joint[ AVATAR_JOINT_HEAD_BASE ].springyPosition,
|
|
||||||
glm::vec3(_headYaw, _headPitch, _headRoll),
|
|
||||||
_joint[ AVATAR_JOINT_HEAD_BASE ].radius
|
|
||||||
);
|
|
||||||
|
|
||||||
setLookatPosition(glm::vec3(0.0f, 0.0f, 0.0f)); //default lookat position is 0,0,0
|
_head.setLookAtPosition(glm::vec3(0.0f, 0.0f, 0.0f)); //default lookat position is 0,0,0
|
||||||
|
|
||||||
if (_interactingOther) {
|
if (_interactingOther) {
|
||||||
_head.setLooking(true);
|
_head.setLooking(true);
|
||||||
|
|
||||||
if (_isMine) {
|
if (_isMine) {
|
||||||
setLookatPosition(_interactingOther->getSpringyHeadPosition());
|
_head.setLookAtPosition(_interactingOther->getSpringyHeadPosition());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_head.setLooking(false);
|
_head.setLooking(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
_head.setBodyYaw(_bodyYaw);
|
_head.setBodyYaw(_bodyYaw);
|
||||||
_head.setLookatPosition(_lookatPosition);
|
|
||||||
_head.setAudioLoudness(_audioLoudness);
|
_head.setAudioLoudness(_audioLoudness);
|
||||||
_head.setSkinColor(glm::vec3(skinColor[0], skinColor[1], skinColor[2]));
|
_head.setSkinColor(glm::vec3(skinColor[0], skinColor[1], skinColor[2]));
|
||||||
_head.simulate(deltaTime, _isMine);
|
_head.simulate(deltaTime, _isMine);
|
||||||
|
@ -1334,27 +1333,21 @@ void Avatar::setHeadFromGyros(glm::vec3* eulerAngles, glm::vec3* angularVelocity
|
||||||
// absolute eulerAngles passed.
|
// absolute eulerAngles passed.
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
float const MAX_YAW = 90.f;
|
|
||||||
float const MIN_YAW = -90.f;
|
|
||||||
float const MAX_PITCH = 85.f;
|
|
||||||
float const MIN_PITCH = -85.f;
|
|
||||||
float const MAX_ROLL = 90.f;
|
|
||||||
float const MIN_ROLL = -90.f;
|
|
||||||
|
|
||||||
if (deltaTime == 0.f) {
|
if (deltaTime == 0.f) {
|
||||||
// On first sample, set head to absolute position
|
// On first sample, set head to absolute position
|
||||||
setHeadYaw(eulerAngles->x);
|
_head.setYaw(eulerAngles->x);
|
||||||
setHeadPitch(eulerAngles->y);
|
_head.setPitch(eulerAngles->y);
|
||||||
setHeadRoll(eulerAngles->z);
|
_head.setRoll(eulerAngles->z);
|
||||||
} else {
|
} else {
|
||||||
glm::vec3 angles(getHeadYaw(), getHeadPitch(), getHeadRoll());
|
glm::vec3 angles(_head.getYaw(), _head.getPitch(), _head.getRoll());
|
||||||
// Increment by detected velocity
|
// Increment by detected velocity
|
||||||
angles += (*angularVelocity) * deltaTime;
|
angles += (*angularVelocity) * deltaTime;
|
||||||
// Smooth to slowly follow absolute values
|
// Smooth to slowly follow absolute values
|
||||||
angles = ((1.f - deltaTime / smoothingTime) * angles) + (deltaTime / smoothingTime) * (*eulerAngles);
|
angles = ((1.f - deltaTime / smoothingTime) * angles) + (deltaTime / smoothingTime) * (*eulerAngles);
|
||||||
setHeadYaw(fmin(fmax(angles.x, MIN_YAW), MAX_YAW));
|
_head.setYaw(angles.x);
|
||||||
setHeadPitch(fmin(fmax(angles.y, MIN_PITCH), MAX_PITCH));
|
_head.setPitch(angles.y);
|
||||||
setHeadRoll(fmin(fmax(angles.z, MIN_ROLL), MAX_ROLL));
|
_head.setRoll(angles.z);
|
||||||
//printLog("Y/P/R: %3.1f, %3.1f, %3.1f\n", angles.x, angles.y, angles.z);
|
//printLog("Y/P/R: %3.1f, %3.1f, %3.1f\n", angles.x, angles.y, angles.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,7 @@ enum AvatarJointID
|
||||||
class Avatar : public AvatarData {
|
class Avatar : public AvatarData {
|
||||||
public:
|
public:
|
||||||
Avatar(bool isMine);
|
Avatar(bool isMine);
|
||||||
|
~Avatar();
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
void updateHeadFromGyros(float frametime, SerialInterface * serialInterface, glm::vec3 * gravity);
|
void updateHeadFromGyros(float frametime, SerialInterface * serialInterface, glm::vec3 * gravity);
|
||||||
|
@ -106,6 +107,7 @@ public:
|
||||||
float getHeight() const { return _height; }
|
float getHeight() const { return _height; }
|
||||||
|
|
||||||
AvatarMode getMode() const { return _mode; }
|
AvatarMode getMode() const { return _mode; }
|
||||||
|
Head getHead() const { return _head; }
|
||||||
|
|
||||||
void setMousePressed(bool pressed);
|
void setMousePressed(bool pressed);
|
||||||
void render(bool lookingInMirror, glm::vec3 cameraPosition);
|
void render(bool lookingInMirror, glm::vec3 cameraPosition);
|
||||||
|
@ -163,8 +165,8 @@ private:
|
||||||
|
|
||||||
Head _head;
|
Head _head;
|
||||||
bool _isMine;
|
bool _isMine;
|
||||||
glm::vec3 _TEST_bigSpherePosition;
|
|
||||||
float _TEST_bigSphereRadius;
|
float _TEST_bigSphereRadius;
|
||||||
|
glm::vec3 _TEST_bigSpherePosition;
|
||||||
bool _mousePressed;
|
bool _mousePressed;
|
||||||
float _bodyPitchDelta;
|
float _bodyPitchDelta;
|
||||||
float _bodyYawDelta;
|
float _bodyYawDelta;
|
||||||
|
@ -180,8 +182,6 @@ private:
|
||||||
float _maxArmLength;
|
float _maxArmLength;
|
||||||
Orientation _orientation;
|
Orientation _orientation;
|
||||||
int _driveKeys[MAX_DRIVE_KEYS];
|
int _driveKeys[MAX_DRIVE_KEYS];
|
||||||
float _renderYaw;
|
|
||||||
float _renderPitch; // Pitch from view frustum when this is own head
|
|
||||||
bool _transmitterIsFirstData;
|
bool _transmitterIsFirstData;
|
||||||
timeval _transmitterTimeLastReceived;
|
timeval _transmitterTimeLastReceived;
|
||||||
timeval _transmitterTimer;
|
timeval _transmitterTimer;
|
||||||
|
|
|
@ -45,10 +45,6 @@ Head::Head() :
|
||||||
_skinColor(0.0f, 0.0f, 0.0f),
|
_skinColor(0.0f, 0.0f, 0.0f),
|
||||||
_position(0.0f, 0.0f, 0.0f),
|
_position(0.0f, 0.0f, 0.0f),
|
||||||
_rotation(0.0f, 0.0f, 0.0f),
|
_rotation(0.0f, 0.0f, 0.0f),
|
||||||
_lookatPosition(0.0f, 0.0f, 0.0f),
|
|
||||||
_yaw(0.0f),
|
|
||||||
_pitch(0.0f),
|
|
||||||
_roll(0.0f),
|
|
||||||
_eyeballPitch(),
|
_eyeballPitch(),
|
||||||
_eyeballYaw(),
|
_eyeballYaw(),
|
||||||
_interBrowDistance(0.75f),
|
_interBrowDistance(0.75f),
|
||||||
|
@ -77,12 +73,9 @@ Head::Head() :
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Head::setPositionRotationAndScale(glm::vec3 p, glm::vec3 r, float s) {
|
void Head::setPositionAndScale(glm::vec3 position, float scale) {
|
||||||
_position = p;
|
_position = position;
|
||||||
_scale = s;
|
_scale = scale;
|
||||||
_yaw = r.x;
|
|
||||||
_pitch = r.y;
|
|
||||||
_roll = r.z;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Head::setNewTarget(float pitch, float yaw) {
|
void Head::setNewTarget(float pitch, float yaw) {
|
||||||
|
@ -230,7 +223,7 @@ void Head::setLooking(bool looking) {
|
||||||
_lookingAtSomething = looking;
|
_lookingAtSomething = looking;
|
||||||
|
|
||||||
glm::vec3 averageEyePosition = _leftEyePosition + (_rightEyePosition - _leftEyePosition ) * ONE_HALF;
|
glm::vec3 averageEyePosition = _leftEyePosition + (_rightEyePosition - _leftEyePosition ) * ONE_HALF;
|
||||||
glm::vec3 targetLookatAxis = glm::normalize(_lookatPosition - averageEyePosition);
|
glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition - averageEyePosition);
|
||||||
|
|
||||||
float dot = glm::dot(targetLookatAxis, _orientation.getFront());
|
float dot = glm::dot(targetLookatAxis, _orientation.getFront());
|
||||||
if (dot < MINIMUM_EYE_ROTATION) {
|
if (dot < MINIMUM_EYE_ROTATION) {
|
||||||
|
@ -376,7 +369,7 @@ void Head::renderEyeBalls() {
|
||||||
if (_lookingAtSomething) {
|
if (_lookingAtSomething) {
|
||||||
|
|
||||||
//rotate the eyeball to aim towards the lookat position
|
//rotate the eyeball to aim towards the lookat position
|
||||||
glm::vec3 targetLookatAxis = glm::normalize(_lookatPosition - _leftEyePosition); // the lookat direction
|
glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition - _leftEyePosition); // the lookat direction
|
||||||
glm::vec3 rotationAxis = glm::cross(targetLookatAxis, IDENTITY_UP);
|
glm::vec3 rotationAxis = glm::cross(targetLookatAxis, IDENTITY_UP);
|
||||||
float angle = 180.0f - angleBetween(targetLookatAxis, IDENTITY_UP);
|
float angle = 180.0f - angleBetween(targetLookatAxis, IDENTITY_UP);
|
||||||
glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z);
|
glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z);
|
||||||
|
@ -420,7 +413,7 @@ void Head::renderEyeBalls() {
|
||||||
if (_lookingAtSomething) {
|
if (_lookingAtSomething) {
|
||||||
|
|
||||||
//rotate the eyeball to aim towards the lookat position
|
//rotate the eyeball to aim towards the lookat position
|
||||||
glm::vec3 targetLookatAxis = glm::normalize(_lookatPosition - _rightEyePosition);
|
glm::vec3 targetLookatAxis = glm::normalize(_lookAtPosition - _rightEyePosition);
|
||||||
glm::vec3 rotationAxis = glm::cross(targetLookatAxis, IDENTITY_UP);
|
glm::vec3 rotationAxis = glm::cross(targetLookatAxis, IDENTITY_UP);
|
||||||
float angle = 180.0f - angleBetween(targetLookatAxis, IDENTITY_UP);
|
float angle = 180.0f - angleBetween(targetLookatAxis, IDENTITY_UP);
|
||||||
glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z);
|
glRotatef(angle, rotationAxis.x, rotationAxis.y, rotationAxis.z);
|
||||||
|
|
|
@ -23,7 +23,7 @@ enum eyeContactTargets
|
||||||
MOUTH
|
MOUTH
|
||||||
};
|
};
|
||||||
|
|
||||||
class Head {
|
class Head : public HeadData {
|
||||||
public:
|
public:
|
||||||
Head();
|
Head();
|
||||||
|
|
||||||
|
@ -31,10 +31,9 @@ public:
|
||||||
void render(bool lookingInMirror);
|
void render(bool lookingInMirror);
|
||||||
|
|
||||||
void setLooking(bool looking);
|
void setLooking(bool looking);
|
||||||
void setPositionRotationAndScale(glm::vec3 position, glm::vec3 rotation, float scale);
|
void setPositionAndScale(glm::vec3 position, float scale);
|
||||||
void setNewTarget(float, float);
|
void setNewTarget(float, float);
|
||||||
|
|
||||||
void setLookatPosition (glm::vec3 lookatPosition ) { _lookatPosition = lookatPosition; }
|
|
||||||
void setGravity (glm::vec3 gravity ) { _gravity = gravity; }
|
void setGravity (glm::vec3 gravity ) { _gravity = gravity; }
|
||||||
void setSkinColor (glm::vec3 skinColor ) { _skinColor = skinColor; }
|
void setSkinColor (glm::vec3 skinColor ) { _skinColor = skinColor; }
|
||||||
void setBodyYaw (float bodyYaw ) { _bodyYaw = bodyYaw; }
|
void setBodyYaw (float bodyYaw ) { _bodyYaw = bodyYaw; }
|
||||||
|
@ -60,12 +59,8 @@ private:
|
||||||
glm::vec3 _skinColor;
|
glm::vec3 _skinColor;
|
||||||
glm::vec3 _position;
|
glm::vec3 _position;
|
||||||
glm::vec3 _rotation;
|
glm::vec3 _rotation;
|
||||||
glm::vec3 _lookatPosition;
|
|
||||||
glm::vec3 _leftEyePosition;
|
glm::vec3 _leftEyePosition;
|
||||||
glm::vec3 _rightEyePosition;
|
glm::vec3 _rightEyePosition;
|
||||||
float _yaw;
|
|
||||||
float _pitch;
|
|
||||||
float _roll;
|
|
||||||
float _eyeballPitch[2];
|
float _eyeballPitch[2];
|
||||||
float _eyeballYaw [2];
|
float _eyeballYaw [2];
|
||||||
float _eyebrowPitch[2];
|
float _eyebrowPitch[2];
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
// hifi
|
// hifi
|
||||||
//
|
//
|
||||||
// Created by Stephen Birarda on 4/9/13.
|
// Created by Stephen Birarda on 4/9/13.
|
||||||
//
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
@ -35,13 +35,9 @@ int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPo
|
||||||
|
|
||||||
AvatarData::AvatarData() :
|
AvatarData::AvatarData() :
|
||||||
_handPosition(0,0,0),
|
_handPosition(0,0,0),
|
||||||
_lookatPosition(0,0,0),
|
|
||||||
_bodyYaw(-90.0),
|
_bodyYaw(-90.0),
|
||||||
_bodyPitch(0.0),
|
_bodyPitch(0.0),
|
||||||
_bodyRoll(0.0),
|
_bodyRoll(0.0),
|
||||||
_headYaw(0),
|
|
||||||
_headPitch(0),
|
|
||||||
_headRoll(0),
|
|
||||||
_headLeanSideways(0),
|
_headLeanSideways(0),
|
||||||
_headLeanForward(0),
|
_headLeanForward(0),
|
||||||
_audioLoudness(0),
|
_audioLoudness(0),
|
||||||
|
@ -57,11 +53,16 @@ AvatarData::AvatarData() :
|
||||||
_keyState(NO_KEY_DOWN),
|
_keyState(NO_KEY_DOWN),
|
||||||
_wantResIn(false),
|
_wantResIn(false),
|
||||||
_wantColor(true),
|
_wantColor(true),
|
||||||
_wantDelta(false)
|
_wantDelta(false),
|
||||||
|
_headData(NULL)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AvatarData::~AvatarData() {
|
||||||
|
delete _headData;
|
||||||
|
}
|
||||||
|
|
||||||
int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
||||||
unsigned char* bufferStart = destinationBuffer;
|
unsigned char* bufferStart = destinationBuffer;
|
||||||
|
|
||||||
|
@ -79,9 +80,9 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
||||||
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll);
|
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll);
|
||||||
|
|
||||||
// Head rotation (NOTE: This needs to become a quaternion to save two bytes)
|
// Head rotation (NOTE: This needs to become a quaternion to save two bytes)
|
||||||
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headYaw);
|
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->_yaw);
|
||||||
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headPitch);
|
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->_pitch);
|
||||||
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headRoll);
|
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->_roll);
|
||||||
|
|
||||||
// Head lean X,Z (head lateral and fwd/back motion relative to torso)
|
// Head lean X,Z (head lateral and fwd/back motion relative to torso)
|
||||||
memcpy(destinationBuffer, &_headLeanSideways, sizeof(float));
|
memcpy(destinationBuffer, &_headLeanSideways, sizeof(float));
|
||||||
|
@ -94,8 +95,8 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
||||||
destinationBuffer += sizeof(float) * 3;
|
destinationBuffer += sizeof(float) * 3;
|
||||||
|
|
||||||
// Lookat Position
|
// Lookat Position
|
||||||
memcpy(destinationBuffer, &_lookatPosition, sizeof(_lookatPosition));
|
memcpy(destinationBuffer, &_headData->_lookAtPosition, sizeof(_headData->_lookAtPosition));
|
||||||
destinationBuffer += sizeof(_lookatPosition);
|
destinationBuffer += sizeof(_headData->_lookAtPosition);
|
||||||
|
|
||||||
// Hand State (0 = not grabbing, 1 = grabbing)
|
// Hand State (0 = not grabbing, 1 = grabbing)
|
||||||
memcpy(destinationBuffer, &_handState, sizeof(char));
|
memcpy(destinationBuffer, &_handState, sizeof(char));
|
||||||
|
@ -145,7 +146,10 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
|
||||||
// called on the other agents - assigns it to my views of the others
|
// called on the other agents - assigns it to my views of the others
|
||||||
int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||||
|
|
||||||
//printf("AvatarData::parseData()\n");
|
// lazily allocate memory for HeadData in case we're not an Avatar instance
|
||||||
|
if (!_headData) {
|
||||||
|
_headData = new HeadData();
|
||||||
|
}
|
||||||
|
|
||||||
// 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);
|
||||||
|
@ -160,14 +164,19 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||||
sourceBuffer += sizeof(float) * 3;
|
sourceBuffer += sizeof(float) * 3;
|
||||||
|
|
||||||
// Body rotation (NOTE: This needs to become a quaternion to save two bytes)
|
// Body rotation (NOTE: This needs to become a quaternion to save two bytes)
|
||||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyYaw);
|
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyYaw);
|
||||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyPitch);
|
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyPitch);
|
||||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyRoll);
|
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &_bodyRoll);
|
||||||
|
|
||||||
// Head rotation (NOTE: This needs to become a quaternion to save two bytes)
|
// Head rotation (NOTE: This needs to become a quaternion to save two bytes)
|
||||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_headYaw);
|
float headYaw, headPitch, headRoll;
|
||||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_headPitch);
|
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headYaw);
|
||||||
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_headRoll);
|
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headPitch);
|
||||||
|
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headRoll);
|
||||||
|
|
||||||
|
_headData->setYaw(headYaw);
|
||||||
|
_headData->setPitch(headPitch);
|
||||||
|
_headData->setRoll(headRoll);
|
||||||
|
|
||||||
// Head position relative to pelvis
|
// Head position relative to pelvis
|
||||||
memcpy(&_headLeanSideways, sourceBuffer, sizeof(float));
|
memcpy(&_headLeanSideways, sourceBuffer, sizeof(float));
|
||||||
|
@ -180,8 +189,8 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||||
sourceBuffer += sizeof(float) * 3;
|
sourceBuffer += sizeof(float) * 3;
|
||||||
|
|
||||||
// Lookat Position
|
// Lookat Position
|
||||||
memcpy(&_lookatPosition, sourceBuffer, sizeof(_lookatPosition));
|
memcpy(&_headData->_lookAtPosition, sourceBuffer, sizeof(_headData->_lookAtPosition));
|
||||||
sourceBuffer += sizeof(_lookatPosition);
|
sourceBuffer += sizeof(_headData->_lookAtPosition);
|
||||||
|
|
||||||
// Hand State
|
// Hand State
|
||||||
memcpy(&_handState, sourceBuffer, sizeof(char));
|
memcpy(&_handState, sourceBuffer, sizeof(char));
|
||||||
|
@ -226,11 +235,4 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||||
_wantDelta = oneAtBit(wantItems,WANT_DELTA_AT_BIT);
|
_wantDelta = oneAtBit(wantItems,WANT_DELTA_AT_BIT);
|
||||||
|
|
||||||
return sourceBuffer - startPosition;
|
return sourceBuffer - startPosition;
|
||||||
}
|
|
||||||
|
|
||||||
void AvatarData::setHeadPitch(float p) {
|
|
||||||
// Set head pitch and apply limits
|
|
||||||
const float MAX_PITCH = 60;
|
|
||||||
const float MIN_PITCH = -60;
|
|
||||||
_headPitch = glm::clamp(p, MIN_PITCH, MAX_PITCH);
|
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
// hifi
|
// hifi
|
||||||
//
|
//
|
||||||
// Created by Stephen Birarda on 4/9/13.
|
// Created by Stephen Birarda on 4/9/13.
|
||||||
//
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef __hifi__AvatarData__
|
#ifndef __hifi__AvatarData__
|
||||||
|
@ -14,6 +14,7 @@
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
#include <AgentData.h>
|
#include <AgentData.h>
|
||||||
|
#include "HeadData.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;
|
||||||
|
@ -29,12 +30,12 @@ enum KeyState
|
||||||
class AvatarData : public AgentData {
|
class AvatarData : public AgentData {
|
||||||
public:
|
public:
|
||||||
AvatarData();
|
AvatarData();
|
||||||
|
~AvatarData();
|
||||||
|
|
||||||
const glm::vec3& getPosition() const { return _position; }
|
const glm::vec3& getPosition() const { return _position; }
|
||||||
|
|
||||||
void setPosition (const glm::vec3 position ) { _position = position; }
|
void setPosition (const glm::vec3 position ) { _position = position; }
|
||||||
void setHandPosition (const glm::vec3 handPosition ) { _handPosition = handPosition; }
|
void setHandPosition (const glm::vec3 handPosition ) { _handPosition = handPosition; }
|
||||||
void setLookatPosition(const glm::vec3 lookatPosition) { _lookatPosition = lookatPosition; }
|
|
||||||
|
|
||||||
int getBroadcastData(unsigned char* destinationBuffer);
|
int getBroadcastData(unsigned char* destinationBuffer);
|
||||||
int parseData(unsigned char* sourceBuffer, int numBytes);
|
int parseData(unsigned char* sourceBuffer, int numBytes);
|
||||||
|
@ -47,17 +48,6 @@ public:
|
||||||
float getBodyRoll() const {return _bodyRoll; }
|
float getBodyRoll() const {return _bodyRoll; }
|
||||||
void setBodyRoll(float bodyRoll) { _bodyRoll = bodyRoll; }
|
void setBodyRoll(float bodyRoll) { _bodyRoll = bodyRoll; }
|
||||||
|
|
||||||
// Head Rotation
|
|
||||||
void setHeadPitch(float p);
|
|
||||||
void setHeadYaw(float y) {_headYaw = y; }
|
|
||||||
void setHeadRoll(float r) {_headRoll = r; };
|
|
||||||
float getHeadPitch() const { return _headPitch; };
|
|
||||||
float getHeadYaw() const { return _headYaw; };
|
|
||||||
float getHeadRoll() const { return _headRoll; };
|
|
||||||
void addHeadPitch(float p) { setHeadPitch(_headPitch - p); }
|
|
||||||
void addHeadYaw(float y){_headYaw -= y; }
|
|
||||||
void addHeadRoll(float r){_headRoll += r; }
|
|
||||||
|
|
||||||
// Head vector deflection from pelvix in X,Z
|
// Head vector deflection from pelvix in X,Z
|
||||||
void setHeadLeanSideways(float s) {_headLeanSideways = s; };
|
void setHeadLeanSideways(float s) {_headLeanSideways = s; };
|
||||||
float getHeadLeanSideways() const { return _headLeanSideways; };
|
float getHeadLeanSideways() const { return _headLeanSideways; };
|
||||||
|
@ -108,6 +98,8 @@ public:
|
||||||
void setWantColor(bool wantColor) { _wantColor = wantColor; }
|
void setWantColor(bool wantColor) { _wantColor = wantColor; }
|
||||||
void setWantDelta(bool wantDelta) { _wantDelta = wantDelta; }
|
void setWantDelta(bool wantDelta) { _wantDelta = wantDelta; }
|
||||||
|
|
||||||
|
void setHeadData(HeadData* headData) { _headData = headData; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// 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&);
|
||||||
|
@ -115,18 +107,12 @@ protected:
|
||||||
|
|
||||||
glm::vec3 _position;
|
glm::vec3 _position;
|
||||||
glm::vec3 _handPosition;
|
glm::vec3 _handPosition;
|
||||||
glm::vec3 _lookatPosition;
|
|
||||||
|
|
||||||
// Body rotation
|
// Body rotation
|
||||||
float _bodyYaw;
|
float _bodyYaw;
|
||||||
float _bodyPitch;
|
float _bodyPitch;
|
||||||
float _bodyRoll;
|
float _bodyRoll;
|
||||||
|
|
||||||
// Head rotation (relative to body)
|
|
||||||
float _headYaw;
|
|
||||||
float _headPitch;
|
|
||||||
float _headRoll;
|
|
||||||
|
|
||||||
float _headLeanSideways;
|
float _headLeanSideways;
|
||||||
float _headLeanForward;
|
float _headLeanForward;
|
||||||
|
|
||||||
|
@ -158,6 +144,8 @@ protected:
|
||||||
bool _wantResIn;
|
bool _wantResIn;
|
||||||
bool _wantColor;
|
bool _wantColor;
|
||||||
bool _wantDelta;
|
bool _wantDelta;
|
||||||
|
|
||||||
|
HeadData* _headData;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__hifi__AvatarData__) */
|
#endif /* defined(__hifi__AvatarData__) */
|
||||||
|
|
30
libraries/avatars/src/HeadData.cpp
Normal file
30
libraries/avatars/src/HeadData.cpp
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
//
|
||||||
|
// HeadData.cpp
|
||||||
|
// hifi
|
||||||
|
//
|
||||||
|
// Created by Stephen Birarda on 5/20/13.
|
||||||
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "HeadData.h"
|
||||||
|
|
||||||
|
HeadData::HeadData() :
|
||||||
|
_yaw(0.0f),
|
||||||
|
_pitch(0.0f),
|
||||||
|
_roll(0.0f),
|
||||||
|
_lookAtPosition(0.0f, 0.0f, 0.0f)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void HeadData::addYaw(float yaw) {
|
||||||
|
setYaw(_yaw + yaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HeadData::addPitch(float pitch) {
|
||||||
|
setPitch(_pitch + pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HeadData::addRoll(float roll) {
|
||||||
|
setRoll(_roll + roll);
|
||||||
|
}
|
51
libraries/avatars/src/HeadData.h
Normal file
51
libraries/avatars/src/HeadData.h
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
//
|
||||||
|
// HeadData.h
|
||||||
|
// hifi
|
||||||
|
//
|
||||||
|
// Created by Stephen Birarda on 5/20/13.
|
||||||
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __hifi__HeadData__
|
||||||
|
#define __hifi__HeadData__
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
const float MIN_HEAD_YAW = -85;
|
||||||
|
const float MAX_HEAD_YAW = 85;
|
||||||
|
const float MIN_HEAD_PITCH = -60;
|
||||||
|
const float MAX_HEAD_PITCH = 60;
|
||||||
|
const float MIN_HEAD_ROLL = -50;
|
||||||
|
const float MAX_HEAD_ROLL = 50;
|
||||||
|
|
||||||
|
class HeadData {
|
||||||
|
public:
|
||||||
|
HeadData();
|
||||||
|
|
||||||
|
float getYaw() const { return _yaw; }
|
||||||
|
void setYaw(float yaw) { _yaw = glm::clamp(yaw, MIN_HEAD_YAW, MAX_HEAD_YAW); }
|
||||||
|
|
||||||
|
float getPitch() const { return _pitch; }
|
||||||
|
void setPitch(float pitch) { _pitch = glm::clamp(pitch, MIN_HEAD_PITCH, MAX_HEAD_PITCH); }
|
||||||
|
|
||||||
|
float getRoll() const { return _roll; }
|
||||||
|
void setRoll(float roll) { _roll = glm::clamp(roll, MIN_HEAD_ROLL, MAX_HEAD_ROLL); }
|
||||||
|
|
||||||
|
void addYaw(float yaw);
|
||||||
|
void addPitch(float pitch);
|
||||||
|
void addRoll(float roll);
|
||||||
|
|
||||||
|
const glm::vec3& getLookAtPosition() const { return _lookAtPosition; }
|
||||||
|
void setLookAtPosition(const glm::vec3& lookAtPosition) { _lookAtPosition = lookAtPosition; }
|
||||||
|
|
||||||
|
friend class AvatarData;
|
||||||
|
protected:
|
||||||
|
float _yaw;
|
||||||
|
float _pitch;
|
||||||
|
float _roll;
|
||||||
|
glm::vec3 _lookAtPosition;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* defined(__hifi__HeadData__) */
|
Loading…
Reference in a new issue