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 "Util.h"
//------------------------
Camera::Camera()
{
yaw = 0.0;
pitch = 0.0;
roll = 0.0;
position = glm::dvec3( 0.0, 0.0, 0.0 );
yaw = 0.0;
pitch = 0.0;
roll = 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();
}
//------------------------
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:
Camera();
void setYaw ( double y ) { yaw = y; }
void setPitch ( double p ) { pitch = p; }
void setRoll ( double r ) { roll = r; }
void setPosition ( glm::dvec3 p ) { position = p; };
void setOrientation ( Orientation o ) { orientation.set(o); }
void update();
void setYaw ( double y ) { yaw = y; }
void setPitch ( double p ) { pitch = p; }
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 getPitch () { return pitch; }
@ -32,9 +37,12 @@ public:
private:
glm::dvec3 position;
glm::dvec3 targetPosition;
double yaw;
double pitch;
double roll;
double up;
double distance;
Orientation orientation;
};

View file

@ -595,7 +595,7 @@ glScalef( 0.03, 0.03, 0.03 );
//---------------------------------------------------------
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()
{
//------------------------------------------------------------------------
// calculate positions of all bones by traversing the skeleton tree:
//------------------------------------------------------------------------
for (int b=0; b<NUM_AVATAR_BONES; b++)
{
if ( avatar.bone[b].parent == AVATAR_BONE_NULL )
@ -757,11 +760,61 @@ void Head::updateAvatarSkeleton()
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 );
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()
{
@ -772,7 +825,7 @@ void Head::renderAvatar()
glPushMatrix();
glTranslatef( avatar.bone[b].position.x, avatar.bone[b].position.y, avatar.bone[b].position.z );
glScalef( 0.02, 0.02, 0.02 );
glutSolidSphere( 1, 6, 3 );
glutSolidSphere( 1, 8, 4 );
glPopMatrix();
}
}

View file

@ -158,6 +158,7 @@ class Head : public AgentData {
void render(int faceToFace, int isMine);
void setAvatarPosition( double, double, double );
void renderAvatar();
void simulate(float);
@ -239,7 +240,6 @@ class Head : public AgentData {
void initializeAvatar();
void simulateAvatar( float deltaTime );
void updateAvatarSkeleton();
void renderAvatar();
void readSensors();
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()
{
assert( right.getMagnitude () < 1.0 + BIG_EPSILON );
assert( right.getMagnitude () > 1.0 - BIG_EPSILON );
assert( up.getMagnitude () < 1.0 + BIG_EPSILON );
assert( up.getMagnitude () > 1.0 - BIG_EPSILON );
assert( front.getMagnitude () < 1.0 + BIG_EPSILON );
assert( front.getMagnitude () > 1.0 - BIG_EPSILON );
assert( right.getMagnitude () < 1.0 + CENTIMETER );
assert( right.getMagnitude () > 1.0 - CENTIMETER );
assert( up.getMagnitude () < 1.0 + CENTIMETER );
assert( up.getMagnitude () > 1.0 - CENTIMETER );
assert( front.getMagnitude () < 1.0 + CENTIMETER );
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() );
}
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() );
}
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() );
}
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() );
}
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() );
}
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() );
}
if (( right.dotWith ( up ) > BIG_EPSILON )
|| ( 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 ) ); }
if (( right.dotWith ( up ) > CENTIMETER )
|| ( 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 )
|| ( 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 ) ); }
if (( right.dotWith ( front ) > CENTIMETER )
|| ( 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 )
|| ( 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 ) ); }
if (( up.dotWith ( front ) > CENTIMETER )
|| ( 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_HALF = 0.5;
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_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 BIG_EPSILON = 0.01; // not as smallish as EPSILON
static const double EPSILON = 0.00001; //smallish number - used as margin of error for some values
static const double SQUARE_ROOT_OF_2 = sqrt(2);
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 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;
double testThingy = 90.0;
int audio_on = 1; // Whether to turn on the audio support
int simulate_on = 1;
@ -196,7 +193,6 @@ char texture_filename[] = "images/int-texture256-v4.png";
unsigned int texture_width = 256;
unsigned int texture_height = 256;
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
@ -253,6 +249,9 @@ void Timer(int extra)
}
}
void display_stats(void)
{
// bitmap chars are about 10 pels high
@ -330,6 +329,9 @@ void initDisplay(void)
if (fullscreen) glutFullScreen();
}
void init(void)
{
voxels.init();
@ -366,7 +368,6 @@ void init(void)
}
#endif
gettimeofday(&timer_start, NULL);
gettimeofday(&last_frame, NULL);
}
@ -416,12 +417,6 @@ void simulateHand(float deltaTime) {
float dy = mouse_y - mouse_start_y;
glm::vec3 vel(dx*MOUSE_HAND_FORCE, -dy*MOUSE_HAND_FORCE*(WIDTH/HEIGHT), 0);
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_direction = 1;
void display(void)
{
PerfStat("display");
@ -571,30 +569,16 @@ void display(void)
glMaterialfv(GL_FRONT, GL_SPECULAR, specular_color);
glMateriali(GL_FRONT, GL_SHININESS, 96);
//-------------------------------------------------------------------------------------
// set the caemra to third-person view
//-------------------------------------------------------------------------------------
testThingy += 1.0;
//myCamera.setYaw ( myHead.getRenderYaw() );
myCamera.setYaw ( testThingy );
myCamera.setPitch ( 0.0 );
myCamera.setRoll ( 0.0 );
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 );
//-------------------------------------------------------------------------------------
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();
//-------------------------------------------------------------------------------------
// transform to camera view
@ -604,16 +588,6 @@ void display(void)
glRotatef ( myCamera.getRoll(), 0, 0, 1 );
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) {
// should be the first rendering pass - w/o depth buffer / lighting
stars.render(fov);
@ -631,7 +605,7 @@ void display(void)
// if (!display_head) cloud.render();
// Draw voxels
voxels.render();
//voxels.render();
// Draw field vectors
if (display_field) field.render();
@ -654,7 +628,8 @@ void display(void)
if (!display_head && stats_on) render_world_box();
myHead.render( true, 1 );
myHead.render( true, 1 );
//myHead.renderAvatar();
/*
// Render my own head
@ -750,6 +725,10 @@ myHead.render( true, 1 );
framecount++;
}
void testPointToVoxel()
{
float y=0;
@ -953,6 +932,23 @@ void idle(void)
if (diffclock(&last_frame, &check) > RENDER_FRAME_MSECS)
{
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
simulateHead(1.f/FPS);
simulateHand(1.f/FPS);