got a basic avatar skeleton with a simpler starter user interaction for moving the right hand

This commit is contained in:
Jeffrey Ventrella 2013-04-05 16:19:23 -07:00
parent 5b2d1ec198
commit a0f09b597a
7 changed files with 158 additions and 79 deletions

View file

@ -6,14 +6,32 @@
//----------------------------------------------------------- //-----------------------------------------------------------
#include "Camera.h" #include "Camera.h"
#include "Util.h"
//------------------------ //------------------------
Camera::Camera() Camera::Camera()
{ {
yaw = 0.0; yaw = 0.0;
pitch = 0.0; pitch = 0.0;
roll = 0.0; roll = 0.0;
position = glm::dvec3( 0.0, 0.0, 0.0 ); up = 0.0;
distance = 0.0;
targetPosition = glm::dvec3( 0.0, 0.0, 0.0 );
position = glm::dvec3( 0.0, 0.0, 0.0 );
orientation.setToIdentity(); orientation.setToIdentity();
} }
//------------------------
void Camera::update()
{
double radian = ( yaw / 180.0 ) * PIE;
double x = distance * sin( radian );
double z = distance * -cos( radian );
double y = -up;
position = glm::dvec3( targetPosition );
position += glm::dvec3( x, y, z );
}

View file

@ -17,11 +17,16 @@ class Camera
public: public:
Camera(); Camera();
void setYaw ( double y ) { yaw = y; } void update();
void setPitch ( double p ) { pitch = p; }
void setRoll ( double r ) { roll = r; } void setYaw ( double y ) { yaw = y; }
void setPosition ( glm::dvec3 p ) { position = p; }; void setPitch ( double p ) { pitch = p; }
void setOrientation ( Orientation o ) { orientation.set(o); } void setRoll ( double r ) { roll = r; }
void setUp ( double u ) { up = u; }
void setDistance ( double d ) { distance = d; }
void setTargetPosition ( glm::dvec3 t ) { targetPosition = t; };
void setPosition ( glm::dvec3 p ) { position = p; };
void setOrientation ( Orientation o ) { orientation.set(o); }
double getYaw () { return yaw; } double getYaw () { return yaw; }
double getPitch () { return pitch; } double getPitch () { return pitch; }
@ -32,9 +37,12 @@ public:
private: private:
glm::dvec3 position; glm::dvec3 position;
glm::dvec3 targetPosition;
double yaw; double yaw;
double pitch; double pitch;
double roll; double roll;
double up;
double distance;
Orientation orientation; Orientation orientation;
}; };

View file

@ -595,7 +595,7 @@ glScalef( 0.03, 0.03, 0.03 );
//--------------------------------------------------------- //---------------------------------------------------------
void Head::setHandMovement( glm::dvec3 movement ) void Head::setHandMovement( glm::dvec3 movement )
{ {
handOffset.setXYZ( movement.x, movement.y, movement.z ); handOffset.setXYZ( movement.x, -movement.y, movement.z );
} }
@ -744,6 +744,9 @@ void Head::simulateAvatar( float deltaTime )
//----------------------------------------- //-----------------------------------------
void Head::updateAvatarSkeleton() void Head::updateAvatarSkeleton()
{ {
//------------------------------------------------------------------------
// calculate positions of all bones by traversing the skeleton tree:
//------------------------------------------------------------------------
for (int b=0; b<NUM_AVATAR_BONES; b++) for (int b=0; b<NUM_AVATAR_BONES; b++)
{ {
if ( avatar.bone[b].parent == AVATAR_BONE_NULL ) if ( avatar.bone[b].parent == AVATAR_BONE_NULL )
@ -757,11 +760,61 @@ void Head::updateAvatarSkeleton()
avatar.bone[b].position.add( avatar.bone[b].defaultPosePosition ); avatar.bone[b].position.add( avatar.bone[b].defaultPosePosition );
} }
//----------------------------------------------------------------
// adjust right hand and elbow according to hand offset
//----------------------------------------------------------------
avatar.bone[ AVATAR_BONE_RIGHT_HAND ].position.add( handOffset ); 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 );
//-------------------------------------------------------------------------------
// 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 ( distance > 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 );
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 );
constrainedPosition += armVector;
avatar.bone[ AVATAR_BONE_RIGHT_HAND ].position.setXYZ( constrainedPosition.x, constrainedPosition.y, constrainedPosition.z );
}
//-----------------------------------------------------------------------------
// 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 );
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 );
} }
//----------------------------------------- //-----------------------------------------
void Head::renderAvatar() void Head::renderAvatar()
{ {
@ -772,7 +825,7 @@ void Head::renderAvatar()
glPushMatrix(); glPushMatrix();
glTranslatef( avatar.bone[b].position.x, avatar.bone[b].position.y, avatar.bone[b].position.z ); glTranslatef( avatar.bone[b].position.x, avatar.bone[b].position.y, avatar.bone[b].position.z );
glScalef( 0.02, 0.02, 0.02 ); glScalef( 0.02, 0.02, 0.02 );
glutSolidSphere( 1, 6, 3 ); glutSolidSphere( 1, 8, 4 );
glPopMatrix(); glPopMatrix();
} }
} }

View file

@ -158,6 +158,7 @@ class Head : public AgentData {
void render(int faceToFace, int isMine); void render(int faceToFace, int isMine);
void setAvatarPosition( double, double, double ); void setAvatarPosition( double, double, double );
void renderAvatar();
void simulate(float); void simulate(float);
@ -239,7 +240,6 @@ class Head : public AgentData {
void initializeAvatar(); void initializeAvatar();
void simulateAvatar( float deltaTime ); void simulateAvatar( float deltaTime );
void updateAvatarSkeleton(); void updateAvatarSkeleton();
void renderAvatar();
void readSensors(); void readSensors();
float renderYaw, renderPitch; // Pitch from view frustum when this is own head. float renderYaw, renderPitch; // Pitch from view frustum when this is own head.

View file

@ -180,50 +180,50 @@ void Orientation::setRightUpFront( const Vector3D &r, const Vector3D &u, const V
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void Orientation::verifyValidOrientation() void Orientation::verifyValidOrientation()
{ {
assert( right.getMagnitude () < 1.0 + BIG_EPSILON ); assert( right.getMagnitude () < 1.0 + CENTIMETER );
assert( right.getMagnitude () > 1.0 - BIG_EPSILON ); assert( right.getMagnitude () > 1.0 - CENTIMETER );
assert( up.getMagnitude () < 1.0 + BIG_EPSILON ); assert( up.getMagnitude () < 1.0 + CENTIMETER );
assert( up.getMagnitude () > 1.0 - BIG_EPSILON ); assert( up.getMagnitude () > 1.0 - CENTIMETER );
assert( front.getMagnitude () < 1.0 + BIG_EPSILON ); assert( front.getMagnitude () < 1.0 + CENTIMETER );
assert( front.getMagnitude () > 1.0 - BIG_EPSILON ); assert( front.getMagnitude () > 1.0 - CENTIMETER );
if ( right.getMagnitude() > 1.0 + BIG_EPSILON ) if ( right.getMagnitude() > 1.0 + CENTIMETER )
{ {
printf( "oops: the magnitude of the 'right' part of the orientation is %f!\n", right.getMagnitude() ); printf( "oops: the magnitude of the 'right' part of the orientation is %f!\n", right.getMagnitude() );
} }
else if ( right.getMagnitude() < 1.0 - BIG_EPSILON ) else if ( right.getMagnitude() < 1.0 - CENTIMETER )
{ {
printf( "oops: the magnitude of the 'right' part of the orientation is %f!\n", right.getMagnitude() ); printf( "oops: the magnitude of the 'right' part of the orientation is %f!\n", right.getMagnitude() );
} }
if ( up.getMagnitude() > 1.0 + BIG_EPSILON ) if ( up.getMagnitude() > 1.0 + CENTIMETER )
{ {
printf( "oops: the magnitude of the 'up' part of the orientation is %f!\n", up.getMagnitude() ); printf( "oops: the magnitude of the 'up' part of the orientation is %f!\n", up.getMagnitude() );
} }
else if ( up.getMagnitude() < 1.0 - BIG_EPSILON ) else if ( up.getMagnitude() < 1.0 - CENTIMETER )
{ {
printf( "oops: the magnitude of the 'up' part of the orientation is %f!\n", up.getMagnitude() ); printf( "oops: the magnitude of the 'up' part of the orientation is %f!\n", up.getMagnitude() );
} }
if ( front.getMagnitude() > 1.0 + BIG_EPSILON ) if ( front.getMagnitude() > 1.0 + CENTIMETER )
{ {
printf( "oops: the magnitude of the 'front' part of the orientation is %f!\n", front.getMagnitude() ); printf( "oops: the magnitude of the 'front' part of the orientation is %f!\n", front.getMagnitude() );
} }
else if ( front.getMagnitude() < 1.0 - BIG_EPSILON ) else if ( front.getMagnitude() < 1.0 - CENTIMETER )
{ {
printf( "oops: the magnitude of the 'front' part of the orientation is %f!\n", front.getMagnitude() ); printf( "oops: the magnitude of the 'front' part of the orientation is %f!\n", front.getMagnitude() );
} }
if (( right.dotWith ( up ) > BIG_EPSILON ) if (( right.dotWith ( up ) > CENTIMETER )
|| ( right.dotWith ( up ) < -BIG_EPSILON )) { printf( "oops: the 'right' and 'up' parts of the orientation are not perpendicular! The dot is: %f\n", right.dotWith ( up ) ); } || ( right.dotWith ( up ) < -CENTIMETER )) { printf( "oops: the 'right' and 'up' parts of the orientation are not perpendicular! The dot is: %f\n", right.dotWith ( up ) ); }
if (( right.dotWith ( front ) > BIG_EPSILON ) if (( right.dotWith ( front ) > CENTIMETER )
|| ( right.dotWith ( front ) < -BIG_EPSILON )) { printf( "oops: the 'right' and 'front' parts of the orientation are not perpendicular! The dot is: %f\n", right.dotWith ( front ) ); } || ( right.dotWith ( front ) < -CENTIMETER )) { printf( "oops: the 'right' and 'front' parts of the orientation are not perpendicular! The dot is: %f\n", right.dotWith ( front ) ); }
if (( up.dotWith ( front ) > BIG_EPSILON ) if (( up.dotWith ( front ) > CENTIMETER )
|| ( up.dotWith ( front ) < -BIG_EPSILON )) { printf( "oops: the 'up' and 'front' parts of the orientation are not perpendicular! The dot is: %f\n", up.dotWith ( front ) ); } || ( up.dotWith ( front ) < -CENTIMETER )) { printf( "oops: the 'up' and 'front' parts of the orientation are not perpendicular! The dot is: %f\n", up.dotWith ( front ) ); }
} }

View file

@ -23,13 +23,17 @@ static const double ZERO = 0.0;
static const double ONE = 1.0; static const double ONE = 1.0;
static const double ONE_HALF = 0.5; static const double ONE_HALF = 0.5;
static const double ONE_THIRD = 0.3333333; static const double ONE_THIRD = 0.3333333;
//static const double PI = 3.14159265359; static const double PIE = 3.14159265359;
static const double PI_TIMES_TWO = 3.14159265359 * 2.0; static const double PI_TIMES_TWO = 3.14159265359 * 2.0;
static const double PI_OVER_180 = 3.14159265359 / 180.0; static const double PI_OVER_180 = 3.14159265359 / 180.0;
static const double EPSILON = 0.00001; // a smallish number meant to be used as a margin of error for some normalized values static const double EPSILON = 0.00001; //smallish number - used as margin of error for some values
static const double BIG_EPSILON = 0.01; // not as smallish as EPSILON static const double SQUARE_ROOT_OF_2 = sqrt(2);
static const double SQUARE_ROOT_OF_3 = sqrt(3); static const double SQUARE_ROOT_OF_3 = sqrt(3);
static const double METER = 1.0;
static const double DECIMETER = 0.1;
static const double CENTIMETER = 0.01;
static const double MILLIIMETER = 0.001;
float azimuth_to(glm::vec3 head_pos, glm::vec3 source_pos); float azimuth_to(glm::vec3 head_pos, glm::vec3 source_pos);
float angle_to(glm::vec3 head_pos, glm::vec3 source_pos, float render_yaw, float head_yaw); float angle_to(glm::vec3 head_pos, glm::vec3 source_pos, float render_yaw, float head_yaw);

View file

@ -66,9 +66,6 @@
using namespace std; using namespace std;
double testThingy = 90.0;
int audio_on = 1; // Whether to turn on the audio support int audio_on = 1; // Whether to turn on the audio support
int simulate_on = 1; int simulate_on = 1;
@ -196,7 +193,6 @@ char texture_filename[] = "images/int-texture256-v4.png";
unsigned int texture_width = 256; unsigned int texture_width = 256;
unsigned int texture_height = 256; unsigned int texture_height = 256;
float particle_attenuation_quadratic[] = { 0.0f, 0.0f, 2.0f }; // larger Z = smaller particles float particle_attenuation_quadratic[] = { 0.0f, 0.0f, 2.0f }; // larger Z = smaller particles
float pointer_attenuation_quadratic[] = { 1.0f, 0.0f, 0.0f }; // for 2D view float pointer_attenuation_quadratic[] = { 1.0f, 0.0f, 0.0f }; // for 2D view
@ -253,6 +249,9 @@ void Timer(int extra)
} }
} }
void display_stats(void) void display_stats(void)
{ {
// bitmap chars are about 10 pels high // bitmap chars are about 10 pels high
@ -330,6 +329,9 @@ void initDisplay(void)
if (fullscreen) glutFullScreen(); if (fullscreen) glutFullScreen();
} }
void init(void) void init(void)
{ {
voxels.init(); voxels.init();
@ -366,7 +368,6 @@ void init(void)
} }
#endif #endif
gettimeofday(&timer_start, NULL); gettimeofday(&timer_start, NULL);
gettimeofday(&last_frame, NULL); gettimeofday(&last_frame, NULL);
} }
@ -416,12 +417,6 @@ void simulateHand(float deltaTime) {
float dy = mouse_y - mouse_start_y; float dy = mouse_y - mouse_start_y;
glm::vec3 vel(dx*MOUSE_HAND_FORCE, -dy*MOUSE_HAND_FORCE*(WIDTH/HEIGHT), 0); glm::vec3 vel(dx*MOUSE_HAND_FORCE, -dy*MOUSE_HAND_FORCE*(WIDTH/HEIGHT), 0);
myHead.hand->addVelocity(vel*deltaTime); myHead.hand->addVelocity(vel*deltaTime);
double leftRight = dx * 0.001;
double downUp = dy * 0.001;
double backFront = 0.0;
glm::dvec3 handMovement( leftRight, downUp, backFront );
myHead.setHandMovement( handMovement );
} }
} }
@ -544,6 +539,9 @@ void simulateHead(float frametime)
int render_test_spot = WIDTH/2; int render_test_spot = WIDTH/2;
int render_test_direction = 1; int render_test_direction = 1;
void display(void) void display(void)
{ {
PerfStat("display"); PerfStat("display");
@ -571,30 +569,16 @@ void display(void)
glMaterialfv(GL_FRONT, GL_SPECULAR, specular_color); glMaterialfv(GL_FRONT, GL_SPECULAR, specular_color);
glMateriali(GL_FRONT, GL_SHININESS, 96); glMateriali(GL_FRONT, GL_SHININESS, 96);
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// set the caemra to third-person view // set the caemra to third-person view
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
myCamera.setTargetPosition ( (glm::dvec3)myHead.getPos() );
testThingy += 1.0; myCamera.setYaw ( 0.0 );
myCamera.setPitch ( 0.0 );
//myCamera.setYaw ( myHead.getRenderYaw() ); myCamera.setRoll ( 0.0 );
myCamera.setYaw ( testThingy ); myCamera.setUp ( 0.15 );
myCamera.setPitch ( 0.0 ); myCamera.setDistance ( 0.08 );
myCamera.setRoll ( 0.0 ); myCamera.update();
double radian = ( testThingy / 180.0 ) * PI;
double x = 0.7 * sin( radian );
double z = 0.7 * cos( radian );
double y = -0.2;
glm::dvec3 offset( x, y, z );
glm::dvec3 positionWithOffset( myHead.getPos() );
positionWithOffset += offset;
myCamera.setPosition( positionWithOffset );
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
// transform to camera view // transform to camera view
@ -604,16 +588,6 @@ void display(void)
glRotatef ( myCamera.getRoll(), 0, 0, 1 ); glRotatef ( myCamera.getRoll(), 0, 0, 1 );
glTranslatef( myCamera.getPosition().x, myCamera.getPosition().y, myCamera.getPosition().z ); glTranslatef( myCamera.getPosition().x, myCamera.getPosition().y, myCamera.getPosition().z );
/*
// Rotate, translate to camera location
fov.setOrientation(
glm::rotate(glm::rotate(glm::translate(glm::mat4(1.0f), -myHead.getPos()),
-myHead.getRenderYaw(), glm::vec3(0.0f,1.0f,0.0f)),
-myHead.getRenderPitch(), glm::vec3(1.0f,0.0f,0.0f)) );
glLoadMatrixf( glm::value_ptr(fov.getWorldViewerXform()) );
*/
if (::starsOn) { if (::starsOn) {
// should be the first rendering pass - w/o depth buffer / lighting // should be the first rendering pass - w/o depth buffer / lighting
stars.render(fov); stars.render(fov);
@ -631,7 +605,7 @@ void display(void)
// if (!display_head) cloud.render(); // if (!display_head) cloud.render();
// Draw voxels // Draw voxels
voxels.render(); //voxels.render();
// Draw field vectors // Draw field vectors
if (display_field) field.render(); if (display_field) field.render();
@ -654,7 +628,8 @@ void display(void)
if (!display_head && stats_on) render_world_box(); if (!display_head && stats_on) render_world_box();
myHead.render( true, 1 ); myHead.render( true, 1 );
//myHead.renderAvatar();
/* /*
// Render my own head // Render my own head
@ -750,6 +725,10 @@ myHead.render( true, 1 );
framecount++; framecount++;
} }
void testPointToVoxel() void testPointToVoxel()
{ {
float y=0; float y=0;
@ -953,6 +932,23 @@ void idle(void)
if (diffclock(&last_frame, &check) > RENDER_FRAME_MSECS) if (diffclock(&last_frame, &check) > RENDER_FRAME_MSECS)
{ {
steps_per_frame++; steps_per_frame++;
//----------------------------------------------------------------
// If mouse is being dragged, update hand movement in the avatar
//----------------------------------------------------------------
if ( mouse_pressed == 1 )
{
double xOffset = ( mouse_x - mouse_start_x ) / (double)WIDTH;
double yOffset = ( mouse_y - mouse_start_y ) / (double)WIDTH;
double leftRight = xOffset;
double downUp = yOffset;
double backFront = 0.0;
glm::dvec3 handMovement( leftRight, downUp, backFront );
myHead.setHandMovement( handMovement );
}
// Simulation // Simulation
simulateHead(1.f/FPS); simulateHead(1.f/FPS);
simulateHand(1.f/FPS); simulateHand(1.f/FPS);