mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 17:14:59 +02:00
(1) re-designed and debugged the orientation class and cleaned up quaternion code, and fixed issues in camera and main related to yaw and camera transforms (2) improved hand-holding algorithm
This commit is contained in:
parent
6b66d8e789
commit
b388e9a760
9 changed files with 247 additions and 296 deletions
|
@ -107,13 +107,14 @@ Avatar::Avatar(bool isMine) {
|
|||
_head.lastLoudness = 0.0;
|
||||
_head.browAudioLift = 0.0;
|
||||
_head.noise = 0;
|
||||
|
||||
_movedHandOffset = glm::vec3( 0.0, 0.0, 0.0 );
|
||||
_usingBodySprings = true;
|
||||
_renderYaw = 0.0;
|
||||
_renderPitch = 0.0;
|
||||
_sphere = NULL;
|
||||
_interactingOther = NULL;
|
||||
_interactingOtherIsNearby = false;
|
||||
_closeEnoughToHoldHands = false;
|
||||
_handHoldingPosition = glm::vec3( 0.0, 0.0, 0.0 );
|
||||
|
||||
initializeSkeleton();
|
||||
|
@ -136,7 +137,7 @@ Avatar::Avatar(const Avatar &otherAvatar) {
|
|||
_velocity = otherAvatar._velocity;
|
||||
_thrust = otherAvatar._thrust;
|
||||
_rotation = otherAvatar._rotation;
|
||||
_interactingOtherIsNearby = otherAvatar._interactingOtherIsNearby;
|
||||
_closeEnoughToHoldHands = otherAvatar._closeEnoughToHoldHands;
|
||||
_bodyYaw = otherAvatar._bodyYaw;
|
||||
_bodyPitch = otherAvatar._bodyPitch;
|
||||
_bodyRoll = otherAvatar._bodyRoll;
|
||||
|
@ -301,18 +302,18 @@ void Avatar::simulate(float deltaTime) {
|
|||
// reset hand and arm positions according to hand movement
|
||||
updateHandMovement( deltaTime );
|
||||
|
||||
if ( !_interactingOtherIsNearby ) {
|
||||
if ( !_closeEnoughToHoldHands ) {
|
||||
//initialize _handHolding
|
||||
_handHoldingPosition = _bone[ AVATAR_BONE_RIGHT_HAND ].position;
|
||||
}
|
||||
|
||||
_interactingOtherIsNearby = false;
|
||||
_closeEnoughToHoldHands = false; // reset for the next go-round
|
||||
|
||||
// if the avatar being simulated is mine, then loop through
|
||||
// all the other avatars for potential interactions...
|
||||
if ( _isMine )
|
||||
{
|
||||
float closestDistance = 10000.0f;
|
||||
//float closestDistance = 10000.0f;
|
||||
|
||||
AgentList* agentList = AgentList::getInstance();
|
||||
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
|
||||
|
@ -329,20 +330,29 @@ void Avatar::simulate(float deltaTime) {
|
|||
float distance = glm::length( v );
|
||||
if ( distance < _maxArmLength + _maxArmLength ) {
|
||||
|
||||
closestDistance = distance;
|
||||
//closestDistance = distance;
|
||||
_interactingOther = otherAvatar;
|
||||
_interactingOtherIsNearby = true;
|
||||
_closeEnoughToHoldHands = true;
|
||||
|
||||
// if I am holding hands with another avatar, a force is applied
|
||||
if (( _handState == 1 ) || ( _interactingOther->_handState == 1 )) {
|
||||
glm::vec3 vectorToOtherHand = _interactingOther->_handPosition - _handHoldingPosition;
|
||||
glm::vec3 vectorToMyHand = _bone[ AVATAR_BONE_RIGHT_HAND ].position - _handHoldingPosition;
|
||||
_handHoldingPosition += vectorToOtherHand * YOUR_HAND_HOLDING_PULL;
|
||||
_handHoldingPosition += vectorToMyHand * MY_HAND_HOLDING_PULL;
|
||||
_bone[ AVATAR_BONE_RIGHT_HAND ].position = _handHoldingPosition;
|
||||
}
|
||||
|
||||
// if the hands are close enough to grasp...
|
||||
//if (distance < 0.1)
|
||||
{
|
||||
glm::vec3 vectorToOtherHand = _interactingOther->_handPosition - _handHoldingPosition;
|
||||
glm::vec3 vectorToMyHand = _bone[ AVATAR_BONE_RIGHT_HAND ].position - _handHoldingPosition;
|
||||
|
||||
_handHoldingPosition += vectorToOtherHand * YOUR_HAND_HOLDING_PULL;
|
||||
_handHoldingPosition += vectorToMyHand * MY_HAND_HOLDING_PULL;
|
||||
_bone[ AVATAR_BONE_RIGHT_HAND ].position = _handHoldingPosition;
|
||||
|
||||
|
||||
_avatarTouch.setYourHandPosition( _interactingOther->_handPosition );
|
||||
//if ( glm::length(vectorToOtherHand) > 0.2 ) {
|
||||
// _velocity += vectorToOtherHand;
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -350,19 +360,24 @@ void Avatar::simulate(float deltaTime) {
|
|||
// Set the vector we send for hand position to other people to be our right hand
|
||||
setHandPosition(_bone[ AVATAR_BONE_RIGHT_HAND ].position);
|
||||
|
||||
//update the effects of touching another avatar
|
||||
_avatarTouch.simulate(deltaTime);
|
||||
|
||||
//update the effects of touching another avatar
|
||||
}//if ( _isMine )
|
||||
|
||||
//constrain right arm length and re-adjust elbow position as it bends
|
||||
updateArmIKAndConstraints( deltaTime );
|
||||
|
||||
if (_isMine) {
|
||||
_avatarTouch.setMyHandPosition( _bone[ AVATAR_BONE_RIGHT_HAND ].position );
|
||||
|
||||
// set hand positions for _avatarTouch.setMyHandPosition AFTER calling updateArmIKAndConstraints
|
||||
if ( _interactingOther != NULL ) {
|
||||
if (_isMine) {
|
||||
_avatarTouch.setMyHandPosition ( _bone[ AVATAR_BONE_RIGHT_HAND ].position );
|
||||
_avatarTouch.setYourHandPosition( _interactingOther->_handPosition );
|
||||
_avatarTouch.setMyHandState ( _handState );
|
||||
_avatarTouch.setYourHandState ( _interactingOther->_handState );
|
||||
_avatarTouch.simulate(deltaTime);
|
||||
}
|
||||
}
|
||||
|
||||
if (!_interactingOtherIsNearby) {
|
||||
if (!_closeEnoughToHoldHands) {
|
||||
_interactingOther = NULL;
|
||||
}
|
||||
|
||||
|
@ -429,9 +444,6 @@ void Avatar::simulate(float deltaTime) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Avatar::updateHead(float deltaTime) {
|
||||
if (!_head.noise) {
|
||||
// Decay back toward center
|
||||
|
@ -488,7 +500,6 @@ void Avatar::updateHead(float deltaTime) {
|
|||
_head.eyeballPitch[0] = _head.eyeballPitch[1] = -_headPitch + eye_target_pitch_adjust;
|
||||
_head.eyeballYaw[0] = _head.eyeballYaw[1] = -_headYaw + eye_target_yaw_adjust;
|
||||
}
|
||||
|
||||
|
||||
if (_head.noise)
|
||||
{
|
||||
|
@ -603,18 +614,16 @@ void Avatar::updateCollisionWithOtherAvatar( Avatar * otherAvatar, float deltaTi
|
|||
// push balls away from each other and apply friction
|
||||
glm::vec3 ballPushForce = directionVector * COLLISION_BALL_FORCE * deltaTime;
|
||||
|
||||
|
||||
float ballMomentum = COLLISION_BALL_FRICTION * deltaTime;
|
||||
float ballMomentum = 1.0 - COLLISION_BALL_FRICTION * deltaTime;
|
||||
if ( ballMomentum < 0.0 ) { ballMomentum = 0.0;}
|
||||
|
||||
|
||||
_bone[b].springyVelocity += ballPushForce;
|
||||
otherAvatar->_bone[o].springyVelocity -= ballPushForce;
|
||||
|
||||
_bone[b].springyVelocity *= 0.9;
|
||||
otherAvatar->_bone[o].springyVelocity *= 0.9;
|
||||
_bone[b].springyVelocity *= ballMomentum;
|
||||
otherAvatar->_bone[o].springyVelocity *= ballMomentum;
|
||||
|
||||
// accumulate forces and frictions to the velocities of avatar bodies
|
||||
// accumulate forces and frictions to apply to the velocities of avatar bodies
|
||||
bodyPushForce += directionVector * COLLISION_BODY_FORCE * deltaTime;
|
||||
bodyMomentum -= COLLISION_BODY_FRICTION * deltaTime;
|
||||
if ( bodyMomentum < 0.0 ) { bodyMomentum = 0.0;}
|
||||
|
@ -637,8 +646,6 @@ void Avatar::updateCollisionWithOtherAvatar( Avatar * otherAvatar, float deltaTi
|
|||
} //method
|
||||
|
||||
|
||||
|
||||
|
||||
void Avatar::setDisplayingHead( bool displayingHead ) {
|
||||
_displayingHead = displayingHead;
|
||||
}
|
||||
|
@ -676,11 +683,8 @@ void Avatar::render(bool lookingInMirror) {
|
|||
}
|
||||
|
||||
// if this is my avatar, then render my interactions with the other avatar
|
||||
if ( _isMine )
|
||||
{
|
||||
if ( _interactingOtherIsNearby ) {
|
||||
_avatarTouch.render();
|
||||
}
|
||||
if (( _isMine ) && ( _closeEnoughToHoldHands )) {
|
||||
_avatarTouch.render();
|
||||
}
|
||||
|
||||
// Render the balls
|
||||
|
@ -739,7 +743,7 @@ void Avatar::renderHead(bool lookingInMirror) {
|
|||
glEnable(GL_RESCALE_NORMAL);
|
||||
|
||||
// show head orientation
|
||||
//renderOrientationDirections( _bone[ AVATAR_BONE_HEAD ].position, _bone[ AVATAR_BONE_HEAD ].orientation, 0.2f );
|
||||
renderOrientationDirections( _bone[ AVATAR_BONE_HEAD ].springyPosition, _bone[ AVATAR_BONE_HEAD ].orientation, 0.2f );
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
|
@ -812,9 +816,7 @@ void Avatar::renderHead(bool lookingInMirror) {
|
|||
}
|
||||
glPopMatrix();
|
||||
|
||||
|
||||
// Mouth
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(0,-0.35,0.75);
|
||||
glColor3f(0,0,0);
|
||||
|
@ -1132,9 +1134,9 @@ void Avatar::updateHandMovement( float deltaTime ) {
|
|||
glm::vec3 transformedHandMovement;
|
||||
|
||||
transformedHandMovement
|
||||
= _orientation.getRight() * _movedHandOffset.x
|
||||
+ _orientation.getUp() * -_movedHandOffset.y * 0.5f
|
||||
+ _orientation.getFront() * -_movedHandOffset.y;
|
||||
= _orientation.getRight() * _movedHandOffset.x * 2.0f
|
||||
+ _orientation.getUp() * -_movedHandOffset.y * 1.0f
|
||||
+ _orientation.getFront() * -_movedHandOffset.y * 1.0f;
|
||||
|
||||
_bone[ AVATAR_BONE_RIGHT_HAND ].position += transformedHandMovement;
|
||||
|
||||
|
@ -1168,7 +1170,10 @@ void Avatar::updateArmIKAndConstraints( float deltaTime ) {
|
|||
// set elbow position
|
||||
glm::vec3 newElbowPosition = _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position;
|
||||
newElbowPosition += armVector * ONE_HALF;
|
||||
|
||||
//glm::vec3 perpendicular = glm::cross( _orientation.getFront(), armVector );
|
||||
glm::vec3 perpendicular = glm::cross( _orientation.getFront(), armVector );
|
||||
|
||||
newElbowPosition += perpendicular * ( 1.0f - ( _maxArmLength / distance ) ) * ONE_HALF;
|
||||
_bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].position = newElbowPosition;
|
||||
|
||||
|
@ -1238,6 +1243,7 @@ void Avatar::renderBody() {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// if the hand is grasping, show it...
|
||||
if (( _usingBodySprings ) && ( _handState == 1 )) {
|
||||
glPushMatrix();
|
||||
|
@ -1250,6 +1256,7 @@ void Avatar::renderBody() {
|
|||
|
||||
glPopMatrix();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void Avatar::SetNewHeadTarget(float pitch, float yaw) {
|
||||
|
|
|
@ -72,7 +72,6 @@ enum AvatarBoneID
|
|||
NUM_AVATAR_BONES
|
||||
};
|
||||
|
||||
|
||||
class Avatar : public AvatarData {
|
||||
public:
|
||||
Avatar(bool isMine);
|
||||
|
@ -93,7 +92,7 @@ public:
|
|||
float getBodyYaw() {return _bodyYaw;};
|
||||
void addBodyYaw(float y) {_bodyYaw += y;};
|
||||
|
||||
bool getIsNearInteractingOther() { return _interactingOtherIsNearby; }
|
||||
bool getIsNearInteractingOther() { return _closeEnoughToHoldHands; }
|
||||
|
||||
float getAbsoluteHeadYaw() const;
|
||||
void setLeanForward(float dist);
|
||||
|
@ -123,7 +122,7 @@ public:
|
|||
void setDisplayingHead( bool displayingHead );
|
||||
|
||||
float getAverageLoudness() {return _head.averageLoudness;};
|
||||
void setAverageLoudness(float al) {_head.averageLoudness = al;};
|
||||
void setAverageLoudness(float al) {_head.averageLoudness = al;};
|
||||
|
||||
void SetNewHeadTarget(float, float);
|
||||
|
||||
|
@ -148,23 +147,17 @@ private:
|
|||
const bool AVATAR_GRAVITY = true;
|
||||
const float DECAY = 0.1;
|
||||
const float THRUST_MAG = 1200.0;
|
||||
const float YAW_MAG = 500.0; //JJV - changed from 300.0;
|
||||
const float YAW_MAG = 500.0;
|
||||
const float TEST_YAW_DECAY = 5.0;
|
||||
const float LIN_VEL_DECAY = 5.0;
|
||||
const float MY_HAND_HOLDING_PULL = 0.2;
|
||||
const float YOUR_HAND_HOLDING_PULL = 1.0;
|
||||
const float BODY_SPRING_FORCE = 6.0f;
|
||||
const float BODY_SPRING_DECAY = 16.0f;
|
||||
|
||||
//const float COLLISION_FRICTION = 0.5;
|
||||
//const float COLLISION_RADIUS_SCALAR = 1.8;
|
||||
//const float COLLISION_BALL_FORCE = 0.1;
|
||||
//const float COLLISION_BODY_FORCE = 3.0;
|
||||
|
||||
const float COLLISION_RADIUS_SCALAR = 1.8;
|
||||
const float COLLISION_BALL_FORCE = 0.6;
|
||||
const float COLLISION_BALL_FORCE = 1.0;
|
||||
const float COLLISION_BODY_FORCE = 6.0;
|
||||
const float COLLISION_BALL_FRICTION = 200.0;
|
||||
const float COLLISION_BALL_FRICTION = 60.0;
|
||||
const float COLLISION_BODY_FRICTION = 0.5;
|
||||
|
||||
struct AvatarBone
|
||||
|
@ -223,37 +216,37 @@ private:
|
|||
float audioAttack;
|
||||
};
|
||||
|
||||
AvatarHead _head;
|
||||
bool _isMine;
|
||||
glm::vec3 _TEST_bigSpherePosition;
|
||||
float _TEST_bigSphereRadius;
|
||||
bool _mousePressed;
|
||||
float _bodyYawDelta;
|
||||
bool _usingBodySprings;
|
||||
glm::vec3 _movedHandOffset;
|
||||
glm::quat _rotation; // the rotation of the avatar body as a whole expressed as a quaternion
|
||||
AvatarBone _bone[ NUM_AVATAR_BONES ];
|
||||
AvatarMode _mode;
|
||||
glm::vec3 _handHoldingPosition;
|
||||
glm::vec3 _velocity;
|
||||
glm::vec3 _thrust;
|
||||
float _speed;
|
||||
float _maxArmLength;
|
||||
Orientation _orientation;
|
||||
int _driveKeys[MAX_DRIVE_KEYS];
|
||||
GLUquadric* _sphere;
|
||||
float _renderYaw;
|
||||
float _renderPitch; // Pitch from view frustum when this is own head
|
||||
timeval _transmitterTimer;
|
||||
float _transmitterHz;
|
||||
int _transmitterPackets;
|
||||
Avatar* _interactingOther;
|
||||
bool _interactingOtherIsNearby;
|
||||
float _pelvisStandingHeight;
|
||||
float _height;
|
||||
Balls* _balls;
|
||||
AvatarTouch _avatarTouch;
|
||||
bool _displayingHead; // should be false if in first-person view
|
||||
AvatarHead _head;
|
||||
bool _isMine;
|
||||
glm::vec3 _TEST_bigSpherePosition;
|
||||
float _TEST_bigSphereRadius;
|
||||
bool _mousePressed;
|
||||
float _bodyYawDelta;
|
||||
bool _usingBodySprings;
|
||||
glm::vec3 _movedHandOffset;
|
||||
glm::quat _rotation; // the rotation of the avatar body as a whole expressed as a quaternion
|
||||
AvatarBone _bone[ NUM_AVATAR_BONES ];
|
||||
AvatarMode _mode;
|
||||
glm::vec3 _handHoldingPosition;
|
||||
glm::vec3 _velocity;
|
||||
glm::vec3 _thrust;
|
||||
float _speed;
|
||||
float _maxArmLength;
|
||||
Orientation _orientation;
|
||||
int _driveKeys[MAX_DRIVE_KEYS];
|
||||
GLUquadric* _sphere;
|
||||
float _renderYaw;
|
||||
float _renderPitch; // Pitch from view frustum when this is own head
|
||||
timeval _transmitterTimer;
|
||||
float _transmitterHz;
|
||||
int _transmitterPackets;
|
||||
Avatar* _interactingOther;
|
||||
bool _closeEnoughToHoldHands;
|
||||
float _pelvisStandingHeight;
|
||||
float _height;
|
||||
Balls* _balls;
|
||||
AvatarTouch _avatarTouch;
|
||||
bool _displayingHead; // should be false if in first-person view
|
||||
|
||||
// private methods...
|
||||
void initializeSkeleton();
|
||||
|
|
|
@ -11,11 +11,12 @@
|
|||
#include "AvatarTouch.h"
|
||||
#include "InterfaceConfig.h"
|
||||
|
||||
|
||||
AvatarTouch::AvatarTouch() {
|
||||
|
||||
_myHandPosition = glm::vec3( 0.0f, 0.0f, 0.0f );
|
||||
_yourHandPosition = glm::vec3( 0.0f, 0.0f, 0.0f );
|
||||
_myHandState = 0;
|
||||
_yourHandState = 0;
|
||||
|
||||
for (int p=0; p<NUM_POINTS; p++) {
|
||||
_point[p] = glm::vec3( 0.0, 0.0, 0.0 );
|
||||
|
@ -30,11 +31,39 @@ void AvatarTouch::setYourHandPosition( glm::vec3 position ) {
|
|||
_yourHandPosition = position;
|
||||
}
|
||||
|
||||
void AvatarTouch::setMyHandState( int state ) {
|
||||
_myHandState = state;
|
||||
}
|
||||
|
||||
void AvatarTouch::setYourHandState( int state ) {
|
||||
_yourHandState = state;
|
||||
}
|
||||
|
||||
void AvatarTouch::render() {
|
||||
|
||||
glm::vec3 v1( _myHandPosition );
|
||||
glm::vec3 v2( _yourHandPosition );
|
||||
|
||||
// if my hand is grasping, show it...
|
||||
if ( _myHandState == 1 ) {
|
||||
glPushMatrix();
|
||||
glTranslatef(_myHandPosition.x, _myHandPosition.y, _myHandPosition.z);
|
||||
glColor4f( 1.0, 1.0, 0.8, 0.3 ); glutSolidSphere( 0.020f, 10.0f, 10.0f );
|
||||
glColor4f( 1.0, 1.0, 0.4, 0.2 ); glutSolidSphere( 0.025f, 10.0f, 10.0f );
|
||||
glColor4f( 1.0, 1.0, 0.2, 0.1 ); glutSolidSphere( 0.030f, 10.0f, 10.0f );
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
// if your hand is grasping, show it...
|
||||
if ( _yourHandState == 1 ) {
|
||||
glPushMatrix();
|
||||
glTranslatef(_yourHandPosition.x, _yourHandPosition.y, _yourHandPosition.z);
|
||||
glColor4f( 1.0, 1.0, 0.8, 0.3 ); glutSolidSphere( 0.020f, 10.0f, 10.0f );
|
||||
glColor4f( 1.0, 1.0, 0.4, 0.2 ); glutSolidSphere( 0.025f, 10.0f, 10.0f );
|
||||
glColor4f( 1.0, 1.0, 0.2, 0.1 ); glutSolidSphere( 0.030f, 10.0f, 10.0f );
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
glLineWidth( 2.0 );
|
||||
glColor4f( 0.7f, 0.4f, 0.1f, 0.3 );
|
||||
glBegin( GL_LINE_STRIP );
|
||||
|
|
|
@ -17,7 +17,9 @@ public:
|
|||
|
||||
void setMyHandPosition ( glm::vec3 position );
|
||||
void setYourHandPosition( glm::vec3 position );
|
||||
void simulate(float deltaTime);
|
||||
void setMyHandState ( int state );
|
||||
void setYourHandState ( int state );
|
||||
void simulate (float deltaTime);
|
||||
void render();
|
||||
|
||||
const float THREAD_RADIUS = 0.007;
|
||||
|
@ -29,6 +31,8 @@ private:
|
|||
glm::vec3 _point [NUM_POINTS];
|
||||
glm::vec3 _myHandPosition;
|
||||
glm::vec3 _yourHandPosition;
|
||||
int _myHandState;
|
||||
int _yourHandState;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -34,12 +34,6 @@ Camera::Camera() {
|
|||
|
||||
void Camera::update( float deltaTime ) {
|
||||
|
||||
// generate the ortho-normals for the orientation based on the Euler angles
|
||||
_orientation.setToIdentity();
|
||||
_orientation.yaw ( _yaw );
|
||||
_orientation.pitch( _pitch );
|
||||
_orientation.roll ( _roll );
|
||||
|
||||
if ( _mode == CAMERA_MODE_NULL ) {
|
||||
_modeShift = 0.0;
|
||||
} else {
|
||||
|
@ -53,6 +47,19 @@ void Camera::update( float deltaTime ) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// do this AFTER making any changes to yaw pitch and roll....
|
||||
generateOrientation();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// generate the ortho-normals for the orientation based on the three Euler angles
|
||||
void Camera::generateOrientation() {
|
||||
_orientation.setToIdentity();
|
||||
_orientation.pitch( _pitch );
|
||||
_orientation.yaw ( _yaw );
|
||||
_orientation.roll ( _roll );
|
||||
}
|
||||
|
||||
|
||||
|
@ -71,9 +78,8 @@ void Camera::updateFollowMode( float deltaTime ) {
|
|||
float radian = (_yaw / 180.0) * PIE;
|
||||
|
||||
// update _position
|
||||
//these need to be checked to make sure they correspond to the correct coordinate system.
|
||||
double x = _distance * -sin(radian);
|
||||
double z = _distance * cos(radian);
|
||||
double x = -_distance * sin(radian);
|
||||
double z = -_distance * cos(radian);
|
||||
double y = _upShift;
|
||||
|
||||
_idealPosition = _targetPosition + glm::vec3(x, y, z);
|
||||
|
|
|
@ -38,7 +38,6 @@ public:
|
|||
void setTargetPosition( glm::vec3 t ) { _targetPosition = t; }
|
||||
void setTargetYaw ( float y ) { _idealYaw = y; }
|
||||
void setPosition ( glm::vec3 p ) { _position = p; }
|
||||
void setOrientation ( Orientation o ) { _orientation.set(o); }
|
||||
void setTightness ( float t ) { _tightness = t; }
|
||||
|
||||
void setMode ( CameraMode m );
|
||||
|
@ -83,6 +82,7 @@ private:
|
|||
float _tightness;
|
||||
Orientation _orientation;
|
||||
|
||||
void generateOrientation();
|
||||
void updateFollowMode( float deltaTime );
|
||||
};
|
||||
|
||||
|
|
|
@ -109,9 +109,9 @@ Oscilloscope audioScope(256,200,true);
|
|||
|
||||
ViewFrustum viewFrustum; // current state of view frustum, perspective, orientation, etc.
|
||||
|
||||
Avatar myAvatar(true); // The rendered avatar of oneself
|
||||
Camera myCamera; // My view onto the world (sometimes on myself :)
|
||||
Camera viewFrustumOffsetCamera; // The camera we use to sometimes show the view frustum from an offset mode
|
||||
Avatar myAvatar(true); // The rendered avatar of oneself
|
||||
Camera myCamera; // My view onto the world (sometimes on myself :)
|
||||
Camera viewFrustumOffsetCamera; // The camera we use to sometimes show the view frustum from an offset mode
|
||||
|
||||
// Starfield information
|
||||
char starFile[] = "https://s3-us-west-1.amazonaws.com/highfidelity/stars.txt";
|
||||
|
@ -495,31 +495,19 @@ void loadViewFrustum(ViewFrustum& viewFrustum) {
|
|||
glm::vec3 up;
|
||||
glm::vec3 right;
|
||||
float fov, nearClip, farClip;
|
||||
float yaw, pitch, roll;
|
||||
|
||||
// Camera or Head?
|
||||
if (::cameraFrustum) {
|
||||
position = ::myCamera.getPosition();
|
||||
position = ::myCamera.getPosition();
|
||||
} else {
|
||||
position = ::myAvatar.getHeadPosition();
|
||||
position = ::myAvatar.getHeadPosition();
|
||||
}
|
||||
|
||||
// This bit of hackery is all because our Cameras report the incorrect yaw.
|
||||
// For whatever reason, the camera has a yaw set to 180.0-trueYaw, so we basically
|
||||
// need to get the "yaw" from the camera and adjust it to be the trueYaw
|
||||
yaw = -(::myCamera.getOrientation().getYaw()-180);
|
||||
pitch = ::myCamera.getOrientation().getPitch();
|
||||
roll = ::myCamera.getOrientation().getRoll();
|
||||
fov = ::myCamera.getFieldOfView();
|
||||
nearClip = ::myCamera.getNearClip();
|
||||
farClip = ::myCamera.getFarClip();
|
||||
|
||||
// We can't use the camera's Orientation because of it's broken yaw. so we make a new
|
||||
// correct orientation to get our vectors
|
||||
Orientation o;
|
||||
o.yaw(yaw);
|
||||
o.pitch(pitch);
|
||||
o.roll(roll);
|
||||
|
||||
Orientation o = ::myCamera.getOrientation();
|
||||
|
||||
direction = o.getFront();
|
||||
up = o.getUp();
|
||||
|
@ -713,7 +701,7 @@ void display(void)
|
|||
if ( ::lookingInMirror ) {
|
||||
// set the camera to looking at my own face
|
||||
myCamera.setTargetPosition ( myAvatar.getHeadPosition() );
|
||||
myCamera.setTargetYaw ( - myAvatar.getBodyYaw() );
|
||||
myCamera.setTargetYaw ( myAvatar.getBodyYaw() - 180.0f ); // 180 degrees from body yaw
|
||||
myCamera.setPitch ( 0.0 );
|
||||
myCamera.setRoll ( 0.0 );
|
||||
myCamera.setUpShift ( 0.0 );
|
||||
|
@ -800,10 +788,10 @@ void display(void)
|
|||
}
|
||||
|
||||
myCamera.setTargetPosition( myAvatar.getHeadPosition() );
|
||||
myCamera.setTargetYaw ( 180.0 - myAvatar.getBodyYaw() );
|
||||
myCamera.setTargetYaw ( myAvatar.getBodyYaw() );
|
||||
myCamera.setRoll ( 0.0 );
|
||||
}
|
||||
|
||||
|
||||
// important...
|
||||
myCamera.update( 1.f/FPS );
|
||||
|
||||
|
@ -821,7 +809,7 @@ void display(void)
|
|||
if (::viewFrustumFromOffset && ::frustumOn) {
|
||||
|
||||
// set the camera to third-person view but offset so we can see the frustum
|
||||
viewFrustumOffsetCamera.setTargetYaw( 180.0 - myAvatar.getBodyYaw() + ::viewFrustumOffsetYaw );
|
||||
viewFrustumOffsetCamera.setTargetYaw( ::viewFrustumOffsetYaw + myAvatar.getBodyYaw() );
|
||||
viewFrustumOffsetCamera.setPitch ( ::viewFrustumOffsetPitch );
|
||||
viewFrustumOffsetCamera.setRoll ( ::viewFrustumOffsetRoll );
|
||||
viewFrustumOffsetCamera.setUpShift ( ::viewFrustumOffsetUp );
|
||||
|
@ -834,9 +822,11 @@ void display(void)
|
|||
// could be myCamera (if in normal mode)
|
||||
// or could be viewFrustumOffsetCamera if in offset mode
|
||||
// I changed the ordering here - roll is FIRST (JJV)
|
||||
glRotatef ( whichCamera.getRoll(), 0, 0, 1 );
|
||||
glRotatef ( whichCamera.getPitch(), 1, 0, 0 );
|
||||
glRotatef ( whichCamera.getYaw(), 0, 1, 0 );
|
||||
|
||||
glRotatef ( whichCamera.getRoll(), IDENTITY_FRONT.x, IDENTITY_FRONT.y, IDENTITY_FRONT.z );
|
||||
glRotatef ( whichCamera.getPitch(), IDENTITY_RIGHT.x, IDENTITY_RIGHT.y, IDENTITY_RIGHT.z );
|
||||
glRotatef ( 180.0 - whichCamera.getYaw(), IDENTITY_UP.x, IDENTITY_UP.y, IDENTITY_UP.z );
|
||||
|
||||
glTranslatef( -whichCamera.getPosition().x, -whichCamera.getPosition().y, -whichCamera.getPosition().z );
|
||||
|
||||
if (::starsOn) {
|
||||
|
|
|
@ -9,165 +9,97 @@
|
|||
#include <SharedUtil.h>
|
||||
#include "avatars_Log.h"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
//#include "Util.h"
|
||||
|
||||
using avatars_lib::printLog;
|
||||
|
||||
// XXXBHG - this test has not yet been reworked to match the correct vector orientation
|
||||
// of the coordinate system, so don't use it for now.
|
||||
//
|
||||
// tosh - yep, I noticed... :-)
|
||||
//
|
||||
|
||||
static bool testingForNormalizationAndOrthogonality = false;
|
||||
static const bool USING_QUATERNIONS = true;
|
||||
|
||||
Orientation::Orientation() {
|
||||
setToIdentity();
|
||||
}
|
||||
|
||||
void Orientation::setToIdentity() {
|
||||
_yaw = 0.0;
|
||||
_pitch = 0.0;
|
||||
_roll = 0.0;
|
||||
right = glm::vec3( -1.0f, 0.0f, 0.0f );
|
||||
up = glm::vec3( 0.0f, 1.0f, 0.0f );
|
||||
front = glm::vec3( 0.0f, 0.0f, 1.0f );
|
||||
|
||||
quat = glm::quat();
|
||||
right = glm::vec3( IDENTITY_RIGHT );
|
||||
up = glm::vec3( IDENTITY_UP );
|
||||
front = glm::vec3( IDENTITY_FRONT );
|
||||
}
|
||||
|
||||
void Orientation::set( Orientation o ) {
|
||||
|
||||
quat = o.quat;
|
||||
right = o.right;
|
||||
up = o.up;
|
||||
front = o.front;
|
||||
}
|
||||
|
||||
void Orientation::update() {
|
||||
void Orientation::yaw( float angle ) {
|
||||
|
||||
float pitchRads = _pitch * PI_OVER_180;
|
||||
float yawRads = _yaw * PI_OVER_180;
|
||||
float rollRads = _roll * PI_OVER_180;
|
||||
float radian = angle * PI_OVER_180;
|
||||
|
||||
glm::quat q(glm::vec3(pitchRads, -(yawRads), rollRads));
|
||||
|
||||
// Next, create a rotation matrix from that quaternion
|
||||
glm::mat4 rotation;
|
||||
rotation = glm::mat4_cast(q);
|
||||
|
||||
// Transform the original vectors by the rotation matrix to get the new vectors
|
||||
glm::vec4 qup(0,1,0,0);
|
||||
glm::vec4 qright(-1,0,0,0);
|
||||
glm::vec4 qfront(0,0,1,0);
|
||||
glm::vec4 upNew = qup*rotation;
|
||||
glm::vec4 rightNew = qright*rotation;
|
||||
glm::vec4 frontNew = qfront*rotation;
|
||||
|
||||
// Copy the answers to output vectors
|
||||
up.x = upNew.x;
|
||||
up.y = upNew.y;
|
||||
up.z = upNew.z;
|
||||
|
||||
right.x = rightNew.x;
|
||||
right.y = rightNew.y;
|
||||
right.z = rightNew.z;
|
||||
|
||||
front.x = frontNew.x;
|
||||
front.y = frontNew.y;
|
||||
front.z = frontNew.z;
|
||||
|
||||
if ( testingForNormalizationAndOrthogonality ) { testForOrthogonalAndNormalizedVectors( EPSILON ); }
|
||||
}
|
||||
|
||||
void Orientation::yaw(float angle) {
|
||||
// remember the value for any future changes to other angles
|
||||
_yaw = angle;
|
||||
update();
|
||||
if ( USING_QUATERNIONS ) {
|
||||
rotateAndGenerateDirections( glm::quat( glm::vec3( 0.0f, -radian, 0.0f )) );
|
||||
} else {
|
||||
float s = sin(radian);
|
||||
float c = cos(radian);
|
||||
|
||||
glm::vec3 cosineFront = front * c;
|
||||
glm::vec3 cosineRight = right * c;
|
||||
glm::vec3 sineFront = front * s;
|
||||
glm::vec3 sineRight = right * s;
|
||||
|
||||
front = cosineFront - sineRight;
|
||||
right = cosineRight + sineFront;
|
||||
}
|
||||
}
|
||||
|
||||
void Orientation::pitch( float angle ) {
|
||||
// remember the value for any future changes to other angles
|
||||
_pitch = angle;
|
||||
update();
|
||||
}
|
||||
|
||||
float radian = angle * PI_OVER_180;
|
||||
|
||||
if ( USING_QUATERNIONS ) {
|
||||
rotateAndGenerateDirections( glm::quat( glm::vec3( radian, 0.0f, 0.0f ) ) );
|
||||
} else {
|
||||
float s = sin(radian);
|
||||
float c = cos(radian);
|
||||
|
||||
glm::vec3 cosineUp = up * c;
|
||||
glm::vec3 cosineFront = front * c;
|
||||
glm::vec3 sineUp = up * s;
|
||||
glm::vec3 sineFront = front * s;
|
||||
|
||||
up = cosineUp - sineFront;
|
||||
front = cosineFront + sineUp;
|
||||
}
|
||||
}
|
||||
|
||||
void Orientation::roll( float angle ) {
|
||||
_roll = angle;
|
||||
update();
|
||||
|
||||
float radian = angle * PI_OVER_180;
|
||||
|
||||
if ( USING_QUATERNIONS ) {
|
||||
rotateAndGenerateDirections( glm::quat( glm::vec3( 0.0f, 0.0f, radian )) );
|
||||
} else {
|
||||
float s = sin(radian);
|
||||
float c = cos(radian);
|
||||
|
||||
glm::vec3 cosineUp = up * c;
|
||||
glm::vec3 cosineRight = right * c;
|
||||
glm::vec3 sineUp = up * s;
|
||||
glm::vec3 sineRight = right * s;
|
||||
|
||||
up = cosineUp - sineRight;
|
||||
right = cosineRight + sineUp;
|
||||
}
|
||||
}
|
||||
|
||||
void Orientation::rotateAndGenerateDirections( glm::quat rotation ) {
|
||||
|
||||
void Orientation::setRightUpFront( const glm::vec3 &r, const glm::vec3 &u, const glm::vec3 &f ) {
|
||||
right = r;
|
||||
up = u;
|
||||
front = f;
|
||||
quat = quat * rotation;
|
||||
|
||||
glm::mat4 rotationMatrix = glm::mat4_cast(quat);
|
||||
|
||||
right = glm::vec3( glm::vec4( IDENTITY_RIGHT, 0.0f ) * rotationMatrix );
|
||||
up = glm::vec3( glm::vec4( IDENTITY_UP, 0.0f ) * rotationMatrix );
|
||||
front = glm::vec3( glm::vec4( IDENTITY_FRONT, 0.0f ) * rotationMatrix );
|
||||
}
|
||||
|
||||
void Orientation::testForOrthogonalAndNormalizedVectors( float epsilon ) {
|
||||
|
||||
// XXXBHG - this test has not yet been reworked to match the correct vector orientation
|
||||
// of the coordinate system
|
||||
// bail for now, assume all is good
|
||||
return;
|
||||
|
||||
// make sure vectors are normalized (or close enough to length 1.0)
|
||||
float rightLength = glm::length( right );
|
||||
float upLength = glm::length( up );
|
||||
float frontLength = glm::length( front );
|
||||
|
||||
if (( rightLength > 1.0f + epsilon )
|
||||
|| ( rightLength < 1.0f - epsilon )) {
|
||||
printLog( "Error in Orientation class: right direction length is %f \n", rightLength );
|
||||
}
|
||||
assert ( rightLength > 1.0f - epsilon );
|
||||
assert ( rightLength < 1.0f + epsilon );
|
||||
|
||||
|
||||
if (( upLength > 1.0f + epsilon )
|
||||
|| ( upLength < 1.0f - epsilon )) {
|
||||
printLog( "Error in Orientation class: up direction length is %f \n", upLength );
|
||||
}
|
||||
assert ( upLength > 1.0f - epsilon );
|
||||
assert ( upLength < 1.0f + epsilon );
|
||||
|
||||
|
||||
if (( frontLength > 1.0f + epsilon )
|
||||
|| ( frontLength < 1.0f - epsilon )) {
|
||||
printLog( "Error in Orientation class: front direction length is %f \n", frontLength );
|
||||
}
|
||||
assert ( frontLength > 1.0f - epsilon );
|
||||
assert ( frontLength < 1.0f + epsilon );
|
||||
|
||||
|
||||
// make sure vectors are orthogonal (or close enough)
|
||||
glm::vec3 rightCross = glm::cross( up, front );
|
||||
glm::vec3 upCross = glm::cross( front, right );
|
||||
glm::vec3 frontCross = glm::cross( right, up );
|
||||
|
||||
float rightDiff = glm::length( rightCross - right );
|
||||
float upDiff = glm::length( upCross - up );
|
||||
float frontDiff = glm::length( frontCross - front );
|
||||
|
||||
|
||||
if ( rightDiff > epsilon ) {
|
||||
printLog( "Error in Orientation class: right direction not orthogonal to up and/or front. " );
|
||||
printLog( "The tested cross of up and front is off by %f \n", rightDiff );
|
||||
}
|
||||
assert ( rightDiff < epsilon );
|
||||
|
||||
|
||||
if ( upDiff > epsilon ) {
|
||||
printLog( "Error in Orientation class: up direction not orthogonal to front and/or right. " );
|
||||
printLog( "The tested cross of front and right is off by %f \n", upDiff );
|
||||
}
|
||||
assert ( upDiff < epsilon );
|
||||
|
||||
|
||||
if ( frontDiff > epsilon ) {
|
||||
printLog( "Error in Orientation class: front direction not orthogonal to right and/or up. " );
|
||||
printLog( "The tested cross of right and up is off by %f \n", frontDiff );
|
||||
}
|
||||
assert ( frontDiff < epsilon );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
//-----------------------------------------------------------
|
||||
//
|
||||
// Created by Jeffrey Ventrella
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
//-----------------------------------------------------------
|
||||
|
@ -8,52 +7,43 @@
|
|||
#ifndef __interface__orientation__
|
||||
#define __interface__orientation__
|
||||
|
||||
#include <cmath> // with this work? "Math.h"
|
||||
#include <cmath>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
enum Axis
|
||||
{
|
||||
ORIENTATION_RIGHT_AXIS,
|
||||
ORIENTATION_UP_AXIS,
|
||||
ORIENTATION_FRONT_AXIS
|
||||
};
|
||||
// this is where the coordinate system is represented
|
||||
const glm::vec3 IDENTITY_RIGHT = glm::vec3( -1.0f, 0.0f, 0.0f );
|
||||
const glm::vec3 IDENTITY_UP = glm::vec3( 0.0f, 1.0f, 0.0f );
|
||||
const glm::vec3 IDENTITY_FRONT = glm::vec3( 0.0f, 0.0f, 1.0f );
|
||||
|
||||
class Orientation
|
||||
{
|
||||
public:
|
||||
Orientation();
|
||||
|
||||
void set( Orientation );
|
||||
void setToIdentity();
|
||||
|
||||
void yaw ( float );
|
||||
void pitch( float );
|
||||
void roll ( float );
|
||||
|
||||
const glm::vec3 & getRight() const { return right; }
|
||||
const glm::vec3 & getUp () const { return up; }
|
||||
const glm::vec3 & getFront() const { return front; }
|
||||
|
||||
const glm::vec3 & getIdentityRight() const { return IDENTITY_RIGHT; }
|
||||
const glm::vec3 & getIdentityUp () const { return IDENTITY_UP; }
|
||||
const glm::vec3 & getIdentityFront() const { return IDENTITY_FRONT; }
|
||||
|
||||
private:
|
||||
float _yaw;
|
||||
float _pitch;
|
||||
float _roll;
|
||||
|
||||
|
||||
glm::quat quat;
|
||||
glm::vec3 right;
|
||||
glm::vec3 up;
|
||||
glm::vec3 front;
|
||||
|
||||
void update(); // actually updates the vectors from yaw, pitch, roll
|
||||
|
||||
public:
|
||||
Orientation();
|
||||
|
||||
void yaw ( float );
|
||||
void pitch ( float );
|
||||
void roll ( float );
|
||||
|
||||
float getYaw() { return _yaw; };
|
||||
float getPitch(){ return _pitch; };
|
||||
float getRoll(){ return _roll; };
|
||||
|
||||
void set( Orientation );
|
||||
void setToIdentity();
|
||||
|
||||
const glm::vec3& getRight() const { return right; }
|
||||
const glm::vec3& getUp() const { return up; }
|
||||
const glm::vec3& getFront() const { return front; }
|
||||
|
||||
void setRightUpFront( const glm::vec3 &, const glm::vec3 &, const glm::vec3 & );
|
||||
|
||||
private:
|
||||
void testForOrthogonalAndNormalizedVectors( float epsilon );
|
||||
void rotateAndGenerateDirections( glm::quat rotation );
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue