Lots of small changes in the head (evolving into "avatar") to include skeleton. Also, added camera behaviors for navigation

This commit is contained in:
Jeffrey Ventrella 2013-04-08 18:46:00 -07:00
parent ead0d2948e
commit cd1533dc7c
3 changed files with 425 additions and 191 deletions

View file

@ -3,6 +3,7 @@
// interface
//
// Created by Philip Rosedale on 9/11/12.
// adapted by Jeffrey Ventrella, starting on April 2, 2013
// Copyright (c) 2012 Physical, Inc.. All rights reserved.
//
@ -45,9 +46,9 @@ Head::Head()
{
initializeAvatar();
position = glm::vec3(0,0,0);
velocity = glm::vec3(0,0,0);
thrust = glm::vec3(0,0,0);
position = glm::vec3(0,0,0);
velocity = glm::vec3(0,0,0);
thrust = glm::vec3(0,0,0);
for (int i = 0; i < MAX_DRIVE_KEYS; i++) driveKeys[i] = false;
@ -83,7 +84,7 @@ Head::Head()
browAudioLift = 0.0;
noise = 0;
handOffset.clear();
handOffset = glm::vec3( 0.0, 0.0, 0.0 );
sphere = NULL;
@ -194,7 +195,6 @@ void Head::reset()
void Head::UpdatePos(float frametime, SerialInterface * serialInterface, int head_mirror, glm::vec3 * gravity)
// Using serial data, update avatar/render position and angles
{
const float PITCH_ACCEL_COUPLING = 0.5;
const float ROLL_ACCEL_COUPLING = -1.0;
float measured_pitch_rate = serialInterface->getRelativeValue(PITCH_RATE);
@ -241,7 +241,7 @@ void Head::UpdatePos(float frametime, SerialInterface * serialInterface, int hea
//---------------------------------------------------
void Head::setAvatarPosition( double x, double y, double z )
{
avatar.position.setXYZ( x, y, z );
avatar.position = glm::dvec3( x, y, z );
}
@ -276,48 +276,159 @@ void Head::setLeanSideways(float dist){
//---------------------------------------------------
void Head::simulate(float deltaTime)
{
simulateAvatar( deltaTime );
updateAvatarSkeleton();
/*
glm::vec3 forward
(
-sin( avatar.yaw * PI_OVER_180 ),
sin( avatar.pitch * PI_OVER_180 ),
cos( avatar.roll * PI_OVER_180 )
);
*/
/*
glm::vec3 forward(-sinf(getRenderYaw()*PI/180),
sinf(getRenderPitch()*PI/180),
cosf(getRenderYaw()*PI/180));
thrust = glm::vec3(0);
*/
const float THRUST_MAG = 10.0;
const float THRUST_LATERAL_MAG = 10.0;
const float THRUST_VERTICAL_MAG = 10.0;
if (driveKeys[FWD]) {
thrust += THRUST_MAG*forward;
/*
const float THRUST_LATERAL_MAG = 10.0;
const float THRUST_VERTICAL_MAG = 10.0;
*/
avatar.thrust = glm::dvec3( 0.0, 0.0, 0.0 );
if (driveKeys[FWD])
{
//position.x += avatar.orientation.getFront().getX() * 0.01;
//position.y += avatar.orientation.getFront().getY() * 0.01;
//position.z -= avatar.orientation.getFront().getZ() * 0.01;
avatar.thrust.x += avatar.orientation.getFront().getX() * THRUST_MAG;
avatar.thrust.y += avatar.orientation.getFront().getY() * THRUST_MAG;
avatar.thrust.z -= avatar.orientation.getFront().getZ() * THRUST_MAG;
//thrust += THRUST_MAG*forward;
}
if (driveKeys[BACK]) {
thrust += -THRUST_MAG*forward;
}
if (driveKeys[RIGHT]) {
thrust.x += forward.z*-THRUST_LATERAL_MAG;
thrust.z += forward.x*THRUST_LATERAL_MAG;
}
if (driveKeys[LEFT]) {
thrust.x += forward.z*THRUST_LATERAL_MAG;
thrust.z += forward.x*-THRUST_LATERAL_MAG;
}
if (driveKeys[UP]) {
thrust.y += -THRUST_VERTICAL_MAG;
}
if (driveKeys[DOWN]) {
thrust.y += THRUST_VERTICAL_MAG;
if (driveKeys[BACK])
{
//position.x -= avatar.orientation.getFront().getX() * 0.01;
//position.y -= avatar.orientation.getFront().getY() * 0.01;
//position.z += avatar.orientation.getFront().getZ() * 0.01;
avatar.thrust.x -= avatar.orientation.getFront().getX() * THRUST_MAG;
avatar.thrust.y -= avatar.orientation.getFront().getY() * THRUST_MAG;
avatar.thrust.z += avatar.orientation.getFront().getZ() * THRUST_MAG;
//thrust += -THRUST_MAG*forward;
}
if (driveKeys[RIGHT])
{
//position.x += avatar.orientation.getRight().getX() * 0.01;
//position.y += avatar.orientation.getRight().getY() * 0.01;
//position.z -= avatar.orientation.getRight().getZ() * 0.01;
avatar.thrust.x += avatar.orientation.getRight().getX() * THRUST_MAG;
avatar.thrust.y += avatar.orientation.getRight().getY() * THRUST_MAG;
avatar.thrust.z -= avatar.orientation.getRight().getZ() * THRUST_MAG;
//thrust.x += forward.z*-THRUST_LATERAL_MAG;
//thrust.z += forward.x*THRUST_LATERAL_MAG;
}
if (driveKeys[LEFT])
{
//position.x -= avatar.orientation.getRight().getX() * 0.01;
//position.y -= avatar.orientation.getRight().getY() * 0.01;
//position.z += avatar.orientation.getRight().getZ() * 0.01;
avatar.thrust.x -= avatar.orientation.getRight().getX() * THRUST_MAG;
avatar.thrust.y -= avatar.orientation.getRight().getY() * THRUST_MAG;
avatar.thrust.z += avatar.orientation.getRight().getZ() * THRUST_MAG;
//thrust.x += forward.z*THRUST_LATERAL_MAG;
//thrust.z += forward.x*-THRUST_LATERAL_MAG;
}
if (driveKeys[UP])
{
//position.x -= avatar.orientation.getUp().getX() * 0.01;
//position.y -= avatar.orientation.getUp().getY() * 0.01;
//position.z += avatar.orientation.getUp().getZ() * 0.01;
avatar.thrust.x -= avatar.orientation.getUp().getX() * THRUST_MAG;
avatar.thrust.y -= avatar.orientation.getUp().getY() * THRUST_MAG;
avatar.thrust.z += avatar.orientation.getUp().getZ() * THRUST_MAG;
//thrust.y += -THRUST_VERTICAL_MAG;
}
if (driveKeys[DOWN])
{
//position.x += avatar.orientation.getUp().getX() * 0.01;
//position.y += avatar.orientation.getUp().getY() * 0.01;
//position.z -= avatar.orientation.getUp().getZ() * 0.01;
avatar.thrust.x += avatar.orientation.getUp().getX() * THRUST_MAG;
avatar.thrust.y += avatar.orientation.getUp().getY() * THRUST_MAG;
avatar.thrust.z -= avatar.orientation.getUp().getZ() * THRUST_MAG;
//thrust.y += THRUST_VERTICAL_MAG;
}
if (driveKeys[ROT_RIGHT])
{
avatar.yawDelta -= 300.0 * deltaTime;
}
if (driveKeys[ROT_LEFT])
{
avatar.yawDelta += 300.0 * deltaTime;
}
avatar.yaw += avatar.yawDelta * deltaTime;
const float TEST_YAW_DECAY = 5.0;
avatar.yawDelta *= ( 1.0 - TEST_YAW_DECAY * deltaTime );
//avatar.yawDelta *= 0.99;
avatar.velocity += avatar.thrust * (double)deltaTime;
position += avatar.velocity * (double)deltaTime;
//avatar.velocity *= 0.9;
const float LIN_VEL_DECAY = 5.0;
avatar.velocity *= ( 1.0 - LIN_VEL_DECAY * deltaTime );
/*
// Increment velocity as time
velocity += thrust * deltaTime;
// Increment position as a function of velocity
position += velocity * deltaTime;
*/
/*
// Decay velocity
const float LIN_VEL_DECAY = 5.0;
velocity *= (1.0 - LIN_VEL_DECAY*deltaTime);
*/
if (!noise)
{
// Decay back toward center
@ -335,6 +446,8 @@ void Head::simulate(float deltaTime)
leanForward *= (1.f - DECAY*30.f*deltaTime);
leanSideways *= (1.f - DECAY*30.f*deltaTime);
// Update where the avatar's eyes are
//
// First, decide if we are making eye contact or not
@ -351,6 +464,8 @@ void Head::simulate(float deltaTime)
}
}
const float DEGREES_BETWEEN_VIEWER_EYES = 3;
const float DEGREES_TO_VIEWER_MOUTH = 7;
@ -374,8 +489,8 @@ void Head::simulate(float deltaTime)
EyeballPitch[0] = EyeballPitch[1] = -Pitch + eye_target_pitch_adjust;
EyeballYaw[0] = EyeballYaw[1] = -Yaw + eye_target_yaw_adjust;
}
if (noise)
{
Pitch += (randFloat() - 0.5)*0.2*NoiseEnvelope;
@ -409,7 +524,8 @@ void Head::simulate(float deltaTime)
}
}
//hand->simulate(deltaTime);
//hand->simulate(deltaTime);
}
@ -419,43 +535,49 @@ void Head::simulate(float deltaTime)
//---------------------------------------------------
void Head::render(int faceToFace, int isMine)
{
// render avatar
renderAvatar();
renderBody();
renderHead( faceToFace, isMine );
}
//---------------------------------------------------
void Head::renderHead( int faceToFace, int isMine )
{
int side = 0;
// Always render own hand, but don't render head unless showing face2face
glEnable(GL_DEPTH_TEST);
glPushMatrix();
//glScalef(scale, scale, scale);
//glScalef(scale, scale, scale);
glTranslatef
(
avatar.bone[ AVATAR_BONE_HEAD ].worldPosition.x,
avatar.bone[ AVATAR_BONE_HEAD ].worldPosition.y,
avatar.bone[ AVATAR_BONE_HEAD ].worldPosition.z
);
glScalef( 0.03, 0.03, 0.03 );
glTranslatef
(
avatar.bone[ AVATAR_BONE_HEAD ].position.x,
avatar.bone[ AVATAR_BONE_HEAD ].position.y,
avatar.bone[ AVATAR_BONE_HEAD ].position.z
);
glScalef( 0.03, 0.03, 0.03 );
glTranslatef(leanSideways, 0.f, leanForward);
//glTranslatef(leanSideways, 0.f, leanForward);
glRotatef(Yaw, 0, 1, 0);
//glRotatef(Yaw, 0, 1, 0);
glRotatef( avatar.yaw, 0, 1, 0);
//hand->render(1);
//hand->render(1);
// Don't render a head if it is really close to your location, because that is your own head!
//if (!isMine || faceToFace)
//if (!isMine || faceToFace)
{
glRotatef(Pitch, 1, 0, 0);
glRotatef(Roll, 0, 0, 1);
// Overall scale of head
if (faceToFace) glScalef(1.5, 2.0, 2.0);
else glScalef(0.75, 1.0, 1.0);
@ -595,7 +717,7 @@ glScalef( 0.03, 0.03, 0.03 );
//---------------------------------------------------------
void Head::setHandMovement( glm::dvec3 movement )
{
handOffset.setXYZ( movement.x, -movement.y, movement.z );
handOffset = glm::dvec3( movement.x, -movement.y, movement.z );
}
@ -603,19 +725,23 @@ void Head::setHandMovement( glm::dvec3 movement )
//-----------------------------------------
void Head::initializeAvatar()
{
//printf( "initializeAvatar\n" );
avatar.position.clear();
//avatar.position.setXYZ( -3.0, 0.0, 0.0 );
avatar.velocity.clear();
avatar.position = glm::dvec3( 0.0, 0.0, 0.0 );
avatar.velocity = glm::dvec3( 0.0, 0.0, 0.0 );
avatar.thrust = glm::dvec3( 0.0, 0.0, 0.0 );
avatar.orientation.setToIdentity();
avatar.yaw = 0.0;
avatar.pitch = 0.0;
avatar.roll = 0.0;
avatar.yawDelta = 0.0;
for (int b=0; b<NUM_AVATAR_BONES; b++)
{
avatar.bone[b].position.clear();
avatar.bone[b].velocity.clear();
avatar.bone[b].orientation.setToIdentity();
avatar.bone[b].worldPosition = glm::dvec3( 0.0, 0.0, 0.0 );
//avatar.bone[b].offsetPosition = glm::dvec3( 0.0, 0.0, 0.0 );
avatar.bone[b].velocity = glm::dvec3( 0.0, 0.0, 0.0 );
avatar.bone[b].worldOrientation.setToIdentity();
}
//----------------------------------------------------------------------------
@ -667,83 +793,77 @@ void Head::initializeAvatar()
//----------------------------------------------------------
// default pose position
// specify the default pose position
//----------------------------------------------------------
avatar.bone[ AVATAR_BONE_PELVIS_SPINE ].defaultPosePosition.setXYZ( 0.0, 0.1, 0.0 );
avatar.bone[ AVATAR_BONE_MID_SPINE ].defaultPosePosition.setXYZ( 0.0, 0.1, 0.0 );
avatar.bone[ AVATAR_BONE_CHEST_SPINE ].defaultPosePosition.setXYZ( 0.0, 0.1, 0.0 );
avatar.bone[ AVATAR_BONE_NECK ].defaultPosePosition.setXYZ( 0.0, 0.06, 0.0 );
avatar.bone[ AVATAR_BONE_HEAD ].defaultPosePosition.setXYZ( 0.0, 0.06, 0.0 );
avatar.bone[ AVATAR_BONE_LEFT_CHEST ].defaultPosePosition.setXYZ( -0.06, 0.06, 0.0 );
avatar.bone[ AVATAR_BONE_LEFT_SHOULDER ].defaultPosePosition.setXYZ( -0.03, 0.0, 0.0 );
avatar.bone[ AVATAR_BONE_LEFT_UPPER_ARM ].defaultPosePosition.setXYZ( 0.0, -0.12, 0.0 );
avatar.bone[ AVATAR_BONE_LEFT_FOREARM ].defaultPosePosition.setXYZ( 0.0, -0.1, 0.0 );
avatar.bone[ AVATAR_BONE_LEFT_HAND ].defaultPosePosition.setXYZ( 0.0, -0.05, 0.0 );
avatar.bone[ AVATAR_BONE_RIGHT_CHEST ].defaultPosePosition.setXYZ( 0.06, 0.06, 0.0 );
avatar.bone[ AVATAR_BONE_RIGHT_SHOULDER ].defaultPosePosition.setXYZ( 0.03, 0.0, 0.0 );
avatar.bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].defaultPosePosition.setXYZ( 0.0, -0.12, 0.0 );
avatar.bone[ AVATAR_BONE_RIGHT_FOREARM ].defaultPosePosition.setXYZ( 0.0, -0.1, 0.0 );
avatar.bone[ AVATAR_BONE_RIGHT_HAND ].defaultPosePosition.setXYZ( 0.0, -0.05, 0.0 );
avatar.bone[ AVATAR_BONE_LEFT_PELVIS ].defaultPosePosition.setXYZ( -0.05, 0.0, 0.0 );
avatar.bone[ AVATAR_BONE_LEFT_THIGH ].defaultPosePosition.setXYZ( 0.0, -0.15, 0.0 );
avatar.bone[ AVATAR_BONE_LEFT_SHIN ].defaultPosePosition.setXYZ( 0.0, -0.15, 0.0 );
avatar.bone[ AVATAR_BONE_LEFT_FOOT ].defaultPosePosition.setXYZ( 0.0, 0.0, 0.04 );
avatar.bone[ AVATAR_BONE_RIGHT_PELVIS ].defaultPosePosition.setXYZ( 0.05, 0.0, 0.0 );
avatar.bone[ AVATAR_BONE_RIGHT_THIGH ].defaultPosePosition.setXYZ( 0.0, -0.15, 0.0 );
avatar.bone[ AVATAR_BONE_RIGHT_SHIN ].defaultPosePosition.setXYZ( 0.0, -0.15, 0.0 );
avatar.bone[ AVATAR_BONE_RIGHT_FOOT ].defaultPosePosition.setXYZ( 0.0, 0.0, 0.04 );
avatar.bone[ AVATAR_BONE_PELVIS_SPINE ].defaultPosePosition = glm::dvec3( 0.0, 0.1, 0.0 );
avatar.bone[ AVATAR_BONE_MID_SPINE ].defaultPosePosition = glm::dvec3( 0.0, 0.1, 0.0 );
avatar.bone[ AVATAR_BONE_CHEST_SPINE ].defaultPosePosition = glm::dvec3( 0.0, 0.1, 0.0 );
avatar.bone[ AVATAR_BONE_NECK ].defaultPosePosition = glm::dvec3( 0.0, 0.06, 0.0 );
avatar.bone[ AVATAR_BONE_HEAD ].defaultPosePosition = glm::dvec3( 0.0, 0.06, 0.0 );
avatar.bone[ AVATAR_BONE_LEFT_CHEST ].defaultPosePosition = glm::dvec3( -0.06, 0.06, 0.0 );
avatar.bone[ AVATAR_BONE_LEFT_SHOULDER ].defaultPosePosition = glm::dvec3( -0.03, 0.0, 0.0 );
avatar.bone[ AVATAR_BONE_LEFT_UPPER_ARM ].defaultPosePosition = glm::dvec3( 0.0, -0.12, 0.0 );
avatar.bone[ AVATAR_BONE_LEFT_FOREARM ].defaultPosePosition = glm::dvec3( 0.0, -0.1, 0.0 );
avatar.bone[ AVATAR_BONE_LEFT_HAND ].defaultPosePosition = glm::dvec3( 0.0, -0.05, 0.0 );
avatar.bone[ AVATAR_BONE_RIGHT_CHEST ].defaultPosePosition = glm::dvec3( 0.06, 0.06, 0.0 );
avatar.bone[ AVATAR_BONE_RIGHT_SHOULDER ].defaultPosePosition = glm::dvec3( 0.03, 0.0, 0.0 );
avatar.bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].defaultPosePosition = glm::dvec3( 0.0, -0.12, 0.0 );
avatar.bone[ AVATAR_BONE_RIGHT_FOREARM ].defaultPosePosition = glm::dvec3( 0.0, -0.1, 0.0 );
avatar.bone[ AVATAR_BONE_RIGHT_HAND ].defaultPosePosition = glm::dvec3( 0.0, -0.05, 0.0 );
avatar.bone[ AVATAR_BONE_LEFT_PELVIS ].defaultPosePosition = glm::dvec3( -0.05, 0.0, 0.0 );
avatar.bone[ AVATAR_BONE_LEFT_THIGH ].defaultPosePosition = glm::dvec3( 0.0, -0.15, 0.0 );
avatar.bone[ AVATAR_BONE_LEFT_SHIN ].defaultPosePosition = glm::dvec3( 0.0, -0.15, 0.0 );
avatar.bone[ AVATAR_BONE_LEFT_FOOT ].defaultPosePosition = glm::dvec3( 0.0, 0.0, 0.04 );
avatar.bone[ AVATAR_BONE_RIGHT_PELVIS ].defaultPosePosition = glm::dvec3( 0.05, 0.0, 0.0 );
avatar.bone[ AVATAR_BONE_RIGHT_THIGH ].defaultPosePosition = glm::dvec3( 0.0, -0.15, 0.0 );
avatar.bone[ AVATAR_BONE_RIGHT_SHIN ].defaultPosePosition = glm::dvec3( 0.0, -0.15, 0.0 );
avatar.bone[ AVATAR_BONE_RIGHT_FOOT ].defaultPosePosition = glm::dvec3( 0.0, 0.0, 0.04 );
//----------------------------------------------------------------------------
// length
// calculate bone length
//----------------------------------------------------------------------------
avatar.bone[ AVATAR_BONE_PELVIS_SPINE ].length = 0.1;
avatar.bone[ AVATAR_BONE_MID_SPINE ].length = 0.1;
avatar.bone[ AVATAR_BONE_CHEST_SPINE ].length = 0.1;
avatar.bone[ AVATAR_BONE_NECK ].length = 0.1;
avatar.bone[ AVATAR_BONE_HEAD ].length = 0.1;
calculateBoneLengths();
avatar.bone[ AVATAR_BONE_LEFT_CHEST ].length = 0.1;
avatar.bone[ AVATAR_BONE_LEFT_SHOULDER ].length = 0.1;
avatar.bone[ AVATAR_BONE_LEFT_UPPER_ARM ].length = 0.1;
avatar.bone[ AVATAR_BONE_LEFT_FOREARM ].length = 0.1;
avatar.bone[ AVATAR_BONE_LEFT_HAND ].length = 0.1;
avatar.bone[ AVATAR_BONE_RIGHT_CHEST ].length = 0.1;
avatar.bone[ AVATAR_BONE_RIGHT_SHOULDER ].length = 0.1;
avatar.bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].length = 0.1;
avatar.bone[ AVATAR_BONE_RIGHT_FOREARM ].length = 0.1;
avatar.bone[ AVATAR_BONE_RIGHT_HAND ].length = 0.1;
avatar.bone[ AVATAR_BONE_LEFT_PELVIS ].length = 0.1;
avatar.bone[ AVATAR_BONE_LEFT_THIGH ].length = 0.1;
avatar.bone[ AVATAR_BONE_LEFT_SHIN ].length = 0.1;
avatar.bone[ AVATAR_BONE_LEFT_FOOT ].length = 0.1;
avatar.bone[ AVATAR_BONE_RIGHT_PELVIS ].length = 0.1;
avatar.bone[ AVATAR_BONE_RIGHT_THIGH ].length = 0.1;
avatar.bone[ AVATAR_BONE_RIGHT_SHIN ].length = 0.1;
avatar.bone[ AVATAR_BONE_RIGHT_FOOT ].length = 0.1;
//----------------------------------------------------------------------------
// generate world positions
//----------------------------------------------------------------------------
updateAvatarSkeleton();
//----------------------------------------------------------------------------
// set offset positions = world positions
//----------------------------------------------------------------------------
for (int b=0; b<NUM_AVATAR_BONES; b++)
{
//avatar.bone[b].offsetPosition = avatar.bone[b].worldPosition;
}
}
//-----------------------------------------
void Head::simulateAvatar( float deltaTime )
void Head::calculateBoneLengths()
{
updateAvatarSkeleton();
}
for (int b=0; b<NUM_AVATAR_BONES; b++)
{
avatar.bone[b].length = glm::length( avatar.bone[b].defaultPosePosition );
}
avatar.maxArmLength
= avatar.bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].length
+ avatar.bone[ AVATAR_BONE_RIGHT_FOREARM ].length
+ avatar.bone[ AVATAR_BONE_RIGHT_HAND ].length;
}
//-----------------------------------------
void Head::updateAvatarSkeleton()
{
//rotate the body...
avatar.orientation.setToIdentity();
avatar.orientation.yaw( -avatar.yaw );
//------------------------------------------------------------------------
// calculate positions of all bones by traversing the skeleton tree:
//------------------------------------------------------------------------
@ -751,81 +871,146 @@ void Head::updateAvatarSkeleton()
{
if ( avatar.bone[b].parent == AVATAR_BONE_NULL )
{
avatar.bone[b].position.set( avatar.position );
avatar.bone[b].worldOrientation.set( avatar.orientation );
avatar.bone[b].worldPosition = avatar.position;
}
else
{
avatar.bone[b].position.set( avatar.bone[ avatar.bone[b].parent ].position );
avatar.bone[b].worldOrientation.set( avatar.bone[ avatar.bone[b].parent ].worldOrientation );
avatar.bone[b].worldPosition = avatar.bone[ avatar.bone[b].parent ].worldPosition;
}
double xx = glm::dot( avatar.bone[b].defaultPosePosition.x, avatar.bone[b].worldOrientation.getRight ().x )
+ glm::dot( avatar.bone[b].defaultPosePosition.y, avatar.bone[b].worldOrientation.getRight ().y )
+ glm::dot( avatar.bone[b].defaultPosePosition.z, avatar.bone[b].worldOrientation.getRight ().z );
double yy = glm::dot( avatar.bone[b].defaultPosePosition.x, avatar.bone[b].worldOrientation.getUp ().x )
+ glm::dot( avatar.bone[b].defaultPosePosition.y, avatar.bone[b].worldOrientation.getUp ().y )
+ glm::dot( avatar.bone[b].defaultPosePosition.z, avatar.bone[b].worldOrientation.getUp ().z );
double zz = glm::dot( avatar.bone[b].defaultPosePosition.x, avatar.bone[b].worldOrientation.getFront ().x )
+ glm::dot( avatar.bone[b].defaultPosePosition.y, avatar.bone[b].worldOrientation.getFront ().y )
+ glm::dot( avatar.bone[b].defaultPosePosition.z, avatar.bone[b].worldOrientation.getFront ().z );
glm::dvec3 rotatedBoneVector( xx, yy, zz );
//rotatedBonePosition.x = avatar.bone[b].defaultPosePosition.x;// * avatar.bone[b].worldOrientation.getFront().x;
//rotatedBonePosition.y = avatar.bone[b].defaultPosePosition.y;// * avatar.bone[b].worldOrientation.getFront().y;
//rotatedBonePosition.z = avatar.bone[b].defaultPosePosition.z;// * avatar.bone[b].worldOrientation.getFront().z;
avatar.bone[b].position.add( avatar.bone[b].defaultPosePosition );
//glm::dvec3 rotatedBoneVector( avatar.bone[b].defaultPosePosition );
//glm::dmat3x3 rotationMatrix ( glm::dvec3( 1.0, 0.0, 0.0 ), glm::dvec3( 0.0, 1.0, 0.0 ), glm::dvec3( 0.0, 0.0, 1.0 ) );
//glm::dmat3x3 rotationMatrix;
//glm::dmat3x3 rotationMatrix = glm::eulerAngleYXZ( 0.0, 0.0, 0.0 );
avatar.bone[b].worldPosition += rotatedBoneVector;
}
//------------------------------------------------------------------------
// reset hand and elbow position according to hand movement
//------------------------------------------------------------------------
updateHandMovement();
/*
glm::dvec3 v( avatar.bone[ AVATAR_BONE_RIGHT_HAND ].worldPosition );
v -= avatar.bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].worldPosition;
double distance = glm::length(v);
if ( distance > avatar.maxArmLength )
{
avatar.bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].worldPosition += v * 0.2;
}
*/
/*
//------------------------------------------------------------------------
// update offset position
//------------------------------------------------------------------------
for (int b=0; b<NUM_AVATAR_BONES; b++)
{
glm::dvec3 diff( avatar.bone[b].worldPosition );
diff -= avatar.bone[b].offsetPosition;
avatar.bone[b].offsetPosition += diff * 0.1;
}
*/
}
//-------------------------------
double Head::getAvatarYaw()
{
return avatar.yaw;
}
//-------------------------------
void Head::updateHandMovement()
{
//----------------------------------------------------------------
// adjust right hand and elbow according to hand offset
//----------------------------------------------------------------
avatar.bone[ AVATAR_BONE_RIGHT_HAND ].position.add( handOffset );
glm::dvec3 armVector = glm::dvec3( avatar.bone[ AVATAR_BONE_RIGHT_HAND ].position.x, avatar.bone[ AVATAR_BONE_RIGHT_HAND ].position.y, avatar.bone[ AVATAR_BONE_RIGHT_HAND ].position.z );
armVector -= glm::dvec3( avatar.bone[ AVATAR_BONE_RIGHT_SHOULDER ].position.x, avatar.bone[ AVATAR_BONE_RIGHT_SHOULDER ].position.y, avatar.bone[ AVATAR_BONE_RIGHT_SHOULDER ].position.z );
avatar.bone[ AVATAR_BONE_RIGHT_HAND ].worldPosition += handOffset;
glm::dvec3 armVector = avatar.bone[ AVATAR_BONE_RIGHT_HAND ].worldPosition;
armVector -= avatar.bone[ AVATAR_BONE_RIGHT_SHOULDER ].worldPosition;
//-------------------------------------------------------------------------------
// test to see if right hand is being dragged beyond maximum arm length
//-------------------------------------------------------------------------------
double distance = glm::length( armVector );
double maxArmLength = 0.27;
//-------------------------------------------------------------------------------
// right hand is being dragged beyond maximum arm length...
// if right hand is being dragged beyond maximum arm length...
//-------------------------------------------------------------------------------
if ( distance > maxArmLength )
if ( distance > avatar.maxArmLength )
{
//-------------------------------------------------------------------------------
// reset right hand to be constrained to maximum arm length
//-------------------------------------------------------------------------------
avatar.bone[ AVATAR_BONE_RIGHT_HAND ].position.set( avatar.bone[ AVATAR_BONE_RIGHT_SHOULDER ].position );
avatar.bone[ AVATAR_BONE_RIGHT_HAND ].worldPosition = avatar.bone[ AVATAR_BONE_RIGHT_SHOULDER ].worldPosition;
glm::dvec3 armNormal = armVector / distance;
armVector = armNormal * maxArmLength;
distance = maxArmLength;
glm::dvec3 constrainedPosition = glm::dvec3( avatar.bone[ AVATAR_BONE_RIGHT_SHOULDER ].position.x, avatar.bone[ AVATAR_BONE_RIGHT_SHOULDER ].position.y, avatar.bone[ AVATAR_BONE_RIGHT_SHOULDER ].position.z );
armVector = armNormal * avatar.maxArmLength;
distance = avatar.maxArmLength;
glm::dvec3 constrainedPosition = avatar.bone[ AVATAR_BONE_RIGHT_SHOULDER ].worldPosition;
constrainedPosition += armVector;
avatar.bone[ AVATAR_BONE_RIGHT_HAND ].position.setXYZ( constrainedPosition.x, constrainedPosition.y, constrainedPosition.z );
avatar.bone[ AVATAR_BONE_RIGHT_HAND ].worldPosition = constrainedPosition;
}
//-----------------------------------------------------------------------------
// set elbow position
// set elbow position
//-----------------------------------------------------------------------------
glm::dvec3 newElbowPosition = glm::dvec3( avatar.bone[ AVATAR_BONE_RIGHT_SHOULDER ].position.x, avatar.bone[ AVATAR_BONE_RIGHT_SHOULDER ].position.y, avatar.bone[ AVATAR_BONE_RIGHT_SHOULDER ].position.z );
glm::dvec3 newElbowPosition = avatar.bone[ AVATAR_BONE_RIGHT_SHOULDER ].worldPosition;
newElbowPosition += armVector * ONE_HALF;
glm::dvec3 perpendicular = glm::dvec3( -armVector.y, armVector.x, armVector.z );
newElbowPosition += perpendicular * ( 1.0 - ( maxArmLength / distance ) ) * ONE_HALF;
avatar.bone[ AVATAR_BONE_RIGHT_FOREARM ].position.setXYZ( newElbowPosition.x, newElbowPosition.y, newElbowPosition.z );
newElbowPosition += perpendicular * ( 1.0 - ( avatar.maxArmLength / distance ) ) * ONE_HALF;
avatar.bone[ AVATAR_BONE_RIGHT_FOREARM ].worldPosition = newElbowPosition;
}
//-----------------------------------------
void Head::renderAvatar()
void Head::renderBody()
{
glColor3fv(skinColor);
for (int b=0; b<NUM_AVATAR_BONES; b++)
{
glPushMatrix();
glTranslatef( avatar.bone[b].position.x, avatar.bone[b].position.y, avatar.bone[b].position.z );
glTranslatef( avatar.bone[b].worldPosition.x, avatar.bone[b].worldPosition.y, avatar.bone[b].worldPosition.z );
glScalef( 0.02, 0.02, 0.02 );
glutSolidSphere( 1, 8, 4 );
glutSolidSphere( 1, 10, 5 );
glPopMatrix();
}
}
@ -835,6 +1020,9 @@ void Head::renderAvatar()
// Transmit data to agents requesting it
//called on me just prior to sending data to others (continuasly called)
//---------------------------------------------------
int Head::getBroadcastData(char* data)
{
@ -843,19 +1031,31 @@ int Head::getBroadcastData(char* data)
getRenderPitch() + Pitch, -getRenderYaw() + 180 -Yaw, Roll,
position.x + leanSideways, position.y, position.z + leanForward,
loudness, averageLoudness,
hand->getPos().x, hand->getPos().y, hand->getPos().z);
//hand->getPos().x, hand->getPos().y, hand->getPos().z); //previous to Ventrella change
avatar.bone[ AVATAR_BONE_RIGHT_HAND ].worldPosition.x,
avatar.bone[ AVATAR_BONE_RIGHT_HAND ].worldPosition.y,
avatar.bone[ AVATAR_BONE_RIGHT_HAND ].worldPosition.z ); // Ventrella change
return strlen(data);
}
//called on the other agents - assigns it to my views of the others
//---------------------------------------------------
void Head::parseData(void *data, int size) {
void Head::parseData(void *data, int size)
{
//glm::vec3 pos;//( (glm::vec3)avatar.bone[ AVATAR_BONE_RIGHT_HAND ].worldPosition );
// parse head data for this agent
glm::vec3 handPos(0,0,0);
sscanf((char *)data, "H%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f",
&Pitch, &Yaw, &Roll,
&position.x, &position.y, &position.z,
&loudness, &averageLoudness,
&handPos.x, &handPos.y, &handPos.z);
glm::vec3 handPos( 0,0,0 );
sscanf
(
(char *)data, "H%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f",
&Pitch, &Yaw, &Roll,
&position.x, &position.y, &position.z,
&loudness, &averageLoudness,
&handPos.x, &handPos.y, &handPos.z
);
if (glm::length(handPos) > 0.0) hand->setPos(handPos);
}

View file

@ -74,30 +74,26 @@ enum AvatarJoints
enum AvatarBones
{
AVATAR_BONE_NULL = -1,
AVATAR_BONE_PELVIS_SPINE, // connects pelvis joint with torso joint (cannot be rotated)
AVATAR_BONE_PELVIS_SPINE, // connects pelvis joint with torso joint (not supposed to be rotated)
AVATAR_BONE_MID_SPINE, // connects torso joint with chest joint
AVATAR_BONE_CHEST_SPINE, // connects chest joint with neckBase joint (cannot be rotated)
AVATAR_BONE_CHEST_SPINE, // connects chest joint with neckBase joint (not supposed to be rotated)
AVATAR_BONE_NECK, // connects neckBase joint with headBase joint
AVATAR_BONE_HEAD, // connects headBase joint with headTop joint
AVATAR_BONE_LEFT_CHEST, // connects chest joint with left clavicle joint (cannot be rotated)
AVATAR_BONE_LEFT_CHEST, // connects chest joint with left clavicle joint (not supposed to be rotated)
AVATAR_BONE_LEFT_SHOULDER, // connects left clavicle joint with left shoulder joint
AVATAR_BONE_LEFT_UPPER_ARM, // connects left shoulder joint with left elbow joint
AVATAR_BONE_LEFT_FOREARM, // connects left elbow joint with left wrist joint
AVATAR_BONE_LEFT_HAND, // connects left wrist joint with left fingertips joint
AVATAR_BONE_RIGHT_CHEST, // connects chest joint with right clavicle joint (cannot be rotated)
AVATAR_BONE_RIGHT_CHEST, // connects chest joint with right clavicle joint (not supposed to be rotated)
AVATAR_BONE_RIGHT_SHOULDER, // connects right clavicle joint with right shoulder joint
AVATAR_BONE_RIGHT_UPPER_ARM, // connects right shoulder joint with right elbow joint
AVATAR_BONE_RIGHT_FOREARM, // connects right elbow joint with right wrist joint
AVATAR_BONE_RIGHT_HAND, // connects right wrist joint with right fingertips joint
AVATAR_BONE_LEFT_PELVIS, // connects pelvis joint with left hip joint (cannot be rotated)
AVATAR_BONE_LEFT_PELVIS, // connects pelvis joint with left hip joint (not supposed to be rotated)
AVATAR_BONE_LEFT_THIGH, // connects left hip joint with left knee joint
AVATAR_BONE_LEFT_SHIN, // connects left knee joint with left heel joint
AVATAR_BONE_LEFT_FOOT, // connects left heel joint with left toes joint
AVATAR_BONE_RIGHT_PELVIS, // connects pelvis joint with right hip joint (cannot be rotated)
AVATAR_BONE_RIGHT_PELVIS, // connects pelvis joint with right hip joint (not supposed to be rotated)
AVATAR_BONE_RIGHT_THIGH, // connects right hip joint with right knee joint
AVATAR_BONE_RIGHT_SHIN, // connects right knee joint with right heel joint
AVATAR_BONE_RIGHT_FOOT, // connects right heel joint with right toes joint
@ -108,20 +104,26 @@ enum AvatarBones
struct AvatarBone
{
AvatarBones parent;
Vector3D position;
Vector3D defaultPosePosition;
Vector3D velocity;
glm::dvec3 worldPosition;
glm::dvec3 defaultPosePosition;
glm::dvec3 velocity;
double yaw;
double pitch;
double roll;
Orientation orientation;
Orientation worldOrientation;
double length;
};
struct Avatar
{
Vector3D position;
Vector3D velocity;
glm::dvec3 position;
glm::dvec3 velocity;
glm::dvec3 thrust;
double yaw;
double pitch;
double roll;
double yawDelta;
double maxArmLength;
Orientation orientation;
AvatarBone bone[ NUM_AVATAR_BONES ];
};
@ -154,15 +156,19 @@ class Head : public AgentData {
float getRoll() {return Roll;}
float getYaw() {return Yaw;}
float getLastMeasuredYaw() {return YawRate;}
double getAvatarYaw();
void render(int faceToFace, int isMine);
void setAvatarPosition( double, double, double );
void renderAvatar();
void renderBody();
void renderHead( int faceToFace, int isMine );
void simulate(float);
void setHandMovement( glm::dvec3 movement );
void updateHandMovement();
// Send and receive network data
int getBroadcastData(char * data);
@ -227,7 +233,7 @@ class Head : public AgentData {
glm::vec3 velocity;
glm::vec3 thrust;
Vector3D handOffset;
glm::dvec3 handOffset;
int driveKeys[MAX_DRIVE_KEYS];
@ -238,8 +244,8 @@ class Head : public AgentData {
Avatar avatar;
void initializeAvatar();
void simulateAvatar( float deltaTime );
void updateAvatarSkeleton();
void calculateBoneLengths();
void readSensors();
float renderYaw, renderPitch; // Pitch from view frustum when this is own head.

View file

@ -566,15 +566,32 @@ void display(void)
glMateriali(GL_FRONT, GL_SHININESS, 96);
//-------------------------------------------------------------------------------------
// set the caemra to third-person view
// set the camera to third-person view
//-------------------------------------------------------------------------------------
myCamera.setTargetPosition ( (glm::dvec3)myHead.getPos() );
myCamera.setYaw ( 0.0 );
myCamera.setPitch ( 0.0 );
myCamera.setRoll ( 0.0 );
myCamera.setUp ( 0.15 );
myCamera.setDistance ( 0.08 );
myCamera.update();
myCamera.setTargetPosition( (glm::dvec3)myHead.getPos() );
myCamera.setPitch ( 0.0 );
myCamera.setRoll ( 0.0 );
if ( display_head )
//-------------------------------------------------------------------------------------
// set the camera to looking at my face
//-------------------------------------------------------------------------------------
{
myCamera.setYaw ( - myHead.getAvatarYaw() );
myCamera.setUp ( 0.4 );
myCamera.setDistance( 0.08 );
myCamera.update();
}
else
//-------------------------------------------------------------------------------------
// set the camera to third-person view
//-------------------------------------------------------------------------------------
{
myCamera.setYaw ( 180.0 - myHead.getAvatarYaw() );
myCamera.setUp ( 0.15 );
myCamera.setDistance( 0.08 );
myCamera.update();
}
//-------------------------------------------------------------------------------------
// transform to camera view
@ -582,7 +599,13 @@ void display(void)
glRotatef ( myCamera.getPitch(), 1, 0, 0 );
glRotatef ( myCamera.getYaw(), 0, 1, 0 );
glRotatef ( myCamera.getRoll(), 0, 0, 1 );
//printf( "myCamera position = %f, %f, %f\n", myCamera.getPosition().x, myCamera.getPosition().y, myCamera.getPosition().z );
glTranslatef( myCamera.getPosition().x, myCamera.getPosition().y, myCamera.getPosition().z );
// fixed view
//glTranslatef( 6.18, -0.15, 1.4 );
if (::starsOn) {
// should be the first rendering pass - w/o depth buffer / lighting
@ -601,7 +624,7 @@ void display(void)
// if (!display_head) cloud.render();
// Draw voxels
//voxels.render();
voxels.render();
// Draw field vectors
if (display_field) field.render();
@ -624,11 +647,12 @@ void display(void)
if (!display_head && stats_on) render_world_box();
//---------------------------------
// Render my own head
//---------------------------------
myHead.render( true, 1 );
//myHead.renderAvatar();
/*
// Render my own head
glPushMatrix();
glLoadIdentity();
glTranslatef(0.f, 0.f, -7.f);
@ -967,7 +991,7 @@ void idle(void)
if ( mouse_pressed == 1 )
{
double xOffset = ( mouse_x - mouse_start_x ) / (double)WIDTH;
double yOffset = ( mouse_y - mouse_start_y ) / (double)WIDTH;
double yOffset = ( mouse_y - mouse_start_y ) / (double)HEIGHT;
double leftRight = xOffset;
double downUp = yOffset;
@ -1001,6 +1025,8 @@ void idle(void)
}
}
void reshape(int width, int height)
{
WIDTH = width;
@ -1018,6 +1044,8 @@ void reshape(int width, int height)
glViewport(0, 0, width, height);
}
void mouseFunc( int button, int state, int x, int y )
{
if( button == GLUT_LEFT_BUTTON && state == GLUT_DOWN )