diff --git a/interface/src/Camera.cpp b/interface/src/Camera.cpp index 320acca51d..d557e2050c 100644 --- a/interface/src/Camera.cpp +++ b/interface/src/Camera.cpp @@ -62,8 +62,11 @@ void Camera::update( float deltaTime ) // generate the ortho-normals for the orientation based on the Euler angles //------------------------------------------------------------------------------ _orientation.setToIdentity(); + _orientation.yaw ( _yaw ); _orientation.pitch ( _pitch ); _orientation.roll ( _roll ); + + //printf( "orientation.front = %f, %f, %f\n", _orientation.front.x, _orientation.front.y, _orientation.front.z ); } diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 45437e449d..f1e63e691c 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -48,6 +48,26 @@ unsigned int iris_texture_height = 256; Head::Head() { initializeAvatar(); + + avatar.velocity = glm::vec3( 0.0, 0.0, 0.0 ); + avatar.thrust = glm::vec3( 0.0, 0.0, 0.0 ); + avatar.orientation.setToIdentity(); + + closestOtherAvatar = 0; + + _bodyYaw = -90.0; + _bodyPitch = 0.0; + _bodyRoll = 0.0; + + bodyYawDelta = 0.0; + + triggeringAction = false; + + mode = AVATAR_MODE_STANDING; + + initializeSkeleton(); + + for (int i = 0; i < MAX_DRIVE_KEYS; i++) driveKeys[i] = false; PupilSize = 0.10; @@ -121,6 +141,25 @@ Head::Head() { Head::Head(const Head &otherHead) { initializeAvatar(); + + avatar.velocity = otherHead.avatar.velocity; + avatar.thrust = otherHead.avatar.thrust; + avatar.orientation.set( otherHead.avatar.orientation ); + + closestOtherAvatar = otherHead.closestOtherAvatar; + + _bodyYaw = otherHead._bodyYaw; + _bodyPitch = otherHead._bodyPitch; + _bodyRoll = otherHead._bodyRoll; + + bodyYawDelta = otherHead.bodyYawDelta; + + triggeringAction = otherHead.triggeringAction; + + mode = otherHead.mode; + + initializeSkeleton(); + for (int i = 0; i < MAX_DRIVE_KEYS; i++) driveKeys[i] = otherHead.driveKeys[i]; @@ -298,14 +337,14 @@ void Head::simulate(float deltaTime) { //------------------------ // update avatar skeleton //------------------------ - updateAvatarSkeleton(); + updateSkeleton(); //------------------------------------------------------------------------ // reset hand and elbow position according to hand movement //------------------------------------------------------------------------ if ( handBeingMoved ){ if (! previousHandBeingMoved ){ - initializeAvatarSprings(); + initializeBodySprings(); usingSprings = true; //printf( "just started moving hand\n" ); } @@ -319,7 +358,7 @@ void Head::simulate(float deltaTime) { if ( handBeingMoved ) { updateHandMovement(); - updateAvatarSprings( deltaTime ); + updateBodySprings( deltaTime ); } previousHandBeingMoved = handBeingMoved; @@ -506,6 +545,8 @@ void Head::simulate(float deltaTime) { void Head::render(int faceToFace, int isMine) { + +/* //--------------------------------------------------- // show avatar position //--------------------------------------------------- @@ -514,7 +555,8 @@ void Head::render(int faceToFace, int isMine) { glScalef( 0.03, 0.03, 0.03 ); glutSolidSphere( 1, 10, 10 ); glPopMatrix(); - +*/ + //--------------------------------------------------- // show avatar orientation //--------------------------------------------------- @@ -558,7 +600,9 @@ void Head::render(int faceToFace, int isMine) { } - + +//this has been moved to Utils.cpp +/* void Head::renderOrientationDirections( glm::vec3 position, Orientation orientation, float size ) { glm::vec3 pRight = position + orientation.right * size; glm::vec3 pUp = position + orientation.up * size; @@ -566,22 +610,23 @@ void Head::renderOrientationDirections( glm::vec3 position, Orientation orientat glColor3f( 1.0f, 0.0f, 0.0f ); glBegin( GL_LINE_STRIP ); - glVertex3f( bone[ AVATAR_BONE_HEAD ].position.x, bone[ AVATAR_BONE_HEAD ].position.y, bone[ AVATAR_BONE_HEAD ].position.z ); + glVertex3f( position.x, position.y, position.z ); glVertex3f( pRight.x, pRight.y, pRight.z ); glEnd(); glColor3f( 0.0f, 1.0f, 0.0f ); glBegin( GL_LINE_STRIP ); - glVertex3f( bone[ AVATAR_BONE_HEAD ].position.x, bone[ AVATAR_BONE_HEAD ].position.y, bone[ AVATAR_BONE_HEAD ].position.z ); + glVertex3f( position.x, position.y, position.z ); glVertex3f( pUp.x, pUp.y, pUp.z ); glEnd(); glColor3f( 0.0f, 0.0f, 1.0f ); glBegin( GL_LINE_STRIP ); - glVertex3f( bone[ AVATAR_BONE_HEAD ].position.x, bone[ AVATAR_BONE_HEAD ].position.y, bone[ AVATAR_BONE_HEAD ].position.z ); + glVertex3f( position.x, position.y, position.z ); glVertex3f( pFront.x, pFront.y, pFront.z ); glEnd(); } +*/ @@ -766,6 +811,7 @@ AvatarMode Head::getMode() { void Head::initializeAvatar() { +/* avatar.velocity = glm::vec3( 0.0, 0.0, 0.0 ); avatar.thrust = glm::vec3( 0.0, 0.0, 0.0 ); avatar.orientation.setToIdentity(); @@ -781,7 +827,16 @@ void Head::initializeAvatar() { triggeringAction = false; mode = AVATAR_MODE_STANDING; - + + initializeSkeleton(); + */ +} + + + + +void Head::initializeSkeleton() { + for (int b=0; b #include -#include // added by Ventrella as a utility +#include #include "Field.h" #include "world.h" @@ -141,7 +141,7 @@ class Head : public AvatarData { void renderBody(); void renderHead( int faceToFace, int isMine ); - void renderOrientationDirections( glm::vec3 position, Orientation orientation, float size ); + //void renderOrientationDirections( glm::vec3 position, Orientation orientation, float size ); void simulate(float); @@ -212,6 +212,8 @@ class Head : public AvatarData { float closeEnoughToInteract; int closestOtherAvatar; + + //temporary - placeholder for real other avs glm::vec3 DEBUG_otherAvatarListPosition [ NUM_OTHER_AVATARS ]; float DEBUG_otherAvatarListTimer [ NUM_OTHER_AVATARS ]; @@ -235,14 +237,7 @@ class Head : public AvatarData { AvatarBone bone[ NUM_AVATAR_BONES ]; AvatarMode mode; - - void initializeAvatar(); - void updateAvatarSkeleton(); - void initializeAvatarSprings(); - void updateAvatarSprings( float deltaTime ); - void calculateBoneLengths(); - - void readSensors(); + float renderYaw, renderPitch; // Pitch from view frustum when this is own head. // @@ -252,6 +247,18 @@ class Head : public AvatarData { float transmitterHz; int transmitterPackets; + + //------------------------------------------- + // private methods... + //------------------------------------------- + void initializeAvatar(); + void initializeSkeleton(); + void updateSkeleton(); + void initializeBodySprings(); + void updateBodySprings( float deltaTime ); + void calculateBoneLengths(); + + void readSensors(); }; #endif diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index f9dc085793..5c41318ec0 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -16,6 +16,7 @@ #include "world.h" #include "Util.h" + // Return the azimuth angle in degrees between two points. float azimuth_to(glm::vec3 head_pos, glm::vec3 source_pos) { return atan2(head_pos.x - source_pos.x, head_pos.z - source_pos.z) * 180.0f / PIf; @@ -202,3 +203,111 @@ void drawGroundPlaneGrid( float size, int resolution ) } +void renderOrientationDirections( glm::vec3 position, Orientation orientation, float size ) { + glm::vec3 pRight = position + orientation.right * size; + glm::vec3 pUp = position + orientation.up * size; + glm::vec3 pFront = position + orientation.front * size; + + glColor3f( 1.0f, 0.0f, 0.0f ); + glBegin( GL_LINE_STRIP ); + glVertex3f( position.x, position.y, position.z ); + glVertex3f( pRight.x, pRight.y, pRight.z ); + glEnd(); + + glColor3f( 0.0f, 1.0f, 0.0f ); + glBegin( GL_LINE_STRIP ); + glVertex3f( position.x, position.y, position.z ); + glVertex3f( pUp.x, pUp.y, pUp.z ); + glEnd(); + + glColor3f( 0.0f, 0.0f, 1.0f ); + glBegin( GL_LINE_STRIP ); + glVertex3f( position.x, position.y, position.z ); + glVertex3f( pFront.x, pFront.y, pFront.z ); + glEnd(); +} + +void testOrientationClass() { + printf("\n----------\ntestOrientationClass()\n----------\n\n"); + + oTestCase tests[] = { + // - inputs ------------, outputs -------------------- ------------------- ---------------------------- + // -- front -------------------, -- up -------------, -- right ------------------- + // ( yaw , pitch, roll , front.x , front.y , front.z , up.x , up.y , up.z , right.x , right.y , right.z ) + + // simple yaw tests + oTestCase( 0.f , 0.f , 0.f , 0.f , 0.f , 1.0f , 0.f , 1.0f , 0.f , -1.0f , 0.f , 0.f ), + oTestCase( 90.0f, 0.f , 0.f , 1.0f , 0.f , 0.f , 0.f , 1.0f , 0.f , 0.0f , 0.f , 1.0f ), + oTestCase(180.0f, 0.f , 0.f , 0.f , 0.f , -1.0f , 0.f , 1.0f , 0.f , 1.0f , 0.f , 0.f ), + oTestCase(270.0f, 0.f , 0.f , -1.0f , 0.f , 0.f , 0.f , 1.0f , 0.f , 0.0f , 0.f , -1.0f ), + + // simple pitch tests + oTestCase( 0.f ,90.f , 0.f , 0.f , 1.0f , 0.0f , 0.f , 0.0f , -1.0f, -1.0f , 0.f , 0.f ), + + }; + + int failedCount = 0; + int totalTests = sizeof(tests)/sizeof(oTestCase); + + for (int i=0; i < totalTests; i++) { + + bool passed = true; // I'm an optimist! + + float yaw = tests[i].yaw; + float pitch = tests[i].pitch; + float roll = tests[i].roll; + + Orientation o1; + o1.setToIdentity(); + o1.yaw(yaw); + o1.pitch(pitch); + o1.roll(roll); + + glm::vec3 front = o1.getFront(); + glm::vec3 up = o1.getUp(); + glm::vec3 right = o1.getRight(); + + printf("\n-----\nTest: %d - yaw=%f , pitch=%f , roll=%f \n\n",i+1,yaw,pitch,roll); + + printf(" +front.x=%f, front.y=%f, front.z=%f\n",front.x,front.y,front.z); + if (front.x == tests[i].frontX && front.y == tests[i].frontY && front.z == tests[i].frontZ) { + printf(" front vector PASSES!\n"); + } else { + printf(" front vector FAILED! expected: \n"); + printf(" front.x=%f, front.y=%f, front.z=%f\n",tests[i].frontX,tests[i].frontY,tests[i].frontZ); + passed = false; + } + + printf(" +up.x=%f, up.y=%f, up.z=%f\n",up.x,up.y,up.z); + if (up.x == tests[i].upX && up.y == tests[i].upY && up.z == tests[i].upZ) { + printf(" up vector PASSES!\n"); + } else { + printf(" up vector FAILED! expected: \n"); + printf(" up.x=%f, up.y=%f, up.z=%f\n",tests[i].upX,tests[i].upY,tests[i].upZ); + passed = false; + } + + + printf(" +right.x=%f, right.y=%f, right.z=%f\n",right.x,right.y,right.z); + if (right.x == tests[i].rightX && right.y == tests[i].rightY && right.z == tests[i].rightZ) { + printf(" right vector PASSES!\n"); + } else { + printf(" right vector FAILED! expected: \n"); + printf(" right.x=%f, right.y=%f, right.z=%f\n",tests[i].rightX,tests[i].rightY,tests[i].rightZ); + passed = false; + } + + if (!passed) { + printf("\n-----\nTest: %d - FAILED! \n----------\n\n",i+1); + failedCount++; + } + } + printf("\n-----\nTotal Failed: %d out of %d \n----------\n\n",failedCount,totalTests); + printf("\n----------DONE----------\n\n"); +} + + + + + + diff --git a/interface/src/Util.h b/interface/src/Util.h index 13b2810092..f2adc918be 100644 --- a/interface/src/Util.h +++ b/interface/src/Util.h @@ -17,6 +17,9 @@ #include +#include + + 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); @@ -30,7 +33,43 @@ void drawvec3(int x, int y, float scale, float rotate, float thick, int mono, gl float r=1.0, float g=1.0, float b=1.0); double diffclock(timeval *clock1,timeval *clock2); - void drawGroundPlaneGrid( float size, int resolution ); +void renderOrientationDirections( glm::vec3 position, Orientation orientation, float size ); + + +class oTestCase { +public: + float yaw; + float pitch; + float roll; + + float frontX; + float frontY; + float frontZ; + + float upX; + float upY; + float upZ; + + float rightX; + float rightY; + float rightZ; + + oTestCase( + float yaw, float pitch, float roll, + float frontX, float frontY, float frontZ, + float upX, float upY, float upZ, + float rightX, float rightY, float rightZ + ) : + yaw(yaw),pitch(pitch),roll(roll), + frontX(frontX),frontY(frontY),frontZ(frontZ), + upX(upX),upY(upY),upZ(upZ), + rightX(rightX),rightY(rightY),rightZ(rightZ) + {}; +}; + + +void testOrientationClass(); + #endif diff --git a/interface/src/main.cpp b/interface/src/main.cpp index b382184281..cbe421ea70 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -722,7 +722,7 @@ void display(void) //---------------------------------------------------- myCamera.setTargetPosition ( myAvatar.getBodyPosition() ); myCamera.setYaw ( 180.0 - myAvatar.getBodyYaw() ); - myCamera.setPitch ( 0.0 ); // temporarily, this must be 0.0 or else bad juju + myCamera.setPitch ( 10.0 ); // temporarily, this must be 0.0 or else bad juju myCamera.setRoll ( 0.0 ); myCamera.setUp ( 0.45); myCamera.setDistance ( 1.0 ); @@ -764,6 +764,13 @@ void display(void) + + //quick test for camera ortho-normal sanity check... + + + + + if (::starsOn) { // should be the first rendering pass - w/o depth buffer / lighting stars.render(fov); @@ -1499,6 +1506,9 @@ void audioMixerUpdate(in_addr_t newMixerAddress, in_port_t newMixerPort) { int main(int argc, const char * argv[]) { + // Quick test of the Orientation class on startup! + testOrientationClass(); + AgentList::createInstance(AGENT_TYPE_INTERFACE); gettimeofday(&applicationStartupTime, NULL); @@ -1593,4 +1603,3 @@ int main(int argc, const char * argv[]) ::terminate(); return EXIT_SUCCESS; } - diff --git a/libraries/avatars/src/Orientation.cpp b/libraries/avatars/src/Orientation.cpp index ed4af46d25..cd19b2aac0 100755 --- a/libraries/avatars/src/Orientation.cpp +++ b/libraries/avatars/src/Orientation.cpp @@ -9,7 +9,7 @@ #include -static bool testingForNormalizationAndOrthogonality = false; +static bool testingForNormalizationAndOrthogonality = true; Orientation::Orientation() { right = glm::vec3( 1.0, 0.0, 0.0 ); @@ -94,9 +94,9 @@ void Orientation::setRightUpFront( const glm::vec3 &r, const glm::vec3 &u, const //---------------------------------------------------------------------- void Orientation::testForOrthogonalAndNormalizedVectors( float epsilon ) { - //---------------------------------------------------------------- - // make sure vectors are normalized (or close to length 1) - //---------------------------------------------------------------- + //------------------------------------------------------------------ + // make sure vectors are normalized (or close enough to length 1.0) + //------------------------------------------------------------------ float rightLength = glm::length( right ); float upLength = glm::length( up ); float frontLength = glm::length( front );