mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
got a basic avatar skeleton with a simpler starter user interaction for moving the right hand
This commit is contained in:
parent
5b2d1ec198
commit
a0f09b597a
7 changed files with 158 additions and 79 deletions
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 ) ); }
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue