From a0f09b597ad832dd6a9ab63bb648a6e8186cedb0 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 5 Apr 2013 16:19:23 -0700 Subject: [PATCH] got a basic avatar skeleton with a simpler starter user interaction for moving the right hand --- interface/src/Camera.cpp | 26 +++++++++-- interface/src/Camera.h | 18 ++++++-- interface/src/Head.cpp | 59 ++++++++++++++++++++++-- interface/src/Head.h | 2 +- interface/src/Orientation.cpp | 36 +++++++-------- interface/src/Util.h | 10 ++-- interface/src/main.cpp | 86 +++++++++++++++++------------------ 7 files changed, 158 insertions(+), 79 deletions(-) diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index b0c5a2c0dd..e7bf3d751b 100755 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -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 ); +} + diff --git a/interface/src/Camera.h b/interface/src/Camera.h index b0bf9373cd..eed70c1c92 100755 --- a/interface/src/Camera.h +++ b/interface/src/Camera.h @@ -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; }; diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 18b5d60690..91cb91bcec 100755 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -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 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(); } } diff --git a/interface/src/Head.h b/interface/src/Head.h index 618bdcc16b..b5ae162c80 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -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. diff --git a/interface/src/Orientation.cpp b/interface/src/Orientation.cpp index 16176e736d..63ea77f4dd 100755 --- a/interface/src/Orientation.cpp +++ b/interface/src/Orientation.cpp @@ -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 ) ); } } diff --git a/interface/src/Util.h b/interface/src/Util.h index 8537f9c769..c5a02df5aa 100644 --- a/interface/src/Util.h +++ b/interface/src/Util.h @@ -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); diff --git a/interface/src/main.cpp b/interface/src/main.cpp index bacd25e3d8..4ae10b94d3 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -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);