Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Stephen Birarda 2013-04-23 13:38:59 -07:00
commit 42ba5a51d4
6 changed files with 240 additions and 191 deletions

View file

@ -250,8 +250,16 @@ int audioCallback (const void *inputBuffer,
}
// play whatever we have in the audio buffer
//
// if we haven't fired off the flange effect, check if we should
int lastYawMeasured = fabsf(data->linkedHead->getLastMeasuredYaw());
//
//
// NOTE: PER - LastMeasuredHeadYaw is now relative to body position, represents the local
// rotation of the head relative to body, this may effect flange effect!
//
//
int lastYawMeasured = fabsf(data->linkedHead->getLastMeasuredHeadYaw());
if (!samplesLeftForFlange && lastYawMeasured > MIN_FLANGE_EFFECT_THRESHOLD) {
// we should flange for one second

View file

@ -73,9 +73,9 @@ Head::Head(bool isMine) {
_head.interPupilDistance = 0.6;
_head.interBrowDistance = 0.75;
_head.nominalPupilSize = 0.10;
_head.yaw = 0.0;
_head.pitch = 0.0;
_head.roll = 0.0;
//_head.yaw = 0.0;
//_head.pitch = 0.0;
//_head.roll = 0.0;
_head.pitchRate = 0.0;
_head.yawRate = 0.0;
_head.rollRate = 0.0;
@ -104,7 +104,6 @@ Head::Head(bool isMine) {
_head.eyeContactTarget = LEFT_EYE;
_head.scale = 1.0;
_head.audioAttack = 0.0;
_head.loudness = 0.0;
_head.averageLoudness = 0.0;
_head.lastLoudness = 0.0;
_head.browAudioLift = 0.0;
@ -118,7 +117,13 @@ Head::Head(bool isMine) {
_renderPitch = 0.0;
_sphere = NULL;
_collisionElipsoid.colliding = false;
_collisionElipsoid.position = glm::vec3( 0.0, 0.0, 0.0 );
_collisionElipsoid.upVector = glm::vec3( 0.0, 0.0, 0.0 );
_collisionElipsoid.girth = 0.0;
_collisionElipsoid.height = 0.0;
if (iris_texture.size() == 0) {
switchToResourcesParentIfRequired();
unsigned error = lodepng::decode(iris_texture, iris_texture_width, iris_texture_height, iris_texture_file);
@ -127,16 +132,12 @@ Head::Head(bool isMine) {
}
}
//--------------------------------------------------
// test... just slam them into random positions...
//--------------------------------------------------
_otherAvatarHandPosition[ 0 ] = glm::vec3( 0.0f, 0.3f, 2.0f );
_otherAvatarHandPosition[ 1 ] = glm::vec3( 4.0f, 0.3f, 2.0f );
_otherAvatarHandPosition[ 2 ] = glm::vec3( 2.0f, 0.3f, 2.0f );
_otherAvatarHandPosition[ 3 ] = glm::vec3( 1.0f, 0.3f, -4.0f );
_otherAvatarHandPosition[ 4 ] = glm::vec3( -2.0f, 0.3f, -2.0f );
for (int o=0; o<MAX_OTHER_AVATARS; o++) {
_otherAvatarHandPosition[o] = glm::vec3( 0.0f, 0.0f, 0.0f );
}
}
Head::Head(const Head &otherAvatar) {
_velocity = otherAvatar._velocity;
@ -174,9 +175,9 @@ Head::Head(const Head &otherAvatar) {
_head.interPupilDistance = otherAvatar._head.interPupilDistance;
_head.interBrowDistance = otherAvatar._head.interBrowDistance;
_head.nominalPupilSize = otherAvatar._head.nominalPupilSize;
_head.yaw = otherAvatar._head.yaw;
_head.pitch = otherAvatar._head.pitch;
_head.roll = otherAvatar._head.roll;
//_head.yaw = otherAvatar._head.yaw;
//_head.pitch = otherAvatar._head.pitch;
//_head.roll = otherAvatar._head.roll;
_head.yawRate = otherAvatar._head.yawRate;
_head.pitchRate = otherAvatar._head.pitchRate;
_head.rollRate = otherAvatar._head.rollRate;
@ -205,7 +206,6 @@ Head::Head(const Head &otherAvatar) {
_head.eyeContactTarget = otherAvatar._head.eyeContactTarget;
_head.scale = otherAvatar._head.scale;
_head.audioAttack = otherAvatar._head.audioAttack;
_head.loudness = otherAvatar._head.loudness;
_head.averageLoudness = otherAvatar._head.averageLoudness;
_head.lastLoudness = otherAvatar._head.lastLoudness;
_head.browAudioLift = otherAvatar._head.browAudioLift;
@ -232,14 +232,14 @@ Head* Head::clone() const {
}
void Head::reset() {
_head.pitch = _head.yaw = _head.roll = 0;
_headPitch = _headYaw = _headRoll = 0;
_head.leanForward = _head.leanSideways = 0;
}
//this pertains to moving the head with the glasses
//---------------------------------------------------
void Head::UpdateGyros(float frametime, SerialInterface * serialInterface, int head_mirror, glm::vec3 * gravity)
void Head::UpdateGyros(float frametime, SerialInterface * serialInterface, glm::vec3 * gravity)
// Using serial data, update avatar/render position and angles
{
const float PITCH_ACCEL_COUPLING = 0.5;
@ -267,20 +267,15 @@ void Head::UpdateGyros(float frametime, SerialInterface * serialInterface, int h
const float MAX_YAW = 85;
const float MIN_YAW = -85;
if ((_head.pitch < MAX_PITCH) && (_head.pitch > MIN_PITCH))
addPitch(measured_pitch_rate * -HEAD_ROTATION_SCALE * frametime);
if ((_headPitch < MAX_PITCH) && (_headPitch > MIN_PITCH))
addHeadPitch(measured_pitch_rate * -HEAD_ROTATION_SCALE * frametime);
addRoll(-measured_roll_rate * HEAD_ROLL_SCALE * frametime);
addHeadRoll(measured_roll_rate * HEAD_ROLL_SCALE * frametime);
if (head_mirror) {
if ((_head.yaw < MAX_YAW) && (_head.yaw > MIN_YAW))
addYaw(-_head.yawRate * HEAD_ROTATION_SCALE * frametime);
addLean(-measured_lateral_accel * frametime * HEAD_LEAN_SCALE, -measured_fwd_accel*frametime * HEAD_LEAN_SCALE);
} else {
if ((_head.yaw < MAX_YAW) && (_head.yaw > MIN_YAW))
addYaw(_head.yawRate * -HEAD_ROTATION_SCALE * frametime);
addLean(measured_lateral_accel * frametime * -HEAD_LEAN_SCALE, measured_fwd_accel*frametime * HEAD_LEAN_SCALE);
}
if ((_headYaw < MAX_YAW) && (_headYaw > MIN_YAW))
addHeadYaw(_head.yawRate * HEAD_ROTATION_SCALE * frametime);
addLean(-measured_lateral_accel * frametime * HEAD_LEAN_SCALE, -measured_fwd_accel*frametime * HEAD_LEAN_SCALE);
}
void Head::addLean(float x, float z) {
@ -302,7 +297,6 @@ void Head::setMousePressed( bool d ) {
_mousePressed = d;
}
void Head::simulate(float deltaTime) {
//-------------------------------------------------------------
@ -311,9 +305,6 @@ void Head::simulate(float deltaTime) {
//-------------------------------------------------------------
if ( _isMine )
{
//-------------------------------------
// DEBUG - other avatars...
//-------------------------------------
_closestOtherAvatar = -1;
float closestDistance = 10000.0f;
@ -348,33 +339,13 @@ void Head::simulate(float deltaTime) {
}
}
/*
///for testing only (prior to having real avs working)
for (int o=0; o<NUM_OTHER_AVATARS; o++) {
//-------------------------------------
// test other avs for proximity...
//-------------------------------------
glm::vec3 v( _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position );
v -= _DEBUG_otherAvatarListPosition[o];
float distance = glm::length( v );
if ( distance < _maxArmLength ) {
if ( distance < closestDistance ) {
closestDistance = distance;
_closestOtherAvatar = o;
}
}
}
*/
}//if ( _isMine )
if ( usingBigSphereCollisionTest ) {
//--------------------------------------------------------------
// test for avatar collision response (using a big sphere :)
//--------------------------------------------------------------
updateBigSphereCollisionTest(deltaTime);
updateAvatarCollisionDetectionAndResponse(_TEST_bigSpherePosition, _TEST_bigSphereRadius, deltaTime);
}
if ( AVATAR_GRAVITY ) {
@ -460,10 +431,6 @@ void Head::simulate(float deltaTime) {
_bodyYaw += _bodyYawDelta * deltaTime;
}
// we will be eventually getting head rotation from elsewhere. For now, just setting it to body rotation
_head.yaw = _bodyYaw;
_head.pitch = _bodyPitch;
_head.roll = _bodyRoll;
//----------------------------------------------------------
// decay body yaw delta
@ -485,21 +452,30 @@ void Head::simulate(float deltaTime) {
//----------------------------------------------------------
_velocity *= ( 1.0 - LIN_VEL_DECAY * deltaTime );
//
// Update Head information
//
// we will be eventually getting head rotation from elsewhere. For now, just setting it to body rotation
//_head.yaw = _bodyYaw;
//_head.pitch = _bodyPitch;
//_head.roll = _bodyRoll;
if (!_head.noise) {
// Decay back toward center
_head.pitch *= (1.0f - DECAY*2*deltaTime);
_head.yaw *= (1.0f - DECAY*2*deltaTime);
_head.roll *= (1.0f - DECAY*2*deltaTime);
_headPitch *= (1.0f - DECAY * 2 * deltaTime);
_headYaw *= (1.0f - DECAY * 2 * deltaTime);
_headRoll *= (1.0f - DECAY * 2 * deltaTime);
}
else {
// Move toward new target
_head.pitch += (_head.pitchTarget - _head.pitch)*10*deltaTime; // (1.f - DECAY*deltaTime)*Pitch + ;
_head.yaw += (_head.yawTarget - _head.yaw )*10*deltaTime; // (1.f - DECAY*deltaTime);
_head.roll *= (1.f - DECAY*deltaTime);
_headPitch += (_head.pitchTarget - _headPitch) * 10 * deltaTime; // (1.f - DECAY*deltaTime)*Pitch + ;
_headYaw += (_head.yawTarget - _headYaw ) * 10 * deltaTime; // (1.f - DECAY*deltaTime);
_headRoll *= 1.f - (DECAY * deltaTime);
}
_head.leanForward *= (1.f - DECAY*30.f*deltaTime);
_head.leanSideways *= (1.f - DECAY*30.f*deltaTime);
_head.leanForward *= (1.f - DECAY * 30 * deltaTime);
_head.leanSideways *= (1.f - DECAY * 30 * deltaTime);
// Update where the avatar's eyes are
//
@ -509,8 +485,8 @@ void Head::simulate(float deltaTime) {
_head.eyeContact = 1;
if (!_head.eyeContact) {
// If we just stopped making eye contact,move the eyes markedly away
_head.eyeballPitch[0] = _head.eyeballPitch[1] = _head.eyeballPitch[0] + 5.0 + (randFloat() - 0.5)*10;
_head.eyeballYaw [0] = _head.eyeballYaw [1] = _head.eyeballYaw [0] + 5.0 + (randFloat() - 0.5)*5;
_head.eyeballPitch[0] = _head.eyeballPitch[1] = _head.eyeballPitch[0] + 5.0 + (randFloat() - 0.5) * 10;
_head.eyeballYaw [0] = _head.eyeballYaw [1] = _head.eyeballYaw [0] + 5.0 + (randFloat() - 0.5) * 5;
} else {
// If now making eye contact, turn head to look right at viewer
SetNewHeadTarget(0,0);
@ -537,63 +513,87 @@ void Head::simulate(float deltaTime) {
if (_head.eyeContactTarget == RIGHT_EYE) eye_target_yaw_adjust = -DEGREES_BETWEEN_VIEWER_EYES;
if (_head.eyeContactTarget == MOUTH) eye_target_pitch_adjust = DEGREES_TO_VIEWER_MOUTH;
_head.eyeballPitch[0] = _head.eyeballPitch[1] = -_head.pitch + eye_target_pitch_adjust;
_head.eyeballYaw[0] = _head.eyeballYaw[1] = -_head.yaw + eye_target_yaw_adjust;
_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)
{
_head.pitch += (randFloat() - 0.5)*0.2*_head.noiseEnvelope;
_head.yaw += (randFloat() - 0.5)*0.3*_head.noiseEnvelope;
//PupilSize += (randFloat() - 0.5)*0.001*NoiseEnvelope;
_headPitch += (randFloat() - 0.5) * 0.2 * _head.noiseEnvelope;
_headYaw += (randFloat() - 0.5) * 0.3 *_head.noiseEnvelope;
//PupilSize += (randFloat() - 0.5) * 0.001*NoiseEnvelope;
if (randFloat() < 0.005) _head.mouthWidth = MouthWidthChoices[rand()%3];
if (!_head.eyeContact) {
if (randFloat() < 0.01) _head.eyeballPitch[0] = _head.eyeballPitch[1] = (randFloat() - 0.5)*20;
if (randFloat() < 0.01) _head.eyeballYaw[0] = _head.eyeballYaw[1] = (randFloat()- 0.5)*10;
if (randFloat() < 0.01) _head.eyeballPitch[0] = _head.eyeballPitch[1] = (randFloat() - 0.5) * 20;
if (randFloat() < 0.01) _head.eyeballYaw[0] = _head.eyeballYaw[1] = (randFloat()- 0.5) * 10;
}
if ((randFloat() < 0.005) && (fabs(_head.pitchTarget - _head.pitch) < 1.0) && (fabs(_head.yawTarget - _head.yaw) < 1.0)) {
SetNewHeadTarget((randFloat()-0.5)*20.0, (randFloat()-0.5)*45.0);
if ((randFloat() < 0.005) && (fabs(_head.pitchTarget - _headPitch) < 1.0) && (fabs(_head.yawTarget - _headYaw) < 1.0)) {
SetNewHeadTarget((randFloat()-0.5) * 20.0, (randFloat()-0.5) * 45.0);
}
if (0) {
// Pick new target
_head.pitchTarget = (randFloat() - 0.5)*45;
_head.yawTarget = (randFloat() - 0.5)*22;
_head.pitchTarget = (randFloat() - 0.5) * 45;
_head.yawTarget = (randFloat() - 0.5) * 22;
}
if (randFloat() < 0.01)
{
_head.eyebrowPitch[0] = _head.eyebrowPitch[1] = BrowPitchAngle[rand()%3];
_head.eyebrowRoll [0] = _head.eyebrowRoll[1] = BrowRollAngle[rand()%5];
_head.eyebrowRoll [1]*=-1;
_head.eyebrowRoll [1] *=-1;
}
}
}
float Head::getGirth() {
return COLLISION_BODY_RADIUS;
}
float Head::getHeight() {
return COLLISION_HEIGHT;
}
glm::vec3 Head::getBodyUpDirection() {
return _orientation.getUp();
}
bool Head::testForCollision( glm::vec3 collisionPosition, float collisionGirth, float collisionHeight, glm::vec3 collisionUpVector ) {
_collisionElipsoid.colliding = false;
_collisionElipsoid.position = glm::vec3( 0.0, 0.0, 0.0 );
_collisionElipsoid.upVector = glm::vec3( 0.0, 0.0, 0.0 );
_collisionElipsoid.girth = 0.0;
_collisionElipsoid.height = 0.0;
return false;
}
//--------------------------------------------------------------------------------
// This is a workspace for testing avatar body collision detection and response
//--------------------------------------------------------------------------------
void Head::updateBigSphereCollisionTest( float deltaTime ) {
void Head::updateAvatarCollisionDetectionAndResponse( glm::vec3 collisionPosition, float collisionRadius, float deltaTime ) {
float myBodyApproximateBoundingRadius = 1.0f;
glm::vec3 vectorFromMyBodyToBigSphere(_bodyPosition - _TEST_bigSpherePosition);
glm::vec3 vectorFromMyBodyToBigSphere(_bodyPosition - collisionPosition);
bool jointCollision = false;
float distanceToBigSphere = glm::length(vectorFromMyBodyToBigSphere);
if ( distanceToBigSphere < myBodyApproximateBoundingRadius + _TEST_bigSphereRadius)
if ( distanceToBigSphere < myBodyApproximateBoundingRadius + collisionRadius )
{
for (int b=0; b<NUM_AVATAR_BONES; b++)
{
glm::vec3 vectorFromJointToBigSphereCenter(_bone[b].springyPosition - _TEST_bigSpherePosition);
glm::vec3 vectorFromJointToBigSphereCenter(_bone[b].springyPosition - collisionPosition);
float distanceToBigSphereCenter = glm::length(vectorFromJointToBigSphereCenter);
float combinedRadius = _bone[b].radius + _TEST_bigSphereRadius;
float combinedRadius = _bone[b].radius + collisionRadius;
if ( distanceToBigSphereCenter < combinedRadius )
{
jointCollision = true;
@ -606,7 +606,7 @@ void Head::updateBigSphereCollisionTest( float deltaTime ) {
_bone[b].springyVelocity += collisionForce * 30.0f * deltaTime;
_velocity += collisionForce * 100.0f * deltaTime;
_bone[b].springyPosition = _TEST_bigSpherePosition + directionVector * combinedRadius;
_bone[b].springyPosition = collisionPosition + directionVector * combinedRadius;
}
}
}
@ -619,11 +619,11 @@ void Head::updateBigSphereCollisionTest( float deltaTime ) {
}
}
}
void Head::render(int faceToFace) {
void Head::render(bool lookingInMirror) {
//---------------------------------------------------
// show avatar position
@ -656,26 +656,13 @@ void Head::render(int faceToFace) {
//---------------------------------------------------
// render head
//---------------------------------------------------
renderHead(faceToFace);
renderHead(lookingInMirror);
//---------------------------------------------------------------------------
// if this is my avatar, then render my interactions with the other avatars
//---------------------------------------------------------------------------
if ( _isMine )
{
/*
//---------------------------------------------------
// render other avatars (DEBUG TEST)
//---------------------------------------------------
for (int o=0; o<_numOtherAvatarsInView; o++) {
glPushMatrix();
glTranslatef( _otherAvatarHandPosition[o].x, _otherAvatarHandPosition[o].y, _otherAvatarHandPosition[o].z );
glScalef( 0.03, 0.03, 0.03 );
glutSolidSphere( 1, 10, 10 );
glPopMatrix();
}
*/
if (_usingBodySprings) {
if ( _closestOtherAvatar != -1 ) {
@ -693,9 +680,9 @@ void Head::render(int faceToFace) {
}
}
void Head::renderHead(int faceToFace) {
void Head::renderHead(bool lookingInMirror) {
int side = 0;
glEnable(GL_DEPTH_TEST);
@ -721,9 +708,15 @@ void Head::renderHead(int faceToFace) {
glScalef( 0.03, 0.03, 0.03 );
glRotatef(_head.yaw, 0, 1, 0);
glRotatef(_head.pitch, 1, 0, 0);
glRotatef(_head.roll, 0, 0, 1);
if (lookingInMirror) {
glRotatef(_bodyYaw - _headYaw, 0, 1, 0);
glRotatef(_bodyPitch + _headPitch, 1, 0, 0);
glRotatef(_bodyRoll - _headRoll, 0, 0, 1);
} else {
glRotatef(_bodyYaw + _headYaw, 0, 1, 0);
glRotatef(_bodyPitch + _headPitch, 1, 0, 0);
glRotatef(_bodyRoll + _headRoll, 0, 0, 1);
}
glScalef(2.0, 2.0, 2.0);
glColor3fv(skinColor);
@ -743,17 +736,17 @@ void Head::renderHead(int faceToFace) {
glPopMatrix();
// _eyebrows
_head.audioAttack = 0.9*_head.audioAttack + 0.1*fabs(_head.loudness - _head.lastLoudness);
_head.lastLoudness = _head.loudness;
_head.audioAttack = 0.9 * _head.audioAttack + 0.1 * fabs(_audioLoudness - _head.lastLoudness);
_head.lastLoudness = _audioLoudness;
const float BROW_LIFT_THRESHOLD = 100;
if (_head.audioAttack > BROW_LIFT_THRESHOLD)
_head.browAudioLift += sqrt(_head.audioAttack)/1000.0;
_head.browAudioLift += sqrt(_head.audioAttack) / 1000.0;
_head.browAudioLift *= .90;
glPushMatrix();
glTranslatef(-_head.interBrowDistance/2.0,0.4,0.45);
glTranslatef(-_head.interBrowDistance / 2.0,0.4,0.45);
for(side = 0; side < 2; side++) {
glColor3fv(browColor);
glPushMatrix();
@ -807,7 +800,7 @@ void Head::renderHead(int faceToFace) {
glPushMatrix();
{
glRotatef(_head.eyeballPitch[1], 1, 0, 0);
glRotatef(_head.eyeballYaw[1] + _head.yaw + _head.pupilConverge, 0, 1, 0);
glRotatef(_head.eyeballYaw[1] + _headYaw + _head.pupilConverge, 0, 1, 0);
glTranslatef(0,0,.35);
glRotatef(-75,1,0,0);
glScalef(1.0, 0.4, 1.0);
@ -833,7 +826,7 @@ void Head::renderHead(int faceToFace) {
glPushMatrix();
{
glRotatef(_head.eyeballPitch[0], 1, 0, 0);
glRotatef(_head.eyeballYaw[0] + _head.yaw - _head.pupilConverge, 0, 1, 0);
glRotatef(_head.eyeballYaw[0] + _headYaw - _head.pupilConverge, 0, 1, 0);
glTranslatef(0, 0, .35);
glRotatef(-75, 1, 0, 0);
glScalef(1.0, 0.4, 1.0);
@ -1131,18 +1124,18 @@ void Head::updateHandMovement() {
_bone[ AVATAR_BONE_RIGHT_HAND ].position += transformedHandMovement;
setHandState(_mousePressed);
//if holding hands, add a pull to the hand...
if ( _usingBodySprings ) {
if ( _closestOtherAvatar != -1 ) {
if ( _mousePressed ) {
glm::vec3 handToHandVector( _otherAvatarHandPosition[ _closestOtherAvatar ]);
handToHandVector -= _bone[ AVATAR_BONE_RIGHT_HAND ].position;
//_bone[ AVATAR_BONE_RIGHT_HAND ].springyVelocity -= handPull;
_bone[ AVATAR_BONE_RIGHT_HAND ].position = _otherAvatarHandPosition[ _closestOtherAvatar ];
}
}
}
}
@ -1152,7 +1145,6 @@ void Head::updateHandMovement() {
glm::vec3 armVector = _bone[ AVATAR_BONE_RIGHT_HAND ].position;
armVector -= _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position;
//-------------------------------------------------------------------------------
// test to see if right hand is being dragged beyond maximum arm length
//-------------------------------------------------------------------------------
@ -1173,30 +1165,13 @@ void Head::updateHandMovement() {
constrainedPosition += armVector;
_bone[ AVATAR_BONE_RIGHT_HAND ].position = constrainedPosition;
}
/*
//-------------------------------------------------------------------------------
// keep arm from going through av body...
//-------------------------------------------------------------------------------
glm::vec3 adjustedArmVector = _bone[ AVATAR_BONE_RIGHT_HAND ].position;
adjustedArmVector -= _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position;
float rightComponent = glm::dot( adjustedArmVector, avatar.orientation.getRight() );
if ( rightComponent < 0.0 )
{
_bone[ AVATAR_BONE_RIGHT_HAND ].position -= avatar.orientation.getRight() * rightComponent;
}
*/
//-----------------------------------------------------------------------------
// set elbow position
//-----------------------------------------------------------------------------
glm::vec3 newElbowPosition = _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position;
newElbowPosition += armVector * ONE_HALF;
//glm::vec3 perpendicular = glm::cross( frontDirection, 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;
@ -1272,7 +1247,7 @@ void Head::renderBody() {
}
}
if (( _usingBodySprings ) && ( _mousePressed )) {
if (( _usingBodySprings ) && ( getHandState() )) {
glColor4f( 1.0, 1.0, 0.5, 0.5 );
glPushMatrix();
glTranslatef
@ -1300,9 +1275,6 @@ void Head::renderBoneAsBlock( AvatarBoneID b ) {
glPopMatrix();
}
void Head::SetNewHeadTarget(float pitch, float yaw) {
_head.pitchTarget = pitch;
_head.yawTarget = yaw;

View file

@ -29,6 +29,9 @@ const float YAW_MAG = 300.0;
const float TEST_YAW_DECAY = 5.0;
const float LIN_VEL_DECAY = 5.0;
const float COLLISION_BODY_RADIUS = 0.3;
const float COLLISION_HEIGHT = 1.5;
enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH};
#define FWD 0
@ -41,7 +44,7 @@ enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH};
#define ROT_RIGHT 7
#define MAX_DRIVE_KEYS 8
#define MAX_OTHER_AVATARS 50 // temporary - for testing purposes!
#define MAX_OTHER_AVATARS 10 // temporary - for testing purposes!
enum AvatarMode
{
@ -81,6 +84,15 @@ enum AvatarBoneID
NUM_AVATAR_BONES
};
struct AvatarCollisionElipsoid
{
bool colliding;
glm::vec3 position;
float girth;
float height;
glm::vec3 upVector;
};
struct AvatarBone
{
AvatarBoneID parent; // which bone is this bone connected to?
@ -100,9 +112,6 @@ struct AvatarBone
struct AvatarHead
{
float pitch;
float yaw;
float roll;
float pitchRate;
float yawRate;
float rollRate;
@ -134,7 +143,7 @@ struct AvatarHead
eyeContactTargets eyeContactTarget;
// Sound loudness information
float loudness, lastLoudness;
float lastLoudness;
float averageLoudness;
float audioAttack;
};
@ -148,11 +157,8 @@ class Head : public AvatarData {
Head* clone() const;
void reset();
void UpdateGyros(float frametime, SerialInterface * serialInterface, int head_mirror, glm::vec3 * gravity);
void UpdateGyros(float frametime, SerialInterface * serialInterface, glm::vec3 * gravity);
void setNoise (float mag) { _head.noise = mag; }
void setPitch(float p) {_head.pitch = p; }
void setYaw(float y) {_head.yaw = y; }
void setRoll(float r) {_head.roll = r; };
void setScale(float s) {_head.scale = s; };
void setRenderYaw(float y) {_renderYaw = y;}
void setRenderPitch(float p) {_renderPitch = p;}
@ -160,14 +166,8 @@ class Head : public AvatarData {
float getRenderPitch() {return _renderPitch;}
void setLeanForward(float dist);
void setLeanSideways(float dist);
void addPitch(float p) {_head.pitch -= p; }
void addYaw(float y){_head.yaw -= y; }
void addRoll(float r){_head.roll += r; }
void addLean(float x, float z);
float getPitch() {return _head.pitch;}
float getRoll() {return _head.roll;}
float getYaw() {return _head.yaw;}
float getLastMeasuredYaw() {return _head.yawRate;}
float getLastMeasuredHeadYaw() const {return _head.yawRate;}
float getBodyYaw() {return _bodyYaw;};
void addBodyYaw(float y) {_bodyYaw += y;};
@ -175,24 +175,27 @@ class Head : public AvatarData {
glm::vec3 getHeadLookatDirectionUp();
glm::vec3 getHeadLookatDirectionRight();
glm::vec3 getHeadPosition();
glm::vec3 getBonePosition( AvatarBoneID b );
glm::vec3 getBonePosition( AvatarBoneID b );
glm::vec3 getBodyUpDirection();
float getGirth();
float getHeight();
AvatarMode getMode();
void setMousePressed( bool pressed );
void render(int faceToFace);
void render(bool lookingInMirror);
void renderBody();
void renderHead( int faceToFace);
void renderHead(bool lookingInMirror);
void simulate(float);
void startHandMovement();
void stopHandMovement();
void setHandMovementValues( glm::vec3 movement );
void updateHandMovement();
float getLoudness() {return _head.loudness;};
float getAverageLoudness() {return _head.averageLoudness;};
void setAverageLoudness(float al) {_head.averageLoudness = al;};
void setLoudness(float l) {_head.loudness = l;};
bool testForCollision( glm::vec3 collisionPosition, float collisionGirth, float collisionHeight, glm::vec3 collisionUpVector );
void SetNewHeadTarget(float, float);
@ -236,7 +239,9 @@ class Head : public AvatarData {
int _driveKeys[MAX_DRIVE_KEYS];
GLUquadric* _sphere;
float _renderYaw;
float _renderPitch; // Pitch from view frustum when this is own head.
float _renderPitch; // Pitch from view frustum when this is own head
AvatarCollisionElipsoid _collisionElipsoid;
//
// Related to getting transmitter UDP data used to animate the avatar hand
@ -253,7 +258,7 @@ class Head : public AvatarData {
void initializeBodySprings();
void updateBodySprings( float deltaTime );
void calculateBoneLengths();
void updateBigSphereCollisionTest( float deltaTime );
void updateAvatarCollisionDetectionAndResponse( glm::vec3, float radius, float deltaTime );
void readSensors();
void renderBoneAsBlock( AvatarBoneID b );

View file

@ -96,8 +96,6 @@ int packetsPerSecond = 0;
int bytesPerSecond = 0;
int bytesCount = 0;
int headMirror = 1; // Whether to mirror own head when viewing it
int WIDTH = 1200; // Window size
int HEIGHT = 800;
int fullscreen = 0;
@ -163,7 +161,7 @@ int noiseOn = 0; // Whether to add random noise
float noise = 1.0; // Overall magnitude scaling for random noise levels
int displayLevels = 0;
int displayHead = 0;
bool lookingInMirror = 0; // Are we currently rendering one's own head as if in mirror?
int displayField = 0;
int displayHeadMouse = 1; // Display sample mouse pointer controlled by head movement
@ -459,7 +457,7 @@ void updateAvatar(float frametime)
float gyroPitchRate = serialPort.getRelativeValue(HEAD_PITCH_RATE);
float gyroYawRate = serialPort.getRelativeValue(HEAD_YAW_RATE );
myAvatar.UpdateGyros(frametime, &serialPort, headMirror, &gravity);
myAvatar.UpdateGyros(frametime, &serialPort, &gravity);
//
// Update gyro-based mouse (X,Y on screen)
@ -819,7 +817,7 @@ void display(void)
//--------------------------------------------------------
// camera settings
//--------------------------------------------------------
if ( displayHead ) {
if ( ::lookingInMirror ) {
//-----------------------------------------------
// set the camera to looking at my own face
//-----------------------------------------------
@ -912,7 +910,7 @@ void display(void)
drawGroundPlaneGrid( 5.0f, 9 );
// Draw cloud of dots
if (!displayHead) cloud.render();
if (!::lookingInMirror) cloud.render();
// Draw voxels
if ( showingVoxels )
@ -934,16 +932,16 @@ void display(void)
}
}
if ( !displayHead ) balls.render();
if ( !::lookingInMirror ) balls.render();
// Render the world box
if (!displayHead && statsOn) render_world_box();
if (!::lookingInMirror && statsOn) render_world_box();
// brad's frustum for debugging
if (::frustumOn) renderViewFrustum(::viewFrustum);
//Render my own avatar
myAvatar.render(true);
myAvatar.render(::lookingInMirror);
}
glPopMatrix();
@ -961,7 +959,7 @@ void display(void)
if (audioScope.getState()) audioScope.render();
#endif
if (displayHeadMouse && !displayHead && statsOn) {
if (displayHeadMouse && !::lookingInMirror && statsOn) {
// Display small target box at center or head mouse target that can also be used to measure LOD
glColor3f(1.0, 1.0, 1.0);
glDisable(GL_LINE_SMOOTH);
@ -1057,7 +1055,7 @@ int setValue(int state, bool *value) {
}
int setHead(int state) {
return setValue(state, &displayHead);
return setValue(state, &::lookingInMirror);
}
int setField(int state) {
@ -1090,10 +1088,6 @@ int setMenu(int state) {
return setValue(state, &::menuOn);
}
int setMirror(int state) {
return setValue(state, &headMirror);
}
int setDisplayFrustum(int state) {
return setValue(state, &::frustumOn);
}
@ -1199,10 +1193,9 @@ void initMenu() {
MenuColumn *menuColumnOptions, *menuColumnTools, *menuColumnDebug, *menuColumnFrustum;
// Options
menuColumnOptions = menu.addColumn("Options");
menuColumnOptions->addRow("(H)ead", setHead);
menuColumnOptions->addRow("Mirror (h)", setHead);
menuColumnOptions->addRow("Field (f)", setField);
menuColumnOptions->addRow("(N)oise", setNoise);
menuColumnOptions->addRow("Mirror", setMirror);
menuColumnOptions->addRow("(V)oxels", setVoxels);
menuColumnOptions->addRow("Stars (*)", setStars);
menuColumnOptions->addRow("(Q)uit", quitApp);
@ -1411,9 +1404,9 @@ void key(unsigned char k, int x, int y)
}
if (k == 'h') {
displayHead = !displayHead;
::lookingInMirror = !::lookingInMirror;
#ifndef _WIN32
audio.setMixerLoopbackFlag(displayHead);
audio.setMixerLoopbackFlag(::lookingInMirror);
#endif
}
@ -1509,6 +1502,9 @@ void idle(void) {
{
Head *avatar = (Head *)agent->getLinkedData();
avatar->simulate(deltaTime);
//not ready yet...
//myAvatar.testForCollision( avatar->getBodyPosition(), avatar->getGirth(), avatar->getHeight(), avatar->getBodyUpDirection() );
}
}

View file

@ -34,9 +34,14 @@ int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPo
}
AvatarData::AvatarData() :
_handPosition(0,0,0),
_bodyYaw(-90.0),
_bodyPitch(0.0),
_bodyRoll(0.0),
_headYaw(0),
_headPitch(0),
_headRoll(0),
_handState(0),
_cameraPosition(0,0,0),
_cameraDirection(0,0,0),
_cameraUp(0,0,0),
@ -63,15 +68,31 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
// that can pack any type given the number of bytes
// and return the number of bytes to push the pointer
// Body world position
memcpy(destinationBuffer, &_bodyPosition, sizeof(float) * 3);
destinationBuffer += sizeof(float) * 3;
// Body rotation (NOTE: This needs to become a quaternion to save two bytes)
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyYaw);
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyPitch);
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll);
// Head rotation (NOTE: This needs to become a quaternion to save two bytes)
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headYaw);
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headPitch);
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headRoll);
// Hand Position
memcpy(destinationBuffer, &_handPosition, sizeof(float) * 3);
destinationBuffer += sizeof(float) * 3;
// Hand State (0 = not grabbing, 1 = grabbing)
memcpy(destinationBuffer, &_handState, sizeof(char));
destinationBuffer += sizeof(char);
// Instantaneous audio loudness (used to drive facial animation)
memcpy(destinationBuffer, &_audioLoudness, sizeof(float));
destinationBuffer += sizeof(float);
// camera details
memcpy(destinationBuffer, &_cameraPosition, sizeof(_cameraPosition));
@ -91,6 +112,7 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) {
memcpy(destinationBuffer, &_cameraFarClip, sizeof(_cameraFarClip));
destinationBuffer += sizeof(_cameraFarClip);
return destinationBuffer - bufferStart;
}
@ -102,16 +124,32 @@ int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) {
unsigned char* startPosition = sourceBuffer;
// Body world position
memcpy(&_bodyPosition, sourceBuffer, sizeof(float) * 3);
sourceBuffer += sizeof(float) * 3;
// Body rotation (NOTE: This needs to become a quaternion to save two bytes)
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyYaw);
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyPitch);
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyRoll);
// Head rotation (NOTE: This needs to become a quaternion to save two bytes)
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_headYaw);
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_headPitch);
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_headRoll);
// Hand Position
memcpy(&_handPosition, sourceBuffer, sizeof(float) * 3);
sourceBuffer += sizeof(float) * 3;
// Hand State
memcpy(&_handState, sourceBuffer, sizeof(char));
sourceBuffer += sizeof(char);
// Instantaneous audio loudness (used to drive facial animation)
memcpy(&_audioLoudness, sourceBuffer, sizeof(float));
sourceBuffer += sizeof(float);
// camera details
memcpy(&_cameraPosition, sourceBuffer, sizeof(_cameraPosition));
sourceBuffer += sizeof(_cameraPosition);

View file

@ -27,16 +27,34 @@ public:
int getBroadcastData(unsigned char* destinationBuffer);
int parseData(unsigned char* sourceBuffer, int numBytes);
// Body Rotation
float getBodyYaw();
void setBodyYaw(float bodyYaw);
float getBodyPitch();
void setBodyPitch(float bodyPitch);
float getBodyRoll();
void setBodyYaw(float bodyYaw);
void setBodyPitch(float bodyPitch);
void setBodyRoll(float bodyRoll);
// getters for camera details
// Head Rotation
void setHeadPitch(float p) {_headPitch = p; }
void setHeadYaw(float y) {_headYaw = y; }
void setHeadRoll(float r) {_headRoll = r; };
const float getHeadPitch() const { return _headPitch; };
const float getHeadYaw() const { return _headYaw; };
const float getHeadRoll() const { return _headRoll; };
void addHeadPitch(float p) {_headPitch -= p; }
void addHeadYaw(float y){_headYaw -= y; }
void addHeadRoll(float r){_headRoll += r; }
// Hand State
void setHandState(char s) { _handState = s; };
const float getHandState() const {return _handState; };
// Instantaneous audio loudness to drive mouth/facial animation
void setLoudness(float l) { _audioLoudness = l; };
const float getLoudness() const {return _audioLoudness; };
// getters for camera details
const glm::vec3& getCameraPosition() const { return _cameraPosition; };
const glm::vec3& getCameraDirection() const { return _cameraDirection; }
const glm::vec3& getCameraUp() const { return _cameraUp; }
@ -60,10 +78,22 @@ protected:
glm::vec3 _bodyPosition;
glm::vec3 _handPosition;
// Body rotation
float _bodyYaw;
float _bodyPitch;
float _bodyRoll;
// Head rotation (relative to body)
float _headYaw;
float _headPitch;
float _headRoll;
// Audio loudness (used to drive facial animation)
float _audioLoudness;
// Hand state (are we grabbing something or not)
char _handState;
// camera details for the avatar
glm::vec3 _cameraPosition;