From d00001613f6716ef429bfdce3ac4315dc8c59bad Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Mon, 15 Apr 2013 21:06:45 -0700 Subject: [PATCH 01/29] Renamed functions in head, added ability to change body yaw. --- interface/src/Head.cpp | 8 +------- interface/src/Head.h | 6 ++++-- interface/src/main.cpp | 9 ++------- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index ef1e9ffeb6..3b048fd7e9 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -188,7 +188,7 @@ void Head::reset() { //this pertains to moving the head with the glasses //--------------------------------------------------- -void Head::UpdatePos(float frametime, SerialInterface * serialInterface, int head_mirror, glm::vec3 * gravity) +void Head::UpdateGyros(float frametime, SerialInterface * serialInterface, int head_mirror, glm::vec3 * gravity) // Using serial data, update avatar/render position and angles { const float PITCH_ACCEL_COUPLING = 0.5; @@ -445,8 +445,6 @@ void Head::simulate(float deltaTime) { } } - - const float DEGREES_BETWEEN_VIEWER_EYES = 3; const float DEGREES_TO_VIEWER_MOUTH = 7; @@ -980,10 +978,6 @@ void Head::updateAvatarSprings( float deltaTime ) { } } -float Head::getBodyYaw() { - return bodyYaw; -} - glm::vec3 Head::getHeadLookatDirection() { return glm::vec3 ( diff --git a/interface/src/Head.h b/interface/src/Head.h index f8af6521d1..938d92884c 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -142,7 +142,7 @@ class Head : public AgentData { Head* clone() const; void reset(); - void UpdatePos(float frametime, SerialInterface * serialInterface, int head_mirror, glm::vec3 * gravity); + void UpdateGyros(float frametime, SerialInterface * serialInterface, int head_mirror, glm::vec3 * gravity); void setNoise (float mag) { noise = mag; } void setPitch(float p) {Pitch = p; } void setYaw(float y) {Yaw = y; } @@ -163,7 +163,9 @@ class Head : public AgentData { float getYaw() {return Yaw;} float getLastMeasuredYaw() {return YawRate;} - float getBodyYaw(); + float getBodyYaw() {return bodyYaw;}; + void addBodyYaw(float y) {bodyYaw += y;}; + glm::vec3 getHeadLookatDirection(); glm::vec3 getHeadLookatDirectionUp(); glm::vec3 getHeadLookatDirectionRight(); diff --git a/interface/src/main.cpp b/interface/src/main.cpp index e3e440c80c..932d96199e 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -227,12 +227,7 @@ void displayStats(void) char stats[200]; sprintf(stats, "FPS = %3.0f Pkts/s = %d Bytes/s = %d Head(x,y,z)= %4.2f, %4.2f, %4.2f ", FPS, packetsPerSecond, bytesPerSecond, avatarPos.x,avatarPos.y,avatarPos.z); - drawtext(10, statsVerticalOffset + 49, 0.10f, 0, 1.0, 0, stats); - if (serialPort.active) { - sprintf(stats, "ADC samples = %d, LED = %d", - serialPort.getNumSamples(), serialPort.getLED()); - drawtext(300, statsVerticalOffset + 30, 0.10f, 0, 1.0, 0, stats); - } + drawtext(10, statsVerticalOffset + 49, 0.10f, 0, 1.0, 0, stats); std::stringstream voxelStats; voxelStats << "Voxels Rendered: " << voxels.getVoxelsRendered(); @@ -383,7 +378,7 @@ void updateAvatar(float frametime) float gyroPitchRate = serialPort.getRelativeValue(PITCH_RATE); float gyroYawRate = serialPort.getRelativeValue(YAW_RATE); - myAvatar.UpdatePos(frametime, &serialPort, headMirror, &gravity); + myAvatar.UpdateGyros(frametime, &serialPort, headMirror, &gravity); // // Update gyro-based mouse (X,Y on screen) From 39bb556cd3a5d08182c76896dc85fc704e3f775f Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 16 Apr 2013 20:29:10 -0700 Subject: [PATCH 02/29] Fix to add local variable underscores to head get/add body yaw functions. --- interface/src/Head.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Head.h b/interface/src/Head.h index 3978f369ab..fae9d18fff 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -124,8 +124,8 @@ class Head : public AvatarData { float getYaw() {return Yaw;} float getLastMeasuredYaw() {return YawRate;} - float getBodyYaw() {return bodyYaw;}; - void addBodyYaw(float y) {bodyYaw += y;}; + float getBodyYaw() {return _bodyYaw;}; + void addBodyYaw(float y) {_bodyYaw += y;}; glm::vec3 getHeadLookatDirection(); glm::vec3 getHeadLookatDirectionUp(); From 77832dbcb4862aef45381eb99250309bfc061e2a Mon Sep 17 00:00:00 2001 From: tosh Date: Wed, 17 Apr 2013 20:53:24 +0200 Subject: [PATCH 03/29] makes FieldOfView store the view matrix instead of its inverse --- interface/src/FieldOfView.cpp | 21 ++++++++++++++----- interface/src/FieldOfView.h | 39 ++++++++++++++++++++++++++--------- 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/interface/src/FieldOfView.cpp b/interface/src/FieldOfView.cpp index c255d7232f..0aef91b0ab 100644 --- a/interface/src/FieldOfView.cpp +++ b/interface/src/FieldOfView.cpp @@ -1,6 +1,6 @@ // // FieldOfView.cpp -// interface +// hifi // // Created by Tobias Schwinger on 3/21/13. // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. @@ -16,7 +16,7 @@ using namespace glm; FieldOfView::FieldOfView() : - _matOrientation(mat4(1.0f)), + _matView(mat4(1.0f)), _vecBoundsLow(vec3(-1.0f,-1.0f,-1.0f)), _vecBoundsHigh(vec3(1.0f,1.0f,1.0f)), _valWidth(256.0f), @@ -26,6 +26,17 @@ FieldOfView::FieldOfView() : _enmAspectBalancing(expose_less) { } +FieldOfView& FieldOfView::setOrientation(mat4 const& matrix) { + + _matView = affineInverse(matrix); + return *this; +} + +mat4 FieldOfView::getOrientation() const { + + return affineInverse(_matView); +} + mat4 FieldOfView::getViewerScreenXform() const { mat4 projection; @@ -48,14 +59,14 @@ mat4 FieldOfView::getViewerScreenXform() const { mat4 FieldOfView::getWorldViewerXform() const { - return translate(affineInverse(_matOrientation), + return translate(_matView, vec3(0.0f, 0.0f, -_vecBoundsHigh.z) ); } mat4 FieldOfView::getWorldScreenXform() const { return translate( - getViewerScreenXform() * affineInverse(_matOrientation), + getViewerScreenXform() * _matView, vec3(0.0f, 0.0f, -_vecBoundsHigh.z) ); } @@ -65,7 +76,7 @@ mat4 FieldOfView::getViewerWorldXform() const { return translate( translate(mat4(1.0f), n_translate) - * _matOrientation, -n_translate ); + * affineInverse(_matView), -n_translate ); } float FieldOfView::getPixelSize() const { diff --git a/interface/src/FieldOfView.h b/interface/src/FieldOfView.h index f4caf582c2..82d5c79b6b 100644 --- a/interface/src/FieldOfView.h +++ b/interface/src/FieldOfView.h @@ -1,22 +1,30 @@ // // FieldOfView.h -// interface +// hifi // // Created by Tobias Schwinger on 3/21/13. // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // -#ifndef __interface__FieldOfView__ -#define __interface__FieldOfView__ +#ifndef __hifi__FieldOfView__ +#define __hifi__FieldOfView__ #include // // Viewing parameter encapsulation. -// +// +// Once configured provides transformation matrices between different coordinate spaces, such as +// +// o world space, +// o viewer space (orientation of local viewer, no projective transforms), and +// o screen space (as Viewer space + projection). +// +// Also provides information about the mapping of the screen space coordinates onto the screen. +// class FieldOfView { - glm::mat4 _matOrientation; + glm::mat4 _matView; glm::vec3 _vecBoundsLow; glm::vec3 _vecBoundsHigh; float _valWidth; @@ -33,7 +41,9 @@ class FieldOfView { FieldOfView& setBounds(glm::vec3 const& low, glm::vec3 const& high) { _vecBoundsLow = low; _vecBoundsHigh = high; return *this; } - FieldOfView& setOrientation(glm::mat4 const& matrix) { _matOrientation = matrix; return *this; } + FieldOfView& setView(glm::mat4 const& matrix) { _matView = matrix; return *this; } + + FieldOfView& setOrientation(glm::mat4 const& matrix); FieldOfView& setPerspective(float angle) { _valAngle = angle; return *this; } @@ -52,13 +62,20 @@ class FieldOfView { // dumb accessors - glm::mat4 const& getOrientation() const { return _matOrientation; } + glm::mat4 const& getView() const { return _matView; } float getWidthInPixels() const { return _valWidth; } float getHeightInPixels() const { return _valHeight; } float getPerspective() const { return _valAngle; } // matrices + // + // Returns a matrix representing the camera position and rotation in + // space. Similar to getViewerWorldXform but without translation offset + // applied. + // + glm::mat4 getOrientation() const; + // // Returns a full transformation matrix to project world coordinates // onto the screen. @@ -100,7 +117,8 @@ class FieldOfView { float getPixelSize() const; // - // Returns the frustum as used for the projection matrices. + // Returns the frustum as used for the projection matrices. That + // is the one that applies when the current orientation is at identity. // The result depdends on the bounds, eventually aspect correction // for the current resolution, the perspective angle (specified in // respect to diagonal) and zoom. @@ -109,7 +127,8 @@ class FieldOfView { // // Returns the z-offset from the origin to where orientation ia - // applied. + // applied (in negated form equivalent to the 'near' parameter of + // gluPerspective). // float getTransformOffset() const { return _vecBoundsHigh.z; } @@ -119,5 +138,5 @@ class FieldOfView { float getAspectRatio() const { return _valHeight / _valWidth; } }; -#endif +#endif /* defined(__hifi__FieldOfView__) */ From e9592c45c744b1da105adaa81cfa09d57c74b966 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 17 Apr 2013 11:56:32 -0700 Subject: [PATCH 04/29] fix reference to resources directory on OS X --- interface/src/Audio.cpp | 4 ++-- interface/src/Head.cpp | 2 +- libraries/shared/src/SharedUtil.cpp | 3 ++- libraries/shared/src/SharedUtil.h | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 578e1368c8..997361a378 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -444,8 +444,8 @@ Audio::Audio(Oscilloscope *s, Head *linkedHead) // read the walking sound from the raw file and store it // in the in memory array - switchToResourcesIfRequired(); - FILE *soundFile = fopen("audio/walking.raw", "r"); + switchToResourcesParentIfRequired(); + FILE *soundFile = fopen("resources/audio/walking.raw", "r"); // get length of file: std::fseek(soundFile, 0, SEEK_END); diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 658e749eed..7a310b8171 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -114,7 +114,7 @@ Head::Head() { springVelocityDecay = 16.0f; if (iris_texture.size() == 0) { - switchToResourcesIfRequired(); + switchToResourcesParentIfRequired(); unsigned error = lodepng::decode(iris_texture, iris_texture_width, iris_texture_height, iris_texture_file); if (error != 0) { std::cout << "error " << error << ": " << lodepng_error_text(error) << std::endl; diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index 8fb8645730..97c9b047be 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -74,7 +74,7 @@ bool oneAtBit(unsigned char byte, int bitIndex) { return (byte >> (7 - bitIndex) & 1); } -void switchToResourcesIfRequired() { +void switchToResourcesParentIfRequired() { #ifdef __APPLE__ CFBundleRef mainBundle = CFBundleGetMainBundle(); CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle); @@ -85,6 +85,7 @@ void switchToResourcesIfRequired() { CFRelease(resourcesURL); chdir(path); + chdir(".."); #endif } diff --git a/libraries/shared/src/SharedUtil.h b/libraries/shared/src/SharedUtil.h index f7e639ba43..e70229637a 100644 --- a/libraries/shared/src/SharedUtil.h +++ b/libraries/shared/src/SharedUtil.h @@ -47,7 +47,7 @@ void printVoxelCode(unsigned char* voxelCode); int numberOfOnes(unsigned char byte); bool oneAtBit(unsigned char byte, int bitIndex); -void switchToResourcesIfRequired(); +void switchToResourcesParentIfRequired(); const char* getCmdOption(int argc, const char * argv[],const char* option); bool cmdOptionExists(int argc, const char * argv[],const char* option); From 4f0ca2f33eff3cc167a0d873fc59ca76c62b43ed Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 17 Apr 2013 12:31:03 -0700 Subject: [PATCH 05/29] added quaternions to avatar body and bone structure (but not using them yet) --- interface/src/Head.cpp | 76 ++++++++++++--------------- interface/src/Head.h | 10 +++- libraries/avatars/src/Orientation.cpp | 3 +- 3 files changed, 43 insertions(+), 46 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 4f77e6fafe..18fa5c9181 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -48,26 +48,20 @@ unsigned int iris_texture_height = 256; Head::Head() { initializeAvatar(); - + avatar.orientation.setToIdentity(); 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; + rotation = glm::quat( 0.0f, 0.0f, 0.0f, 0.0f ); + 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; @@ -102,17 +96,15 @@ Head::Head() { browAudioLift = 0.0; noise = 0; - handBeingMoved = false; - previousHandBeingMoved = false; - movedHandOffset = glm::vec3( 0.0, 0.0, 0.0 ); + handBeingMoved = false; + previousHandBeingMoved = false; + movedHandOffset = glm::vec3( 0.0, 0.0, 0.0 ); + usingSprings = false; + springForce = 6.0f; + springVelocityDecay = 16.0f; sphere = NULL; - usingSprings = false; - - springForce = 6.0f; - springVelocityDecay = 16.0f; - if (iris_texture.size() == 0) { switchToResourcesIfRequired(); unsigned error = lodepng::decode(iris_texture, iris_texture_width, iris_texture_height, iris_texture_file); @@ -137,30 +129,23 @@ Head::Head() { } - - Head::Head(const Head &otherHead) { initializeAvatar(); + avatar.orientation.set( otherHead.avatar.orientation ); 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; + rotation = otherHead.rotation; + 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]; PupilSize = otherHead.PupilSize; @@ -833,14 +818,19 @@ void Head::initializeAvatar() { } - - void Head::initializeSkeleton() { for (int b=0; b + +#include and + + enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH}; #define FWD 0 @@ -80,6 +85,7 @@ struct AvatarBone glm::vec3 springyPosition; // used for special effects (a 'flexible' variant of position) glm::dvec3 springyVelocity; // used for special effects ( the velocity of the springy position) float springBodyTightness; // how tightly the springy position tries to stay on the position + glm::quat rotation; // this will eventually replace yaw, pitch and roll (and maybe orienttion) float yaw; // the yaw Euler angle of the bone rotation off the parent float pitch; // the pitch Euler angle of the bone rotation off the parent float roll; // the roll Euler angle of the bone rotation off the parent @@ -231,7 +237,9 @@ class Head : public AvatarData { GLUquadric *sphere; Avatar avatar; - + + glm::quat rotation; // the rotation of the avatar body as a whole + AvatarBone bone[ NUM_AVATAR_BONES ]; AvatarMode mode; diff --git a/libraries/avatars/src/Orientation.cpp b/libraries/avatars/src/Orientation.cpp index 8eeb3dd0ff..f11f820c89 100755 --- a/libraries/avatars/src/Orientation.cpp +++ b/libraries/avatars/src/Orientation.cpp @@ -22,7 +22,6 @@ void Orientation::setToIdentity() { front = glm::vec3( 0.0, 0.0, 1.0 ); } - void Orientation::set( Orientation o ) { right = o.right; up = o.up; @@ -125,7 +124,7 @@ void Orientation::testForOrthogonalAndNormalizedVectors( float epsilon ) { //---------------------------------------------------------------- - // make sure vectors are orthoginal (or close enough) + // make sure vectors are orthogonal (or close enough) //---------------------------------------------------------------- glm::vec3 rightCross = glm::cross( up, front ); glm::vec3 upCross = glm::cross( front, right ); From 3856a70b7e2eb76f8949e372a23965afa0958949 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 17 Apr 2013 12:48:47 -0700 Subject: [PATCH 06/29] added "_" to several members in Head class, and cleaned up some code formatting (housecleaning :) --- interface/src/Head.cpp | 426 ++++++++++++++++++++--------------------- interface/src/Head.h | 52 +++-- 2 files changed, 235 insertions(+), 243 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 18fa5c9181..1d25118210 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -48,17 +48,17 @@ unsigned int iris_texture_height = 256; Head::Head() { initializeAvatar(); - avatar.orientation.setToIdentity(); - avatar.velocity = glm::vec3( 0.0, 0.0, 0.0 ); - avatar.thrust = glm::vec3( 0.0, 0.0, 0.0 ); - rotation = glm::quat( 0.0f, 0.0f, 0.0f, 0.0f ); - closestOtherAvatar = 0; + _avatar.orientation.setToIdentity(); + _avatar.velocity = glm::vec3( 0.0, 0.0, 0.0 ); + _avatar.thrust = glm::vec3( 0.0, 0.0, 0.0 ); + _rotation = glm::quat( 0.0f, 0.0f, 0.0f, 0.0f ); + _closestOtherAvatar = 0; _bodyYaw = -90.0; _bodyPitch = 0.0; _bodyRoll = 0.0; - bodyYawDelta = 0.0; - triggeringAction = false; - mode = AVATAR_MODE_STANDING; + _bodyYawDelta = 0.0; + _triggeringAction = false; + _mode = AVATAR_MODE_STANDING; initializeSkeleton(); @@ -96,12 +96,12 @@ Head::Head() { browAudioLift = 0.0; noise = 0; - handBeingMoved = false; - previousHandBeingMoved = false; - movedHandOffset = glm::vec3( 0.0, 0.0, 0.0 ); - usingSprings = false; - springForce = 6.0f; - springVelocityDecay = 16.0f; + _handBeingMoved = false; + _previousHandBeingMoved = false; + _movedHandOffset = glm::vec3( 0.0, 0.0, 0.0 ); + _usingSprings = false; + _springForce = 6.0f; + _springVelocityDecay = 16.0f; sphere = NULL; @@ -132,17 +132,17 @@ Head::Head() { Head::Head(const Head &otherHead) { initializeAvatar(); - avatar.orientation.set( otherHead.avatar.orientation ); - avatar.velocity = otherHead.avatar.velocity; - avatar.thrust = otherHead.avatar.thrust; - rotation = otherHead.rotation; - closestOtherAvatar = otherHead.closestOtherAvatar; + _avatar.orientation.set( otherHead._avatar.orientation ); + _avatar.velocity = otherHead._avatar.velocity; + _avatar.thrust = otherHead._avatar.thrust; + _rotation = otherHead._rotation; + _closestOtherAvatar = otherHead._closestOtherAvatar; _bodyYaw = otherHead._bodyYaw; _bodyPitch = otherHead._bodyPitch; _bodyRoll = otherHead._bodyRoll; - bodyYawDelta = otherHead.bodyYawDelta; - triggeringAction = otherHead.triggeringAction; - mode = otherHead.mode; + _bodyYawDelta = otherHead._bodyYawDelta; + _triggeringAction = otherHead._triggeringAction; + _mode = otherHead._mode; initializeSkeleton(); @@ -268,7 +268,7 @@ void Head::setLeanSideways(float dist){ } void Head::setTriggeringAction( bool d ) { - triggeringAction = d; + _triggeringAction = d; } @@ -279,7 +279,7 @@ void Head::simulate(float deltaTime) { // DEBUG - other avatars... //------------------------------------- //closeEnoughToInteract = 0.3f; - closestOtherAvatar = -1; + _closestOtherAvatar = -1; float closestDistance = 10000.0f; @@ -303,15 +303,15 @@ void Head::simulate(float deltaTime) { //------------------------------------- // test other avs for proximity... //------------------------------------- - glm::vec3 v( bone[ AVATAR_BONE_RIGHT_SHOULDER ].position ); + glm::vec3 v( _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position ); v -= DEBUG_otherAvatarListPosition[o]; float distance = glm::length( v ); - if ( distance < avatar.maxArmLength ) { + if ( distance < _avatar.maxArmLength ) { if ( distance < closestDistance ) { closestDistance = distance; - closestOtherAvatar = o; + _closestOtherAvatar = o; } } } @@ -327,80 +327,80 @@ void Head::simulate(float deltaTime) { //------------------------------------------------------------------------ // reset hand and elbow position according to hand movement //------------------------------------------------------------------------ - if ( handBeingMoved ){ - if (! previousHandBeingMoved ){ + if ( _handBeingMoved ){ + if (! _previousHandBeingMoved ){ initializeBodySprings(); - usingSprings = true; + _usingSprings = true; //printf( "just started moving hand\n" ); } } else { - if ( previousHandBeingMoved ){ - usingSprings = false; + if ( _previousHandBeingMoved ){ + _usingSprings = false; //printf( "just stopped moving hand\n" ); } } - if ( handBeingMoved ) { + if ( _handBeingMoved ) { updateHandMovement(); updateBodySprings( deltaTime ); } - previousHandBeingMoved = handBeingMoved; - handBeingMoved = false; + _previousHandBeingMoved = _handBeingMoved; + _handBeingMoved = false; //------------------------------------------------- // this handles the avatar being driven around... //------------------------------------------------- - avatar.thrust = glm::vec3( 0.0, 0.0, 0.0 ); + _avatar.thrust = glm::vec3( 0.0, 0.0, 0.0 ); if (driveKeys[FWD]) { - glm::vec3 front( avatar.orientation.getFront().x, avatar.orientation.getFront().y, avatar.orientation.getFront().z ); - avatar.thrust += front * THRUST_MAG; + glm::vec3 front( _avatar.orientation.getFront().x, _avatar.orientation.getFront().y, _avatar.orientation.getFront().z ); + _avatar.thrust += front * THRUST_MAG; } if (driveKeys[BACK]) { - glm::vec3 front( avatar.orientation.getFront().x, avatar.orientation.getFront().y, avatar.orientation.getFront().z ); - avatar.thrust -= front * THRUST_MAG; + glm::vec3 front( _avatar.orientation.getFront().x, _avatar.orientation.getFront().y, _avatar.orientation.getFront().z ); + _avatar.thrust -= front * THRUST_MAG; } if (driveKeys[RIGHT]) { - glm::vec3 right( avatar.orientation.getRight().x, avatar.orientation.getRight().y, avatar.orientation.getRight().z ); - avatar.thrust -= right * THRUST_MAG; + glm::vec3 right( _avatar.orientation.getRight().x, _avatar.orientation.getRight().y, _avatar.orientation.getRight().z ); + _avatar.thrust -= right * THRUST_MAG; } if (driveKeys[LEFT]) { - glm::vec3 right( avatar.orientation.getRight().x, avatar.orientation.getRight().y, avatar.orientation.getRight().z ); - avatar.thrust += right * THRUST_MAG; + glm::vec3 right( _avatar.orientation.getRight().x, _avatar.orientation.getRight().y, _avatar.orientation.getRight().z ); + _avatar.thrust += right * THRUST_MAG; } if (driveKeys[UP]) { - glm::vec3 up( avatar.orientation.getUp().x, avatar.orientation.getUp().y, avatar.orientation.getUp().z ); - avatar.thrust += up * THRUST_MAG; + glm::vec3 up( _avatar.orientation.getUp().x, _avatar.orientation.getUp().y, _avatar.orientation.getUp().z ); + _avatar.thrust += up * THRUST_MAG; } if (driveKeys[DOWN]) { - glm::vec3 up( avatar.orientation.getUp().x, avatar.orientation.getUp().y, avatar.orientation.getUp().z ); - avatar.thrust -= up * THRUST_MAG; + glm::vec3 up( _avatar.orientation.getUp().x, _avatar.orientation.getUp().y, _avatar.orientation.getUp().z ); + _avatar.thrust -= up * THRUST_MAG; } if (driveKeys[ROT_RIGHT]) { - bodyYawDelta -= YAW_MAG * deltaTime; + _bodyYawDelta -= YAW_MAG * deltaTime; } if (driveKeys[ROT_LEFT]) { - bodyYawDelta += YAW_MAG * deltaTime; + _bodyYawDelta += YAW_MAG * deltaTime; } //---------------------------------------------------------- - float translationalSpeed = glm::length( avatar.velocity ); - float rotationalSpeed = fabs( bodyYawDelta ); + float translationalSpeed = glm::length( _avatar.velocity ); + float rotationalSpeed = fabs( _bodyYawDelta ); if ( translationalSpeed + rotationalSpeed > 0.2 ) { - mode = AVATAR_MODE_WALKING; + _mode = AVATAR_MODE_WALKING; } else { - mode = AVATAR_MODE_COMMUNICATING; + _mode = AVATAR_MODE_COMMUNICATING; } //---------------------------------------------------------- // update body yaw by body yaw delta //---------------------------------------------------------- - _bodyYaw += bodyYawDelta * deltaTime; + _bodyYaw += _bodyYawDelta * deltaTime; //---------------------------------------------------------- // (for now) set head yaw to body yaw @@ -411,23 +411,23 @@ void Head::simulate(float deltaTime) { // decay body yaw delta //---------------------------------------------------------- const float TEST_YAW_DECAY = 5.0; - bodyYawDelta *= ( 1.0 - TEST_YAW_DECAY * deltaTime ); + _bodyYawDelta *= ( 1.0 - TEST_YAW_DECAY * deltaTime ); //---------------------------------------------------------- // add thrust to velocity //---------------------------------------------------------- - avatar.velocity += glm::dvec3( avatar.thrust * deltaTime ); + _avatar.velocity += glm::dvec3( _avatar.thrust * deltaTime ); //---------------------------------------------------------- // update position by velocity //---------------------------------------------------------- - _bodyPosition += (glm::vec3)avatar.velocity * deltaTime; + _bodyPosition += (glm::vec3)_avatar.velocity * deltaTime; //---------------------------------------------------------- // decay velocity //---------------------------------------------------------- const float LIN_VEL_DECAY = 5.0; - avatar.velocity *= ( 1.0 - LIN_VEL_DECAY * deltaTime ); + _avatar.velocity *= ( 1.0 - LIN_VEL_DECAY * deltaTime ); @@ -545,7 +545,7 @@ void Head::render(int faceToFace, int isMine) { //--------------------------------------------------- // show avatar orientation //--------------------------------------------------- - renderOrientationDirections(bone[ AVATAR_BONE_HEAD ].position, bone[ AVATAR_BONE_HEAD ].orientation, 0.2f ); + renderOrientationDirections( _bone[ AVATAR_BONE_HEAD ].position, _bone[ AVATAR_BONE_HEAD ].orientation, 0.2f ); //--------------------------------------------------- // render body @@ -568,11 +568,11 @@ void Head::render(int faceToFace, int isMine) { glPopMatrix(); } - if ( usingSprings ) { - if ( closestOtherAvatar != -1 ) { + if ( _usingSprings ) { + if ( _closestOtherAvatar != -1 ) { - glm::vec3 v1( bone[ AVATAR_BONE_RIGHT_HAND ].position ); - glm::vec3 v2( DEBUG_otherAvatarListPosition[ closestOtherAvatar ] ); + glm::vec3 v1( _bone[ AVATAR_BONE_RIGHT_HAND ].position ); + glm::vec3 v2( DEBUG_otherAvatarListPosition[ _closestOtherAvatar ] ); glLineWidth( 5.0 ); glColor4f( 0.9f, 0.5f, 0.2f, 0.6 ); @@ -624,20 +624,20 @@ void Head::renderHead( int faceToFace, int isMine ) { glPushMatrix(); - if ( usingSprings ) { + if ( _usingSprings ) { glTranslatef ( - bone[ AVATAR_BONE_HEAD ].springyPosition.x, - bone[ AVATAR_BONE_HEAD ].springyPosition.y, - bone[ AVATAR_BONE_HEAD ].springyPosition.z + _bone[ AVATAR_BONE_HEAD ].springyPosition.x, + _bone[ AVATAR_BONE_HEAD ].springyPosition.y, + _bone[ AVATAR_BONE_HEAD ].springyPosition.z ); } else { glTranslatef ( - bone[ AVATAR_BONE_HEAD ].position.x, - bone[ AVATAR_BONE_HEAD ].position.y, - bone[ AVATAR_BONE_HEAD ].position.z + _bone[ AVATAR_BONE_HEAD ].position.x, + _bone[ AVATAR_BONE_HEAD ].position.y, + _bone[ AVATAR_BONE_HEAD ].position.z ); } @@ -786,12 +786,12 @@ void Head::renderHead( int faceToFace, int isMine ) { void Head::setHandMovement( glm::vec3 movement ) { - handBeingMoved = true; - movedHandOffset = movement; + _handBeingMoved = true; + _movedHandOffset = movement; } AvatarMode Head::getMode() { - return mode; + return _mode; } @@ -821,18 +821,18 @@ void Head::initializeAvatar() { void Head::initializeSkeleton() { for (int b=0; b 0.0f ) { glm::vec3 springDirection = springVector / length; - float force = ( length - bone[b].length ) * springForce * deltaTime; + float force = ( length - _bone[b].length ) * _springForce * deltaTime; - bone[ b ].springyVelocity -= springDirection * force; - bone[ bone[b].parent ].springyVelocity += springDirection * force; + _bone[ b ].springyVelocity -= springDirection * force; + _bone[ _bone[b].parent ].springyVelocity += springDirection * force; } - bone[b].springyVelocity += ( bone[b].position - bone[b].springyPosition ) * bone[b].springBodyTightness * deltaTime; + _bone[b].springyVelocity += ( _bone[b].position - _bone[b].springyPosition ) * _bone[b].springBodyTightness * deltaTime; - float decay = 1.0 - springVelocityDecay * deltaTime; + float decay = 1.0 - _springVelocityDecay * deltaTime; if ( decay > 0.0 ) { - bone[b].springyVelocity *= decay; + _bone[b].springyVelocity *= decay; } else { - bone[b].springyVelocity = glm::vec3( 0.0f, 0.0f, 0.0f ); + _bone[b].springyVelocity = glm::vec3( 0.0f, 0.0f, 0.0f ); } - bone[b].springyPosition += bone[b].springyVelocity; + _bone[b].springyPosition += _bone[b].springyVelocity; } } @@ -1024,36 +1024,36 @@ float Head::getBodyYaw() { glm::vec3 Head::getHeadLookatDirection() { return glm::vec3 ( - avatar.orientation.getFront().x, - avatar.orientation.getFront().y, - avatar.orientation.getFront().z + _avatar.orientation.getFront().x, + _avatar.orientation.getFront().y, + _avatar.orientation.getFront().z ); } glm::vec3 Head::getHeadLookatDirectionUp() { return glm::vec3 ( - avatar.orientation.getUp().x, - avatar.orientation.getUp().y, - avatar.orientation.getUp().z + _avatar.orientation.getUp().x, + _avatar.orientation.getUp().y, + _avatar.orientation.getUp().z ); } glm::vec3 Head::getHeadLookatDirectionRight() { return glm::vec3 ( - avatar.orientation.getRight().x, - avatar.orientation.getRight().y, - avatar.orientation.getRight().z + _avatar.orientation.getRight().x, + _avatar.orientation.getRight().y, + _avatar.orientation.getRight().z ); } glm::vec3 Head::getHeadPosition() { return glm::vec3 ( - bone[ AVATAR_BONE_HEAD ].position.x, - bone[ AVATAR_BONE_HEAD ].position.y, - bone[ AVATAR_BONE_HEAD ].position.z + _bone[ AVATAR_BONE_HEAD ].position.x, + _bone[ AVATAR_BONE_HEAD ].position.y, + _bone[ AVATAR_BONE_HEAD ].position.z ); } @@ -1061,26 +1061,26 @@ void Head::updateHandMovement() { glm::vec3 transformedHandMovement; transformedHandMovement - = avatar.orientation.getRight() * -movedHandOffset.x - + avatar.orientation.getUp() * -movedHandOffset.y * 0.5f - + avatar.orientation.getFront() * -movedHandOffset.y; + = _avatar.orientation.getRight() * -_movedHandOffset.x + + _avatar.orientation.getUp() * -_movedHandOffset.y * 0.5f + + _avatar.orientation.getFront() * -_movedHandOffset.y; - bone[ AVATAR_BONE_RIGHT_HAND ].position += transformedHandMovement; + _bone[ AVATAR_BONE_RIGHT_HAND ].position += transformedHandMovement; //if holding hands, add a pull to the hand... - if ( usingSprings ) { - if ( closestOtherAvatar != -1 ) { - if ( triggeringAction ) { + if ( _usingSprings ) { + if ( _closestOtherAvatar != -1 ) { + if ( _triggeringAction ) { /* glm::vec3 handShakePull( DEBUG_otherAvatarListPosition[ closestOtherAvatar ]); - handShakePull -= bone[ AVATAR_BONE_RIGHT_HAND ].position; + handShakePull -= _bone[ AVATAR_BONE_RIGHT_HAND ].position; handShakePull *= 1.0; transformedHandMovement += handShakePull; */ - bone[ AVATAR_BONE_RIGHT_HAND ].position = DEBUG_otherAvatarListPosition[ closestOtherAvatar ]; + _bone[ AVATAR_BONE_RIGHT_HAND ].position = DEBUG_otherAvatarListPosition[ _closestOtherAvatar ]; } } } @@ -1090,8 +1090,8 @@ void Head::updateHandMovement() { //------------------------------------------------------------------------------- // determine the arm vector //------------------------------------------------------------------------------- - glm::vec3 armVector = bone[ AVATAR_BONE_RIGHT_HAND ].position; - armVector -= bone[ AVATAR_BONE_RIGHT_SHOULDER ].position; + glm::vec3 armVector = _bone[ AVATAR_BONE_RIGHT_HAND ].position; + armVector -= _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position; //------------------------------------------------------------------------------- @@ -1102,52 +1102,52 @@ void Head::updateHandMovement() { //------------------------------------------------------------------------------- // if right hand is being dragged beyond maximum arm length... //------------------------------------------------------------------------------- - if ( distance > avatar.maxArmLength ) { + if ( distance > _avatar.maxArmLength ) { //------------------------------------------------------------------------------- // reset right hand to be constrained to maximum arm length //------------------------------------------------------------------------------- - bone[ AVATAR_BONE_RIGHT_HAND ].position = bone[ AVATAR_BONE_RIGHT_SHOULDER ].position; + _bone[ AVATAR_BONE_RIGHT_HAND ].position = _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position; glm::vec3 armNormal = armVector / distance; - armVector = armNormal * avatar.maxArmLength; - distance = avatar.maxArmLength; - glm::vec3 constrainedPosition = bone[ AVATAR_BONE_RIGHT_SHOULDER ].position; + armVector = armNormal * _avatar.maxArmLength; + distance = _avatar.maxArmLength; + glm::vec3 constrainedPosition = _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position; constrainedPosition += armVector; - bone[ AVATAR_BONE_RIGHT_HAND ].position = constrainedPosition; + _bone[ AVATAR_BONE_RIGHT_HAND ].position = constrainedPosition; } /* //------------------------------------------------------------------------------- // keep arm from going through av body... //------------------------------------------------------------------------------- - glm::vec3 adjustedArmVector = bone[ AVATAR_BONE_RIGHT_HAND ].position; - adjustedArmVector -= bone[ AVATAR_BONE_RIGHT_SHOULDER ].position; + glm::vec3 adjustedArmVector = _bone[ AVATAR_BONE_RIGHT_HAND ].position; + adjustedArmVector -= _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position; float rightComponent = glm::dot( adjustedArmVector, avatar.orientation.getRight() ); if ( rightComponent < 0.0 ) { - bone[ AVATAR_BONE_RIGHT_HAND ].position -= avatar.orientation.getRight() * rightComponent; + _bone[ AVATAR_BONE_RIGHT_HAND ].position -= avatar.orientation.getRight() * rightComponent; } */ //----------------------------------------------------------------------------- // set elbow position //----------------------------------------------------------------------------- - glm::vec3 newElbowPosition = bone[ AVATAR_BONE_RIGHT_SHOULDER ].position; + glm::vec3 newElbowPosition = _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position; newElbowPosition += armVector * ONE_HALF; - glm::vec3 perpendicular = glm::cross( avatar.orientation.getFront(), armVector ); + glm::vec3 perpendicular = glm::cross( _avatar.orientation.getFront(), armVector ); - newElbowPosition += perpendicular * ( 1.0f - ( avatar.maxArmLength / distance ) ) * ONE_HALF; - bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].position = newElbowPosition; + newElbowPosition += perpendicular * ( 1.0f - ( _avatar.maxArmLength / distance ) ) * ONE_HALF; + _bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].position = newElbowPosition; //----------------------------------------------------------------------------- // set wrist position //----------------------------------------------------------------------------- - glm::vec3 vv( bone[ AVATAR_BONE_RIGHT_HAND ].position ); - vv -= bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].position; - glm::vec3 newWristPosition = bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].position; + glm::vec3 vv( _bone[ AVATAR_BONE_RIGHT_HAND ].position ); + vv -= _bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].position; + glm::vec3 newWristPosition = _bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].position; newWristPosition += vv * 0.7f; - bone[ AVATAR_BONE_RIGHT_FOREARM ].position = newWristPosition; + _bone[ AVATAR_BONE_RIGHT_FOREARM ].position = newWristPosition; } @@ -1157,17 +1157,17 @@ void Head::renderBody() { // Render bone positions as spheres //----------------------------------------- for (int b=0; b - -#include and +#include +#include +#include enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH}; @@ -164,9 +164,9 @@ class Head : public AvatarData { bool getDriveKeys(int key) { return driveKeys[key]; }; // Set/Get update the thrust that will move the avatar around - void setThrust(glm::vec3 newThrust) { avatar.thrust = newThrust; }; - void addThrust(glm::vec3 newThrust) { avatar.thrust += newThrust; }; - glm::vec3 getThrust() { return avatar.thrust; }; + void setThrust(glm::vec3 newThrust) { _avatar.thrust = newThrust; }; + void addThrust(glm::vec3 newThrust) { _avatar.thrust += newThrust; }; + glm::vec3 getThrust() { return _avatar.thrust; }; // // Related to getting transmitter UDP data used to animate the avatar hand @@ -210,39 +210,33 @@ class Head : public AvatarData { float audioAttack; float browAudioLift; - bool triggeringAction; - - float bodyYawDelta; - - float closeEnoughToInteract; - int closestOtherAvatar; //temporary - placeholder for real other avs glm::vec3 DEBUG_otherAvatarListPosition [ NUM_OTHER_AVATARS ]; float DEBUG_otherAvatarListTimer [ NUM_OTHER_AVATARS ]; - bool usingSprings; - - bool handBeingMoved; - bool previousHandBeingMoved; - glm::vec3 movedHandOffset; + bool _triggeringAction; + float _bodyYawDelta; + float _closeEnoughToInteract; + int _closestOtherAvatar; + bool _usingSprings; + bool _handBeingMoved; + bool _previousHandBeingMoved; + glm::vec3 _movedHandOffset; + float _springVelocityDecay; + float _springForce; + glm::quat _rotation; // the rotation of the avatar body as a whole + AvatarBone _bone[ NUM_AVATAR_BONES ]; + AvatarMode _mode; + Avatar _avatar; int driveKeys[MAX_DRIVE_KEYS]; - float springVelocityDecay; - float springForce; int eyeContact; eyeContactTargets eyeContactTarget; GLUquadric *sphere; - Avatar avatar; - - glm::quat rotation; // the rotation of the avatar body as a whole - - AvatarBone bone[ NUM_AVATAR_BONES ]; - - AvatarMode mode; float renderYaw, renderPitch; // Pitch from view frustum when this is own head. @@ -252,18 +246,16 @@ class Head : public AvatarData { timeval transmitterTimer; float transmitterHz; int transmitterPackets; - - //------------------------------------------- + //----------------------------- // private methods... - //------------------------------------------- + //----------------------------- void initializeAvatar(); void initializeSkeleton(); void updateSkeleton(); void initializeBodySprings(); void updateBodySprings( float deltaTime ); void calculateBoneLengths(); - void readSensors(); }; From 4b1ce1158f9dd26d1788a27cf0b6517ab9d12c91 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 17 Apr 2013 13:15:44 -0700 Subject: [PATCH 07/29] fix number of bytes for avatar processBulkAgentData --- interface/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 851408b55e..9fb29cc6e2 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -1316,7 +1316,7 @@ void *networkReceive(void *args) AgentList::getInstance()->processBulkAgentData(&senderAddress, incomingPacket, bytesReceived, - (sizeof(float) * 3) + (sizeof(uint16_t) * 2)); + (sizeof(float) * 3) + (sizeof(uint16_t) * 3)); break; default: AgentList::getInstance()->processAgentData(&senderAddress, incomingPacket, bytesReceived); From 38d229ab67e7ed682d6cb5f102c24493ba85e63d Mon Sep 17 00:00:00 2001 From: tosh Date: Thu, 18 Apr 2013 00:13:41 +0200 Subject: [PATCH 08/29] reiterates starfield: o allows UrlReader to cache the downloaded content in a local (updating it automatically when the server indicates a newer time stamp) o retires the FieldOfView class o makes the stars move again o fixes bad deletion in UrlReader (delete instead of delete[]) o allows UrlReader to advertise supported compression algorithms to the server --- interface/src/FieldOfView.cpp | 137 -------- interface/src/FieldOfView.h | 142 --------- interface/src/Stars.cpp | 10 +- interface/src/Stars.h | 6 +- interface/src/main.cpp | 42 +-- interface/src/starfield/Config.h | 7 +- interface/src/starfield/Controller.h | 4 +- interface/src/starfield/Loader.h | 4 +- interface/src/starfield/renderer/Renderer.h | 10 +- libraries/shared/src/UrlReader.cpp | 45 ++- libraries/shared/src/UrlReader.h | 331 +++++++++++--------- 11 files changed, 255 insertions(+), 483 deletions(-) delete mode 100644 interface/src/FieldOfView.cpp delete mode 100644 interface/src/FieldOfView.h diff --git a/interface/src/FieldOfView.cpp b/interface/src/FieldOfView.cpp deleted file mode 100644 index 0aef91b0ab..0000000000 --- a/interface/src/FieldOfView.cpp +++ /dev/null @@ -1,137 +0,0 @@ -// -// FieldOfView.cpp -// hifi -// -// Created by Tobias Schwinger on 3/21/13. -// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. -// - -#include "FieldOfView.h" - -#include -#include -#include -#include - -using namespace glm; - -FieldOfView::FieldOfView() : - _matView(mat4(1.0f)), - _vecBoundsLow(vec3(-1.0f,-1.0f,-1.0f)), - _vecBoundsHigh(vec3(1.0f,1.0f,1.0f)), - _valWidth(256.0f), - _valHeight(256.0f), - _valAngle(0.61), - _valZoom(1.0f), - _enmAspectBalancing(expose_less) { -} - -FieldOfView& FieldOfView::setOrientation(mat4 const& matrix) { - - _matView = affineInverse(matrix); - return *this; -} - -mat4 FieldOfView::getOrientation() const { - - return affineInverse(_matView); -} - -mat4 FieldOfView::getViewerScreenXform() const { - - mat4 projection; - vec3 low, high; - getFrustum(low, high); - - // perspective projection? determine correct near distance - if (_valAngle != 0.0f) { - - projection = translate( - frustum(low.x, high.x, low.y, high.y, low.z, high.z), - vec3(0.f, 0.f, -low.z) ); - } else { - - projection = ortho(low.x, high.x, low.y, high.y, low.z, high.z); - } - - return projection; -} - -mat4 FieldOfView::getWorldViewerXform() const { - - return translate(_matView, - vec3(0.0f, 0.0f, -_vecBoundsHigh.z) ); -} - -mat4 FieldOfView::getWorldScreenXform() const { - - return translate( - getViewerScreenXform() * _matView, - vec3(0.0f, 0.0f, -_vecBoundsHigh.z) ); -} - -mat4 FieldOfView::getViewerWorldXform() const { - - vec3 n_translate = vec3(0.0f, 0.0f, _vecBoundsHigh.z); - - return translate( - translate(mat4(1.0f), n_translate) - * affineInverse(_matView), -n_translate ); -} - -float FieldOfView::getPixelSize() const { - - vec3 low, high; - getFrustum(low, high); - - return std::min( - abs(high.x - low.x) / _valWidth, - abs(high.y - low.y) / _valHeight); -} - -void FieldOfView::getFrustum(vec3& low, vec3& high) const { - - low = _vecBoundsLow; - high = _vecBoundsHigh; - - // start with uniform zoom - float inv_zoom = 1.0f / _valZoom; - float adj_x = inv_zoom, adj_y = inv_zoom; - - // balance aspect - if (_enmAspectBalancing != stretch) { - - float f_aspect = (high.x - low.x) / (high.y - low.y); - float vp_aspect = _valWidth / _valHeight; - - if ((_enmAspectBalancing == expose_more) - != (f_aspect > vp_aspect)) { - - // expose_more -> f_aspect <= vp_aspect <=> adj >= 1 - // expose_less -> f_aspect > vp_aspect <=> adj < 1 - adj_x = vp_aspect / f_aspect; - - } else { - - // expose_more -> f_aspect > vp_aspect <=> adj > 1 - // expose_less -> f_aspect <= vp_aspect <=> adj <= 1 - adj_y = f_aspect / vp_aspect; - } - } - - // scale according to zoom / aspect correction - float ax = (low.x + high.x) / 2.0f, ay = (low.y + high.y) / 2.0f; - low.x = (low.x - ax) * adj_x + ax; - high.x = (high.x - ax) * adj_x + ax; - low.y = (low.y - ay) * adj_y + ay; - high.y = (high.y - ay) * adj_y + ay; - low.z = (low.z - high.z) * inv_zoom + high.z; - - // calc and apply near distance based on near diagonal and perspective - float w = high.x - low.x, h = high.y - low.y; - high.z -= low.z; - low.z = _valAngle == 0.0f ? 0.0f : - sqrt(w*w+h*h) * 0.5f / tan(_valAngle * 0.5f); - high.z += low.z; -} - diff --git a/interface/src/FieldOfView.h b/interface/src/FieldOfView.h deleted file mode 100644 index 82d5c79b6b..0000000000 --- a/interface/src/FieldOfView.h +++ /dev/null @@ -1,142 +0,0 @@ -// -// FieldOfView.h -// hifi -// -// Created by Tobias Schwinger on 3/21/13. -// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. -// - -#ifndef __hifi__FieldOfView__ -#define __hifi__FieldOfView__ - -#include - -// -// Viewing parameter encapsulation. -// -// Once configured provides transformation matrices between different coordinate spaces, such as -// -// o world space, -// o viewer space (orientation of local viewer, no projective transforms), and -// o screen space (as Viewer space + projection). -// -// Also provides information about the mapping of the screen space coordinates onto the screen. -// -class FieldOfView { - - glm::mat4 _matView; - glm::vec3 _vecBoundsLow; - glm::vec3 _vecBoundsHigh; - float _valWidth; - float _valHeight; - float _valAngle; - float _valZoom; - int _enmAspectBalancing; - public: - - FieldOfView(); - - // mutators - - FieldOfView& setBounds(glm::vec3 const& low, glm::vec3 const& high) { - _vecBoundsLow = low; _vecBoundsHigh = high; return *this; } - - FieldOfView& setView(glm::mat4 const& matrix) { _matView = matrix; return *this; } - - FieldOfView& setOrientation(glm::mat4 const& matrix); - - FieldOfView& setPerspective(float angle) { _valAngle = angle; return *this; } - - FieldOfView& setResolution(unsigned width, unsigned height) { _valWidth = width; _valHeight = height; return *this; } - - FieldOfView& setZoom(float factor) { _valZoom = factor; return *this; } - - enum aspect_balancing - { - expose_more, - expose_less, - stretch - }; - - FieldOfView& setAspectBalancing(aspect_balancing v) { _enmAspectBalancing = v; return *this; } - - // dumb accessors - - glm::mat4 const& getView() const { return _matView; } - float getWidthInPixels() const { return _valWidth; } - float getHeightInPixels() const { return _valHeight; } - float getPerspective() const { return _valAngle; } - - // matrices - - // - // Returns a matrix representing the camera position and rotation in - // space. Similar to getViewerWorldXform but without translation offset - // applied. - // - glm::mat4 getOrientation() const; - - // - // Returns a full transformation matrix to project world coordinates - // onto the screen. - // - glm::mat4 getWorldScreenXform() const; - - // - // Transforms world coordinates to viewer-relative coordinates. - // - // This matrix can be used as the modelview matrix in legacy GL code - // where the projection matrix is kept separately. - // - glm::mat4 getWorldViewerXform() const; - - // - // Returns the transformation to of viewer-relative coordinates back - // to world space. - // - // This matrix can be used to set up a coordinate system for avatar - // rendering. - // - glm::mat4 getViewerWorldXform() const; - - // - // Returns the transformation of viewer-relative coordinates to the - // screen. - // - // This matrix can be used as the projection matrix in legacy GL code. - // - glm::mat4 getViewerScreenXform() const; - - - // other useful information - - // - // Returns the size of a pixel in world space, that is the minimum - // in respect to x/y screen directions. - // - float getPixelSize() const; - - // - // Returns the frustum as used for the projection matrices. That - // is the one that applies when the current orientation is at identity. - // The result depdends on the bounds, eventually aspect correction - // for the current resolution, the perspective angle (specified in - // respect to diagonal) and zoom. - // - void getFrustum(glm::vec3& low, glm::vec3& high) const; - - // - // Returns the z-offset from the origin to where orientation ia - // applied (in negated form equivalent to the 'near' parameter of - // gluPerspective). - // - float getTransformOffset() const { return _vecBoundsHigh.z; } - - // - // Returns the aspect ratio. - // - float getAspectRatio() const { return _valHeight / _valWidth; } -}; - -#endif /* defined(__hifi__FieldOfView__) */ - diff --git a/interface/src/Stars.cpp b/interface/src/Stars.cpp index 95a0af3654..97d68bc61d 100644 --- a/interface/src/Stars.cpp +++ b/interface/src/Stars.cpp @@ -7,7 +7,6 @@ // #include "InterfaceConfig.h" -#include "FieldOfView.h" #include "Stars.h" #define __interface__Starfield_impl__ @@ -23,8 +22,8 @@ Stars::~Stars() { delete _ptrController; } -bool Stars::readInput(const char* url, unsigned limit) { - return _ptrController->readInput(url, limit); +bool Stars::readInput(const char* url, const char* cacheFile, unsigned limit) { + return _ptrController->readInput(url, cacheFile, limit); } bool Stars::setResolution(unsigned k) { @@ -35,8 +34,9 @@ float Stars::changeLOD(float fraction, float overalloc, float realloc) { return float(_ptrController->changeLOD(fraction, overalloc, realloc)); } -void Stars::render(FieldOfView const& fov) { - _ptrController->render(fov.getPerspective(), fov.getAspectRatio(), fov.getOrientation()); +void Stars::render(float fovDiagonal, float aspect, glm::mat4 const& view) { + + _ptrController->render(fovDiagonal, aspect, glm::affineInverse(view)); } diff --git a/interface/src/Stars.h b/interface/src/Stars.h index 90c52e64ef..92c7b0f806 100644 --- a/interface/src/Stars.h +++ b/interface/src/Stars.h @@ -9,7 +9,7 @@ #ifndef __interface__Stars__ #define __interface__Stars__ -#include "FieldOfView.h" +#include namespace starfield { class Controller; } @@ -31,13 +31,13 @@ class Stars { * The limit parameter allows to reduce the number of stars * that are loaded, keeping the brightest ones. */ - bool readInput(const char* url, unsigned limit = 200000); + bool readInput(const char* url, const char* cacheFile = 0l, unsigned limit = 200000); /** * Renders the starfield from a local viewer's perspective. * The parameter specifies the field of view. */ - void render(FieldOfView const& fov); + void render(float fovDiagonal, float aspect, glm::mat4 const& view); /** * Sets the resolution for FOV culling. diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 851408b55e..2a6a6476f7 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -54,7 +54,7 @@ #include "Audio.h" #endif -#include "FieldOfView.h" +#include "AngleUtil.h" #include "Stars.h" #include "MenuRow.h" @@ -95,6 +95,7 @@ int headMirror = 1; // Whether to mirror own head when viewing int WIDTH = 1200; // Window size int HEIGHT = 800; int fullscreen = 0; +float aspectRatio = 1.0f; bool wantColorRandomizer = true; // for addSphere and load file @@ -108,12 +109,8 @@ Camera viewFrustumOffsetCamera; // The camera we use to sometimes show the v // Starfield information char starFile[] = "https://s3-us-west-1.amazonaws.com/highfidelity/stars.txt"; -FieldOfView fov; +char starCacheFile[] = "cachedStars.txt"; Stars stars; -#ifdef STARFIELD_KEYS -int starsTiles = 20; -double starsLod = 1.0; -#endif bool showingVoxels = true; @@ -306,7 +303,7 @@ void init(void) headMouseX = WIDTH/2; headMouseY = HEIGHT/2; - stars.readInput(starFile, 0); + stars.readInput(starFile, starCacheFile, 0); // Initialize Field values field = Field(); @@ -767,18 +764,12 @@ void display(void) glRotatef ( whichCamera.getYaw(), 0, 1, 0 ); glTranslatef( -whichCamera.getPosition().x, -whichCamera.getPosition().y, -whichCamera.getPosition().z ); - - - - //quick test for camera ortho-normal sanity check... - - - - - if (::starsOn) { // should be the first rendering pass - w/o depth buffer / lighting - stars.render(fov); + + glm::mat4 view; + glGetFloatv(GL_MODELVIEW_MATRIX, glm::value_ptr(view)); + stars.render(angleConvert(whichCamera.getFieldOfView()), aspectRatio, view); } glEnable(GL_LIGHTING); @@ -1280,13 +1271,6 @@ void key(unsigned char k, int x, int y) if (k == ' ') reset_sensors(); if (k == 't') renderPitchRate -= KEYBOARD_PITCH_RATE; if (k == 'g') renderPitchRate += KEYBOARD_PITCH_RATE; -#ifdef STARFIELD_KEYS - if (k == 'u') stars.setResolution(starsTiles += 1); - if (k == 'j') stars.setResolution(starsTiles = max(starsTiles-1,1)); - if (k == 'i') if (starsLod < 1.0) starsLod = stars.changeLOD(1.01); - if (k == 'k') if (starsLod > 0.01) starsLod = stars.changeLOD(0.99); - if (k == 'r') stars.readInput(starFile, 0); -#endif if (k == 'a') myAvatar.setDriveKeys(ROT_LEFT, 1); if (k == 'd') myAvatar.setDriveKeys(ROT_RIGHT, 1); } @@ -1406,7 +1390,7 @@ void reshape(int width, int height) { WIDTH = width; HEIGHT = height; - float aspectRatio = ((float)width/(float)height); // based on screen resize + aspectRatio = ((float)width/(float)height); // based on screen resize float fov; float nearClip; @@ -1434,14 +1418,6 @@ void reshape(int width, int height) glMatrixMode(GL_PROJECTION); //hello - // XXXBHG - Note: this is Tobias's code for loading the perspective matrix. At Philip's suggestion, I'm removing - // it and putting back our old code that simply loaded the fov, ratio, and near/far clips. But I'm keeping this here - // for reference for now. - //fov.setResolution(width, height) - // .setBounds(glm::vec3(-0.5f,-0.5f,-500.0f), glm::vec3(0.5f, 0.5f, 0.1f) ) - // .setPerspective(0.7854f); - //glLoadMatrixf(glm::value_ptr(fov.getViewerScreenXform())); - glLoadIdentity(); // XXXBHG - If we're in view frustum mode, then we need to do this little bit of hackery so that diff --git a/interface/src/starfield/Config.h b/interface/src/starfield/Config.h index 001af23a5f..5717fa22ee 100644 --- a/interface/src/starfield/Config.h +++ b/interface/src/starfield/Config.h @@ -25,8 +25,8 @@ #define STARFIELD_LOW_MEMORY 0 // set to 1 not to use 16-bit types #endif -#ifndef STARFIELD_DEBUG_LOD -#define STARFIELD_DEBUG_LOD 0 // set to 1 to peek behind the scenes +#ifndef STARFIELD_DEBUG_CULLING +#define STARFIELD_DEBUG_CULLING 0 // set to 1 to peek behind the scenes #endif #ifndef STARFIELD_MULTITHREADING @@ -64,7 +64,6 @@ #include #include #include -#include #include "UrlReader.h" #include "AngleUtil.h" @@ -80,13 +79,11 @@ namespace starfield { using glm::vec4; using glm::dot; using glm::normalize; - using glm::swizzle; using glm::X; using glm::Y; using glm::Z; using glm::W; using glm::mat4; - using glm::column; using glm::row; using namespace std; diff --git a/interface/src/starfield/Controller.h b/interface/src/starfield/Controller.h index 329119bbc4..f5680f881a 100644 --- a/interface/src/starfield/Controller.h +++ b/interface/src/starfield/Controller.h @@ -109,11 +109,11 @@ namespace starfield { _ptrRenderer(0l) { } - bool readInput(const char* url, unsigned limit) + bool readInput(const char* url, const char* cacheFile, unsigned limit) { InputVertices vertices; - if (! Loader().loadVertices(vertices, url, limit)) + if (! Loader().loadVertices(vertices, url, cacheFile, limit)) return false; BrightnessLevels brightness; diff --git a/interface/src/starfield/Loader.h b/interface/src/starfield/Loader.h index 03dfd18a53..00210e5e8a 100644 --- a/interface/src/starfield/Loader.h +++ b/interface/src/starfield/Loader.h @@ -33,7 +33,7 @@ namespace starfield { public: bool loadVertices( - InputVertices& destination, char const* url, unsigned limit) + InputVertices& destination, char const* url, char const* cacheFile, unsigned limit) { _ptrVertices = & destination; _valLimit = limit; @@ -43,7 +43,7 @@ namespace starfield { #endif _strUrl = url; // in case we fail early - if (! UrlReader::readUrl(url, *this)) + if (! UrlReader::readUrl(url, *this, cacheFile)) { fprintf(stderr, "%s:%d: %s\n", _strUrl, _valLineNo, getError()); diff --git a/interface/src/starfield/renderer/Renderer.h b/interface/src/starfield/renderer/Renderer.h index 03bc0b5763..a09226ed85 100644 --- a/interface/src/starfield/renderer/Renderer.h +++ b/interface/src/starfield/renderer/Renderer.h @@ -149,7 +149,7 @@ namespace starfield { matrix[3][2] = 0.0f; // extract local z vector - vec3 ahead = swizzle( column(matrix, 2) ); + vec3 ahead = vec3(matrix[2]); float azimuth = atan2(ahead.x,-ahead.z) + Radians::pi(); float altitude = atan2(-ahead.y, hypotf(ahead.x, ahead.z)); @@ -163,7 +163,7 @@ namespace starfield { // fprintf(stderr, "Stars.cpp: starting on tile #%d\n", tileIndex); -#if STARFIELD_DEBUG_LOD +#if STARFIELD_DEBUG_CULLING mat4 matrix_debug = glm::translate( glm::frustum(-hw, hw, -hh, hh, nearClip, 10.0f), vec3(0.0f, 0.0f, -4.0f)) * glm::affineInverse(matrix); @@ -173,7 +173,7 @@ namespace starfield { * glm::affineInverse(matrix); this->_itrOutIndex = (unsigned*) _arrBatchOffs; - this->_vecWxform = swizzle(row(matrix, 3)); + this->_vecWxform = vec3(row(matrix, 3)); this->_valHalfPersp = halfPersp; this->_valMinBright = minBright; @@ -181,13 +181,13 @@ namespace starfield { _arrTile, _arrTile + _objTiling.getTileCount(), (Tile**) _arrBatchCount)); -#if STARFIELD_DEBUG_LOD +#if STARFIELD_DEBUG_CULLING # define matrix matrix_debug #endif this->glBatch(glm::value_ptr(matrix), prepareBatch( (unsigned*) _arrBatchOffs, _itrOutIndex) ); -#if STARFIELD_DEBUG_LOD +#if STARFIELD_DEBUG_CULLING # undef matrix #endif } diff --git a/libraries/shared/src/UrlReader.cpp b/libraries/shared/src/UrlReader.cpp index f8fb707375..750ff1a821 100644 --- a/libraries/shared/src/UrlReader.cpp +++ b/libraries/shared/src/UrlReader.cpp @@ -6,13 +6,17 @@ // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // - #include "UrlReader.h" #include + #ifdef _WIN32 #define NOCURL_IN_WINDOWS #endif + +#include +#include + #ifndef NOCURL_IN_WINDOWS #include size_t const UrlReader::max_read_ahead = CURL_MAX_WRITE_SIZE; @@ -21,6 +25,7 @@ size_t const UrlReader::max_read_ahead = 0; #endif char const* const UrlReader::success = "UrlReader: Success!"; +char const* const UrlReader::success_cached = "UrlReader:: Using local file."; char const* const UrlReader::error_init_failed = "UrlReader: Initialization failed."; char const* const UrlReader::error_aborted = "UrlReader: Processing error."; char const* const UrlReader::error_buffer_overflow = "UrlReader: Buffer overflow."; @@ -29,7 +34,7 @@ char const* const UrlReader::error_leftover_input = "UrlReader: Incomplete pro #define hnd_curl static_cast(_ptrImpl) UrlReader::UrlReader() - : _ptrImpl(0l), _arrXtra(0l), _strError(0l) { + : _ptrImpl(0l), _arrXtra(0l), _strError(0l), _arrCacheRdBuf(0l) { _arrXtra = new(std::nothrow) char[max_read_ahead]; if (! _arrXtra) { _strError = error_init_failed; return; } @@ -39,12 +44,14 @@ UrlReader::UrlReader() curl_easy_setopt(hnd_curl, CURLOPT_NOSIGNAL, 1l); curl_easy_setopt(hnd_curl, CURLOPT_FAILONERROR, 1l); curl_easy_setopt(hnd_curl, CURLOPT_FILETIME, 1l); + curl_easy_setopt(hnd_curl, CURLOPT_ENCODING, ""); #endif } UrlReader::~UrlReader() { - delete _arrXtra; + delete[] _arrXtra; + delete[] _arrCacheRdBuf; #ifndef NOCURL_IN_WINDOWS if (! hnd_curl) return; curl_easy_cleanup(hnd_curl); @@ -78,14 +85,42 @@ void UrlReader::getinfo(char const*& url, char const*& type, int64_t& length, int64_t& stardate) { #ifndef NOCURL_IN_WINDOWS + double clen; + long time; + curl_easy_getinfo(hnd_curl, CURLINFO_FILETIME, & time); + + // check caching file time whether we actually want to download anything + if (_strCacheFile != 0l) { + struct stat s; + stat(_strCacheFile, & s); + if (time > s.st_mtime) { + // file on server is newer -> update cache file + _ptrCacheFile = fopen(_strCacheFile, "wb"); + if (_ptrCacheFile != 0l) { + _valCacheMode = cache_write; + } + } else { + // file on server is older -> use cache file + if (! _arrCacheRdBuf) { + _arrCacheRdBuf = new (std::nothrow) char[max_read_ahead]; + if (! _arrCacheRdBuf) { + _valCacheMode = no_cache; + } + } + _ptrCacheFile = fopen(_strCacheFile, "rb"); + if (_ptrCacheFile != 0l) { + _valCacheMode = cache_read; + } + _strError = success_cached; + } + } + curl_easy_getinfo(hnd_curl, CURLINFO_EFFECTIVE_URL, & url); curl_easy_getinfo(hnd_curl, CURLINFO_CONTENT_TYPE, & type); - double clen; curl_easy_getinfo(hnd_curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, & clen); length = static_cast(clen); - long time; curl_easy_getinfo(hnd_curl, CURLINFO_FILETIME, & time); stardate = time; #endif diff --git a/libraries/shared/src/UrlReader.h b/libraries/shared/src/UrlReader.h index c50fe88d5b..9ad77d27ff 100644 --- a/libraries/shared/src/UrlReader.h +++ b/libraries/shared/src/UrlReader.h @@ -12,119 +12,132 @@ #include #include #include - -/** - * UrlReader class that encapsulates a context for sequential data retrieval - * via URLs. Use one per thread. - */ +#include + +// +// UrlReader class that encapsulates a context for sequential data retrieval +// via URLs. Use one per thread. +// class UrlReader { + enum CacheMode { no_cache, cache_write, cache_read }; + void* _ptrImpl; char* _arrXtra; char const* _strError; void* _ptrStream; + char const* _strCacheFile; + FILE* _ptrCacheFile; + char* _arrCacheRdBuf; + CacheMode _valCacheMode; size_t _valXtraSize; - public: - /** - * Constructor - performs initialization, never throws. - */ + // + // Constructor - performs initialization, never throws. + // UrlReader(); - /** - * Destructor - frees resources, never throws. - */ + // + // Destructor - frees resources, never throws. + // ~UrlReader(); - /** - * Reads data from an URL and forwards it to the instance of a class - * fulfilling the ContentStream concept. - * - * The call protocol on the ContentStream is detailed as follows: - * - * 1. begin(char const* url, - * char const* content_type, uint64_t bytes, uint64_t stardate) - * - * All information except 'url' is optional; 'content_type' can - * be a null pointer - 'bytes' and 'stardate' can be equal to - * to 'unavailable'. - * - * 2. transfer(char* buffer, size_t bytes) - * - * Called until all data has been received. The number of bytes - * actually processed should be returned. - * Unprocessed data is stored in an extra buffer whose size is - * given by the constant UrlReader::max_read_ahead - it can be - * assumed to be reasonably large for on-the-fly parsing. - * - * 3. end(bool ok) - * - * Called at the end of the transfer. - * - * Returns the same success code - */ + // + // Reads data from an URL and forwards it to the instance of a class + // fulfilling the ContentStream concept. + // + // The call protocol on the ContentStream is detailed as follows: + // + // 1. begin(char const* url, + // char const* content_type, uint64_t bytes, uint64_t stardate) + // + // All information except 'url' is optional; 'content_type' can + // be a null pointer - 'bytes' and 'stardate' can be equal to + // to 'unavailable'. + // + // 2. transfer(char* buffer, size_t bytes) + // + // Called until all data has been received. The number of bytes + // actually processed should be returned. + // Unprocessed data is stored in an extra buffer whose size is + // given by the constant UrlReader::max_read_ahead - it can be + // assumed to be reasonably large for on-the-fly parsing. + // + // 3. end(bool ok) + // + // Called at the end of the transfer. + // + // Returns the same success code + // template< class ContentStream > - bool readUrl(char const* url, ContentStream& s); + bool readUrl(char const* url, ContentStream& s, char const* cacheFile = 0l); - /** - * Returns a pointer to a static C-string that describes the error - * condition. - */ + // + // Returns a pointer to a static C-string that describes the error + // condition. + // inline char const* getError() const; - /** - * Can be called by the stream to set a user-defined error string. - */ + // + // Can be called by the stream to set a user-defined error string. + // inline void setError(char const* static_c_string); - /** - * Pointer to the C-string returned by a call to 'readUrl' when no - * error occurred. - */ + // + // Pointer to the C-string returned by a call to 'readUrl' when no + // error occurred. + // static char const* const success; - /** - * Pointer to the C-string returned by a call to 'readUrl' when the - * initialization has failed. - */ + // + // Pointer to the C-string returned by a call to 'readUrl' when no + // error occurred and a local file has been read instead of the + // network stream. + // + static char const* const success_cached; + + // + // Pointer to the C-string returned by a call to 'readUrl' when the + // initialization has failed. + // static char const* const error_init_failed; - /** - * Pointer to the C-string returned by a call to 'readUrl' when the - * transfer has been aborted by the client. - */ + // + // Pointer to the C-string returned by a call to 'readUrl' when the + // transfer has been aborted by the client. + // static char const* const error_aborted; - /** - * Pointer to the C-string returned by a call to 'readUrl' when - * leftover input from incomplete processing caused a buffer - * overflow. - */ + // + // Pointer to the C-string returned by a call to 'readUrl' when + // leftover input from incomplete processing caused a buffer + // overflow. + // static char const* const error_buffer_overflow; - /** - * Pointer to the C-string return by a call to 'readUrl' when the - * input provided was not completely consumed. - */ + // + // Pointer to the C-string return by a call to 'readUrl' when the + // input provided was not completely consumed. + // static char const* const error_leftover_input; - /** - * Constant of the maximum number of bytes that are buffered - * between invocations of 'transfer'. - */ + // + // Constant of the maximum number of bytes that are buffered + // between invocations of 'transfer'. + // static size_t const max_read_ahead; - /** - * Constant representing absent information in the call to the - * 'begin' member function of the target stream. - */ + // + // Constant representing absent information in the call to the + // 'begin' member function of the target stream. + // static int const unavailable = -1; - /** - * Constant for requesting to abort the current transfer when - * returned by the 'transfer' member function of the target stream. - */ + // + // Constant for requesting to abort the current transfer when + // returned by the 'transfer' member function of the target stream. + // static size_t const abort = ~0u; private: @@ -143,38 +156,105 @@ class UrlReader { // synthesized callback - template< class Stream > - static size_t callback_template( - char *input, size_t size, size_t nmemb, void* thiz); + template< class Stream > static size_t callback_template(char *input, size_t size, + size_t nmemb, void* thiz); + + template< class Stream > size_t feedBuffered(Stream* stream, + char* input, size_t size); }; template< class ContentStream > -bool UrlReader::readUrl(char const* url, ContentStream& s) { +bool UrlReader::readUrl(char const* url, ContentStream& s, char const* cacheFile) { if (! _ptrImpl) return false; + _strCacheFile = cacheFile; + _ptrCacheFile = 0l; + _valCacheMode = no_cache; // eventually set later _strError = success; _ptrStream = & s; _valXtraSize = ~size_t(0); this->perform(url, & callback_template); s.end(_strError == success); - return _strError == success; + if (_ptrCacheFile != 0l) { + fclose(_ptrCacheFile); + } + return _strError == success || _strError == success_cached; } inline char const* UrlReader::getError() const { return this->_strError; } -inline void UrlReader::setError(char const* static_c_string) { +inline void UrlReader::setError(char const* staticCstring) { - if (this->_strError == success) - this->_strError = static_c_string; + if (this->_strError == success || this->_strError == success_cached) + this->_strError = staticCstring; } template< class Stream > -size_t UrlReader::callback_template( - char *input, size_t size, size_t nmemb, void* thiz) { +size_t UrlReader::feedBuffered(Stream* stream, char* input, size_t size) { + size_t inputOffset = 0u; - size *= nmemb; + while (true) { + char* buffer = input + inputOffset; + size_t bytes = size - inputOffset; + + // data in extra buffer? + if (_valXtraSize > 0) { + + // fill extra buffer with beginning of input + size_t fill = max_read_ahead - _valXtraSize; + if (bytes < fill) fill = bytes; + memcpy(_arrXtra + _valXtraSize, buffer, fill); + // use extra buffer for next transfer + buffer = _arrXtra; + bytes = _valXtraSize + fill; + inputOffset += fill; + } + + // call 'transfer' + size_t processed = stream->transfer(buffer, bytes); + if (processed == abort) { + + setError(error_aborted); + return 0u; + + } else if (! processed && ! input) { + + setError(error_leftover_input); + return 0u; + } + size_t unprocessed = bytes - processed; + + // can switch to input buffer, now? + if (buffer == _arrXtra && unprocessed <= inputOffset) { + + _valXtraSize = 0u; + inputOffset -= unprocessed; + + } else { // no? unprocessed data -> extra buffer + + if (unprocessed > max_read_ahead) { + + setError(error_buffer_overflow); + return 0; + } + _valXtraSize = unprocessed; + memmove(_arrXtra, buffer + processed, unprocessed); + + if (inputOffset == size || buffer != _arrXtra) { + + return size; + } + } + } // while +} + +template< class Stream > +size_t UrlReader::callback_template(char *input, size_t size, size_t nmemb, void* thiz) { + + size_t result = 0u; UrlReader* me = static_cast(thiz); Stream* stream = static_cast(me->_ptrStream); + size *= nmemb; // first call? if (me->_valXtraSize == ~size_t(0)) { @@ -184,65 +264,28 @@ size_t UrlReader::callback_template( char const* url, * type; int64_t length, stardate; me->getinfo(url, type, length, stardate); - stream->begin(url, type, length, stardate); + if (me->_valCacheMode != cache_read) { + stream->begin(url, type, length, stardate); + } } + do { + // will have to repeat from here when reading a local file - size_t input_offset = 0u; - - while (true) { - - char* buffer = input + input_offset; - size_t bytes = size - input_offset; - - // data in extra buffer? - if (me->_valXtraSize > 0) { - - // fill extra buffer with beginning of input - size_t fill = max_read_ahead - me->_valXtraSize; - if (bytes < fill) fill = bytes; - memcpy(me->_arrXtra + me->_valXtraSize, buffer, fill); - // use extra buffer for next transfer - buffer = me->_arrXtra; - bytes = me->_valXtraSize + fill; - input_offset += fill; + // read from cache file? + if (me->_valCacheMode == cache_read) { + // change input buffer and start + input = me->_arrCacheRdBuf; + size = fread(input, 1, max_read_ahead, me->_ptrCacheFile); + nmemb = 1; + } else if (me->_valCacheMode == cache_write) { + fwrite(input, 1, size, me->_ptrCacheFile); } - // call 'transfer' - size_t processed = stream->transfer(buffer, bytes); - if (processed == abort) { + result = me->feedBuffered(stream, input, size); - me->setError(error_aborted); - return 0u; + } while (me->_valCacheMode == cache_read && result != 0 && ! feof(me->_ptrCacheFile)); - } else if (! processed && ! input) { - - me->setError(error_leftover_input); - return 0u; - } - size_t unprocessed = bytes - processed; - - // can switch to input buffer, now? - if (buffer == me->_arrXtra && unprocessed <= input_offset) { - - me->_valXtraSize = 0u; - input_offset -= unprocessed; - - } else { // no? unprocessed data -> extra buffer - - if (unprocessed > max_read_ahead) { - - me->setError(error_buffer_overflow); - return 0; - } - me->_valXtraSize = unprocessed; - memmove(me->_arrXtra, buffer + processed, unprocessed); - - if (input_offset == size || buffer != me->_arrXtra) { - - return size; - } - } - } // for + return me->_valCacheMode != cache_read ? result : 0; } #endif /* defined(__hifi__UrlReader__) */ From 952cb2f2ae2bf4ba118656a3a55349874bb7b9f7 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 17 Apr 2013 15:14:30 -0700 Subject: [PATCH 09/29] Added head _isMine variable, added hand position transmission! --- interface/src/Head.cpp | 18 ++++++++++++------ interface/src/Head.h | 7 ++++--- interface/src/main.cpp | 8 ++++---- libraries/avatars/src/AvatarData.cpp | 14 ++++++++++++++ libraries/avatars/src/AvatarData.h | 2 ++ 5 files changed, 36 insertions(+), 13 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 2fdb6efe72..0a7390613b 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -45,7 +45,7 @@ vector iris_texture; unsigned int iris_texture_width = 512; unsigned int iris_texture_height = 256; -Head::Head() { +Head::Head(bool isMine) { initializeAvatar(); _avatar.orientation.setToIdentity(); @@ -59,6 +59,7 @@ Head::Head() { _bodyYawDelta = 0.0; _triggeringAction = false; _mode = AVATAR_MODE_STANDING; + _isMine = isMine; initializeSkeleton(); @@ -529,7 +530,7 @@ void Head::simulate(float deltaTime) { -void Head::render(int faceToFace, int isMine) { +void Head::render(int faceToFace) { //--------------------------------------------------- // show avatar position @@ -553,7 +554,7 @@ void Head::render(int faceToFace, int isMine) { //--------------------------------------------------- // render head //--------------------------------------------------- - renderHead( faceToFace, isMine ); + renderHead(faceToFace); //--------------------------------------------------- // render other avatars (DEBUG TEST) @@ -613,7 +614,7 @@ void Head::renderOrientationDirections( glm::vec3 position, Orientation orientat -void Head::renderHead( int faceToFace, int isMine ) { +void Head::renderHead( int faceToFace) { int side = 0; glEnable(GL_DEPTH_TEST); @@ -659,6 +660,7 @@ void Head::renderHead( int faceToFace, int isMine ) { glColor3fv(skinColor); // Head + if (!_isMine) glColor3f(0,0,1); // Temp: Other people are BLUE glutSolidSphere(1, 30, 30); // Ears @@ -1059,8 +1061,8 @@ void Head::updateHandMovement() { + _avatar.orientation.getUp() * -_movedHandOffset.y * 0.5f + _avatar.orientation.getFront() * -_movedHandOffset.y; - _bone[ AVATAR_BONE_RIGHT_HAND ].position += transformedHandMovement; - + _bone[ AVATAR_BONE_RIGHT_HAND ].position += transformedHandMovement; + //if holding hands, add a pull to the hand... if ( _usingSprings ) { if ( _closestOtherAvatar != -1 ) { @@ -1142,6 +1144,10 @@ void Head::updateHandMovement() { glm::vec3 newWristPosition = _bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].position; newWristPosition += vv * 0.7f; _bone[ AVATAR_BONE_RIGHT_FOREARM ].position = newWristPosition; + + // Set the vector we send for hand position to other people to be our right hand + setHandPosition(_bone[ AVATAR_BONE_RIGHT_HAND ].position); + } diff --git a/interface/src/Head.h b/interface/src/Head.h index 30fa9ba936..fae52332ab 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -103,7 +103,7 @@ struct Avatar class Head : public AvatarData { public: - Head(); + Head(bool isMine); ~Head(); Head(const Head &otherHead); Head* clone() const; @@ -143,10 +143,10 @@ class Head : public AvatarData { void setTriggeringAction( bool trigger ); - void render(int faceToFace, int isMine); + void render(int faceToFace); void renderBody(); - void renderHead( int faceToFace, int isMine ); + void renderHead( int faceToFace); //void renderOrientationDirections( glm::vec3 position, Orientation orientation, float size ); void simulate(float); @@ -178,6 +178,7 @@ class Head : public AvatarData { float getTransmitterHz() { return transmitterHz; }; private: + bool _isMine; float noise; float Pitch; float Yaw; diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 547ac38a57..b2b7055db5 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -102,7 +102,7 @@ Oscilloscope audioScope(256,200,true); ViewFrustum viewFrustum; // current state of view frustum, perspective, orientation, etc. -Head myAvatar; // The rendered avatar of oneself +Head myAvatar(true); // The rendered avatar of oneself Camera myCamera; // My view onto the world (sometimes on myself :) Camera viewFrustumOffsetCamera; // The camera we use to sometimes show the view frustum from an offset mode @@ -826,7 +826,7 @@ void display(void) glPushMatrix(); glm::vec3 pos = agentHead->getBodyPosition(); glTranslatef(-pos.x, -pos.y, -pos.z); - agentHead->render(0, 0); + agentHead->render(0); glPopMatrix(); } } @@ -841,7 +841,7 @@ void display(void) //Render my own avatar - myAvatar.render( true, 1 ); + myAvatar.render(true); } glPopMatrix(); @@ -1494,7 +1494,7 @@ void mouseoverFunc( int x, int y) void attachNewHeadToAgent(Agent *newAgent) { if (newAgent->getLinkedData() == NULL) { - newAgent->setLinkedData(new Head()); + newAgent->setLinkedData(new Head(false)); } } diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 0bf9ddff74..9be48b04ac 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -51,6 +51,7 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { // TODO: DRY this up to a shared method // that can pack any type given the number of bytes // and return the number of bytes to push the pointer + memcpy(destinationBuffer, &_bodyPosition, sizeof(float) * 3); destinationBuffer += sizeof(float) * 3; @@ -58,6 +59,11 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyPitch); destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll); + memcpy(destinationBuffer, &_handPosition, sizeof(float) * 3); + destinationBuffer += sizeof(float) * 3; + + //std::cout << _handPosition.x << ", " << _handPosition.y << ", " << _handPosition.z << "\n"; + return destinationBuffer - bufferStart; } @@ -73,6 +79,10 @@ void AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyYaw); sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyPitch); sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyRoll); + + memcpy(&_handPosition, sourceBuffer, sizeof(float) * 3); + sourceBuffer += sizeof(float) * 3; + } glm::vec3 AvatarData::getBodyPosition() { @@ -85,6 +95,10 @@ void AvatarData::setBodyPosition(glm::vec3 bodyPosition) { _bodyPosition = bodyPosition; } +void AvatarData::setHandPosition(glm::vec3 handPosition) { + _handPosition = handPosition; +} + float AvatarData::getBodyYaw() { return _bodyYaw; } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 5e7f52a04d..b650a317f8 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -24,6 +24,7 @@ public: glm::vec3 getBodyPosition(); void setBodyPosition(glm::vec3 bodyPosition); + void setHandPosition(glm::vec3 handPosition); int getBroadcastData(unsigned char* destinationBuffer); void parseData(unsigned char* sourceBuffer, int numBytes); @@ -39,6 +40,7 @@ public: protected: glm::vec3 _bodyPosition; + glm::vec3 _handPosition; float _bodyYaw; float _bodyPitch; From 1a3df2be5f635b915a72ff254d3078233a0952de Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 17 Apr 2013 15:25:05 -0700 Subject: [PATCH 10/29] comment cleanup in AvatarData --- libraries/avatars/src/AvatarData.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 0bf9ddff74..c29789029f 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -43,8 +43,6 @@ AvatarData* AvatarData::clone() const { return new AvatarData(*this); } -// transmit data to agents requesting it -// called on me just prior to sending data to others (continuasly called) int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { unsigned char* bufferStart = destinationBuffer; From 0306b63af4a19dfa57080e38d686844c26fc6f28 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 17 Apr 2013 15:32:16 -0700 Subject: [PATCH 11/29] added more cleanup and preparation for switching over to quaternions --- interface/src/Head.cpp | 56 ++++++++++++++++------------ interface/src/Head.h | 5 +-- libraries/avatars/src/AvatarData.cpp | 2 + 3 files changed, 36 insertions(+), 27 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index ace31629ca..b4d075e592 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -18,6 +18,9 @@ #include #include #include +//#include +//#include +//#include //looks like we might not need this using namespace std; @@ -529,8 +532,6 @@ void Head::simulate(float deltaTime) { - - void Head::render(int faceToFace, int isMine) { //--------------------------------------------------- @@ -822,17 +823,17 @@ void Head::initializeSkeleton() { for (int b=0; b #include -#include - +#include //looks like we might not need this enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH}; @@ -85,7 +84,7 @@ struct AvatarBone glm::vec3 springyPosition; // used for special effects (a 'flexible' variant of position) glm::dvec3 springyVelocity; // used for special effects ( the velocity of the springy position) float springBodyTightness; // how tightly the springy position tries to stay on the position - glm::quat rotation; // this will eventually replace yaw, pitch and roll (and maybe orienttion) + glm::quat rotation; // this will eventually replace yaw, pitch and roll (and maybe orientation) float yaw; // the yaw Euler angle of the bone rotation off the parent float pitch; // the pitch Euler angle of the bone rotation off the parent float roll; // the roll Euler angle of the bone rotation off the parent diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 0bf9ddff74..5e113e3454 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -58,6 +58,8 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyPitch); destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll); + //printf( "_bodyYaw = %f\n", _bodyYaw ); + return destinationBuffer - bufferStart; } From 5aeb307be26b4fc885b5ef6ed4472199ffe13bae Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 17 Apr 2013 15:36:40 -0700 Subject: [PATCH 12/29] including Philips hand position transmission code --- interface/src/Head.cpp | 5 +++-- libraries/avatars/src/AvatarData.cpp | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 127f4afe66..3bb78aa5bb 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -132,7 +132,6 @@ Head::Head(bool isMine) { DEBUG_otherAvatarListPosition[ 4 ] = glm::vec3( -2.0, 0.3, -2.0 ); } - Head::Head(const Head &otherHead) { initializeAvatar(); @@ -531,7 +530,9 @@ void Head::simulate(float deltaTime) { -void Head::render(int faceToFace, int isMine) { + + +void Head::render(int faceToFace) { //--------------------------------------------------- // show avatar position diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 0f080fceeb..02c97e3446 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -57,7 +57,10 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyPitch); destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll); - //printf( "_bodyYaw = %f\n", _bodyYaw ); + memcpy(destinationBuffer, &_handPosition, sizeof(float) * 3); + destinationBuffer += sizeof(float) * 3; + + //std::cout << _handPosition.x << ", " << _handPosition.y << ", " << _handPosition.z << "\n"; return destinationBuffer - bufferStart; } From 6b03622e29aa8c2f01b42fe605cc04a9ec595115 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 17 Apr 2013 16:49:39 -0700 Subject: [PATCH 13/29] Fixed bug having other people showing up at negative of their transmitted position. --- interface/src/main.cpp | 2 +- libraries/avatars/src/AvatarData.cpp | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index b2b7055db5..59617f27c4 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -825,7 +825,7 @@ void display(void) Head *agentHead = (Head *)agent->getLinkedData(); glPushMatrix(); glm::vec3 pos = agentHead->getBodyPosition(); - glTranslatef(-pos.x, -pos.y, -pos.z); + glTranslatef(pos.x, pos.y, pos.z); agentHead->render(0); glPopMatrix(); } diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 9be48b04ac..33818cf43a 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -59,10 +59,12 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyPitch); destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll); + //printf( "_bodyYaw = %f", _bodyYaw ); + memcpy(destinationBuffer, &_handPosition, sizeof(float) * 3); destinationBuffer += sizeof(float) * 3; - //std::cout << _handPosition.x << ", " << _handPosition.y << ", " << _handPosition.z << "\n"; + //std::cout << _bodyPosition.x << ", " << _bodyPosition.y << ", " << _bodyPosition.z << "\n"; return destinationBuffer - bufferStart; } @@ -83,6 +85,9 @@ void AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { memcpy(&_handPosition, sourceBuffer, sizeof(float) * 3); sourceBuffer += sizeof(float) * 3; + //std::cout << _bodyPosition.x << ", " << _bodyPosition.y << ", " << _bodyPosition.z << "\n"; + + } glm::vec3 AvatarData::getBodyPosition() { From ecb5047e7cbeacc3c805a15d42d33901f841db45 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 17 Apr 2013 16:58:04 -0700 Subject: [PATCH 14/29] removed initializeAvatar() method in Head class (deprecated). and also un-negated the pos in the rendering of other avatars (same fix as Philip just made) --- interface/src/Head.cpp | 118 +++++++++++---------------- interface/src/Head.h | 1 - interface/src/main.cpp | 5 +- libraries/avatars/src/AvatarData.cpp | 4 + 4 files changed, 55 insertions(+), 73 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 3bb78aa5bb..d691bc2e1b 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -49,7 +49,6 @@ unsigned int iris_texture_width = 512; unsigned int iris_texture_height = 256; Head::Head(bool isMine) { - initializeAvatar(); _avatar.orientation.setToIdentity(); _avatar.velocity = glm::vec3( 0.0, 0.0, 0.0 ); @@ -133,7 +132,6 @@ Head::Head(bool isMine) { } Head::Head(const Head &otherHead) { - initializeAvatar(); _avatar.orientation.set( otherHead._avatar.orientation ); _avatar.velocity = otherHead._avatar.velocity; @@ -352,42 +350,44 @@ void Head::simulate(float deltaTime) { _previousHandBeingMoved = _handBeingMoved; _handBeingMoved = false; - //------------------------------------------------- - // this handles the avatar being driven around... - //------------------------------------------------- - _avatar.thrust = glm::vec3( 0.0, 0.0, 0.0 ); - - if (driveKeys[FWD]) { - glm::vec3 front( _avatar.orientation.getFront().x, _avatar.orientation.getFront().y, _avatar.orientation.getFront().z ); - _avatar.thrust += front * THRUST_MAG; - } - if (driveKeys[BACK]) { - glm::vec3 front( _avatar.orientation.getFront().x, _avatar.orientation.getFront().y, _avatar.orientation.getFront().z ); - _avatar.thrust -= front * THRUST_MAG; - } - if (driveKeys[RIGHT]) { - glm::vec3 right( _avatar.orientation.getRight().x, _avatar.orientation.getRight().y, _avatar.orientation.getRight().z ); - _avatar.thrust -= right * THRUST_MAG; - } - if (driveKeys[LEFT]) { - glm::vec3 right( _avatar.orientation.getRight().x, _avatar.orientation.getRight().y, _avatar.orientation.getRight().z ); - _avatar.thrust += right * THRUST_MAG; - } - if (driveKeys[UP]) { - glm::vec3 up( _avatar.orientation.getUp().x, _avatar.orientation.getUp().y, _avatar.orientation.getUp().z ); - _avatar.thrust += up * THRUST_MAG; - } - if (driveKeys[DOWN]) { - glm::vec3 up( _avatar.orientation.getUp().x, _avatar.orientation.getUp().y, _avatar.orientation.getUp().z ); - _avatar.thrust -= up * THRUST_MAG; - } - if (driveKeys[ROT_RIGHT]) { - _bodyYawDelta -= YAW_MAG * deltaTime; - } - if (driveKeys[ROT_LEFT]) { - _bodyYawDelta += YAW_MAG * deltaTime; - } - + if ( _isMine ) { // driving the avatar around should only apply is this is my avatar (as opposed to an avatar being driven remotely) + //------------------------------------------------- + // this handles the avatar being driven around... + //------------------------------------------------- + _avatar.thrust = glm::vec3( 0.0, 0.0, 0.0 ); + + if (driveKeys[FWD]) { + glm::vec3 front( _avatar.orientation.getFront().x, _avatar.orientation.getFront().y, _avatar.orientation.getFront().z ); + _avatar.thrust += front * THRUST_MAG; + } + if (driveKeys[BACK]) { + glm::vec3 front( _avatar.orientation.getFront().x, _avatar.orientation.getFront().y, _avatar.orientation.getFront().z ); + _avatar.thrust -= front * THRUST_MAG; + } + if (driveKeys[RIGHT]) { + glm::vec3 right( _avatar.orientation.getRight().x, _avatar.orientation.getRight().y, _avatar.orientation.getRight().z ); + _avatar.thrust -= right * THRUST_MAG; + } + if (driveKeys[LEFT]) { + glm::vec3 right( _avatar.orientation.getRight().x, _avatar.orientation.getRight().y, _avatar.orientation.getRight().z ); + _avatar.thrust += right * THRUST_MAG; + } + if (driveKeys[UP]) { + glm::vec3 up( _avatar.orientation.getUp().x, _avatar.orientation.getUp().y, _avatar.orientation.getUp().z ); + _avatar.thrust += up * THRUST_MAG; + } + if (driveKeys[DOWN]) { + glm::vec3 up( _avatar.orientation.getUp().x, _avatar.orientation.getUp().y, _avatar.orientation.getUp().z ); + _avatar.thrust -= up * THRUST_MAG; + } + if (driveKeys[ROT_RIGHT]) { + _bodyYawDelta -= YAW_MAG * deltaTime; + } + if (driveKeys[ROT_LEFT]) { + _bodyYawDelta += YAW_MAG * deltaTime; + } + } + //---------------------------------------------------------- float translationalSpeed = glm::length( _avatar.velocity ); float rotationalSpeed = fabs( _bodyYawDelta ); @@ -403,7 +403,7 @@ void Head::simulate(float deltaTime) { //---------------------------------------------------------- // update body yaw by body yaw delta //---------------------------------------------------------- - _bodyYaw += _bodyYawDelta * deltaTime; + _bodyYaw += _bodyYawDelta * deltaTime; //---------------------------------------------------------- // (for now) set head yaw to body yaw @@ -650,7 +650,7 @@ void Head::renderHead( int faceToFace) { // Don't render a head if it is really close to your location, because that is your own head! //if (!isMine || faceToFace) - { + //{ glRotatef(Pitch, 1, 0, 0); glRotatef(Roll, 0, 0, 1); @@ -780,7 +780,7 @@ void Head::renderHead( int faceToFace) { glPopMatrix(); - } + //} glPopMatrix(); } @@ -797,29 +797,6 @@ 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(); - - closestOtherAvatar = 0; - - _bodyYaw = -90.0; - _bodyPitch = 0.0; - _bodyRoll = 0.0; - - bodyYawDelta = 0.0; - - triggeringAction = false; - - mode = AVATAR_MODE_STANDING; - - initializeSkeleton(); - */ -} - - void Head::initializeSkeleton() { for (int b=0; bgetLinkedData(); glPushMatrix(); glm::vec3 pos = agentHead->getBodyPosition(); - glTranslatef(-pos.x, -pos.y, -pos.z); + glTranslatef(pos.x, pos.y, pos.z); agentHead->render(0); glPopMatrix(); } @@ -839,7 +839,6 @@ void display(void) // brad's frustum for debugging if (::frustumOn) render_view_frustum(); - //Render my own avatar myAvatar.render(true); } @@ -1361,7 +1360,7 @@ void idle(void) { } // - // Sample hardware, update view frustum if needed, send avatar data to mixer/agents + // Sample hardware, update view frustum if needed, Lsend avatar data to mixer/agents // updateAvatar( 1.f/FPS ); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 02c97e3446..fe36b44817 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -57,6 +57,8 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyPitch); destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll); + //printf( "_bodyYaw = %f\n", _bodyYaw ); + memcpy(destinationBuffer, &_handPosition, sizeof(float) * 3); destinationBuffer += sizeof(float) * 3; @@ -78,6 +80,8 @@ void AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyPitch); sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyRoll); + printf( "_bodyYaw = %f\n", _bodyYaw ); + memcpy(&_handPosition, sourceBuffer, sizeof(float) * 3); sourceBuffer += sizeof(float) * 3; From e75add411c7da631aa2aafb08edc36fa9c2ea5ab Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 17 Apr 2013 16:57:04 -0700 Subject: [PATCH 15/29] use a constant number of BYTES_PER_AVATAR as an interim solution --- interface/src/main.cpp | 3 ++- libraries/avatars/src/AvatarData.cpp | 4 ++-- libraries/avatars/src/AvatarData.h | 2 ++ libraries/shared/src/AgentList.cpp | 7 +++---- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 9fb29cc6e2..8ca43cba20 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -74,6 +74,7 @@ #include #include #include +#include #include "ViewFrustum.h" @@ -1316,7 +1317,7 @@ void *networkReceive(void *args) AgentList::getInstance()->processBulkAgentData(&senderAddress, incomingPacket, bytesReceived, - (sizeof(float) * 3) + (sizeof(uint16_t) * 3)); + BYTES_PER_AVATAR); break; default: AgentList::getInstance()->processAgentData(&senderAddress, incomingPacket, bytesReceived); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index c29789029f..11eb01a50a 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include "AvatarData.h" @@ -23,7 +24,7 @@ int packFloatAngleToTwoByte(unsigned char* buffer, float angle) { return sizeof(uint16_t); } -int unpackFloatAngleFromTwoByte(uint16_t *byteAnglePointer, float *destinationPointer) { +int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPointer) { *destinationPointer = (*byteAnglePointer / std::numeric_limits::max()) * 360.0 - 180; return sizeof(uint16_t); } @@ -61,7 +62,6 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { // called on the other agents - assigns it to my views of the others void AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { - // increment to push past the packet header sourceBuffer++; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 5e7f52a04d..bf0b150a54 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -15,6 +15,8 @@ #include +const int BYTES_PER_AVATAR = 30; + class AvatarData : public AgentData { public: AvatarData(); diff --git a/libraries/shared/src/AgentList.cpp b/libraries/shared/src/AgentList.cpp index 33716ec9f1..e4325df2a0 100644 --- a/libraries/shared/src/AgentList.cpp +++ b/libraries/shared/src/AgentList.cpp @@ -109,7 +109,7 @@ void AgentList::processBulkAgentData(sockaddr *senderAddress, unsigned char *pac unsigned char *startPosition = (unsigned char *)packetData; unsigned char *currentPosition = startPosition + 1; - unsigned char *packetHolder = new unsigned char[numBytesPerAgent + 1]; + unsigned char packetHolder[numBytesPerAgent + 1]; packetHolder[0] = PACKET_HEADER_HEAD_DATA; @@ -122,13 +122,12 @@ void AgentList::processBulkAgentData(sockaddr *senderAddress, unsigned char *pac int matchingAgentIndex = indexOfMatchingAgent(agentID); if (matchingAgentIndex >= 0) { + updateAgentWithData(&agents[matchingAgentIndex], packetHolder, numBytesPerAgent + 1); } currentPosition += numBytesPerAgent; } - - delete[] packetHolder; } void AgentList::updateAgentWithData(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes) { @@ -148,7 +147,7 @@ void AgentList::updateAgentWithData(Agent *agent, unsigned char *packetData, int linkedDataCreateCallback(agent); } } - + agent->getLinkedData()->parseData(packetData, dataBytes); } From 484ab53764b04a0284d6e6939c2cdd5453d33234 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 17 Apr 2013 17:04:29 -0700 Subject: [PATCH 16/29] fix the flipped sign for agentHead translate --- interface/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index fb605a8c20..1854992526 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -826,7 +826,7 @@ void display(void) Head *agentHead = (Head *)agent->getLinkedData(); glPushMatrix(); glm::vec3 pos = agentHead->getBodyPosition(); - glTranslatef(-pos.x, -pos.y, -pos.z); + glTranslatef(pos.x, pos.y, pos.z); agentHead->render(0); glPopMatrix(); } From 4340f127e12d01ae9356e36e73383892d53b5298 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 17 Apr 2013 17:41:37 -0700 Subject: [PATCH 17/29] cast max uint16_t to float for angle unpack --- libraries/avatars/src/AvatarData.cpp | 2 +- libraries/shared/src/AgentList.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 60e05b8d05..955ed0cc9f 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -25,7 +25,7 @@ int packFloatAngleToTwoByte(unsigned char* buffer, float angle) { } int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPointer) { - *destinationPointer = (*byteAnglePointer / std::numeric_limits::max()) * 360.0 - 180; + *destinationPointer = (*byteAnglePointer / (float) std::numeric_limits::max()) * 360.0 - 180; return sizeof(uint16_t); } diff --git a/libraries/shared/src/AgentList.cpp b/libraries/shared/src/AgentList.cpp index e4325df2a0..25a98cdb31 100644 --- a/libraries/shared/src/AgentList.cpp +++ b/libraries/shared/src/AgentList.cpp @@ -107,7 +107,7 @@ void AgentList::processBulkAgentData(sockaddr *senderAddress, unsigned char *pac bulkSendAgent->setLastRecvTimeUsecs(usecTimestampNow()); } - unsigned char *startPosition = (unsigned char *)packetData; + unsigned char *startPosition = packetData; unsigned char *currentPosition = startPosition + 1; unsigned char packetHolder[numBytesPerAgent + 1]; From 24994f35619430f1006bb627d80c0f6e90609fe0 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 17 Apr 2013 17:43:30 -0700 Subject: [PATCH 18/29] remove extra debug line left over from mutex fixes --- libraries/shared/src/Agent.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/shared/src/Agent.cpp b/libraries/shared/src/Agent.cpp index 1ac676e916..dfd16c4cc6 100644 --- a/libraries/shared/src/Agent.cpp +++ b/libraries/shared/src/Agent.cpp @@ -71,7 +71,6 @@ Agent::Agent(const Agent &otherAgent) { } Agent& Agent::operator=(Agent otherAgent) { - std::cout << "Agent swap constructor called on resize?\n"; swap(*this, otherAgent); return *this; } From aba20c6afd3ec191f3ec812edc14ae2cad9e631a Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 17 Apr 2013 17:48:08 -0700 Subject: [PATCH 19/29] a few debugging changes --- interface/src/Head.cpp | 6 +++--- libraries/avatars/src/AvatarData.cpp | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index d691bc2e1b..0ee70d11cf 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -922,7 +922,7 @@ void Head::updateSkeleton() { _avatar.orientation.yaw( _bodyYaw ); //test! - make sure this does what expected: st rotation to be identity PLUS _bodyYaw - _rotation = glm::angleAxis( _bodyYaw, _avatar.orientation.up ); + //_rotation = glm::angleAxis( _bodyYaw, _avatar.orientation.up ); //glm::quat yaw_rotation = glm::angleAxis( _bodyYaw, _avatar.orientation.up ); @@ -940,7 +940,7 @@ void Head::updateSkeleton() { _bone[b].position = _bone[ _bone[b].parent ].position; } - ///TEST! - get this working and then add a comment JJV + ///TEST! - get this working and then add a comment; JJV if ( ! _isMine ) { _bone[ AVATAR_BONE_RIGHT_HAND ].position = _handPosition; } @@ -1051,7 +1051,7 @@ void Head::updateHandMovement() { + _avatar.orientation.getFront() * -_movedHandOffset.y; _bone[ AVATAR_BONE_RIGHT_HAND ].position += transformedHandMovement; - + //if holding hands, add a pull to the hand... if ( _usingSprings ) { if ( _closestOtherAvatar != -1 ) { diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 5e1fbf7828..0f3d5db777 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -63,7 +63,7 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { memcpy(destinationBuffer, &_handPosition, sizeof(float) * 3); destinationBuffer += sizeof(float) * 3; - //std::cout << _handPosition.x << ", " << _handPosition.y << ", " << _handPosition.z << "\n"; + std::cout << _handPosition.x << ", " << _handPosition.y << ", " << _handPosition.z << "\n"; return destinationBuffer - bufferStart; } @@ -80,8 +80,6 @@ void AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyPitch); sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t *)sourceBuffer, &_bodyRoll); - printf( "_bodyYaw = %f\n", _bodyYaw ); - memcpy(&_handPosition, sourceBuffer, sizeof(float) * 3); sourceBuffer += sizeof(float) * 3; From 557bf79e0a7e59572f542e4559596d79df508620 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 17 Apr 2013 17:49:26 -0700 Subject: [PATCH 20/29] body yaw debugging (commented out) --- libraries/avatars/src/AvatarData.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 904a106f73..726617b9e0 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -82,7 +82,10 @@ void AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { memcpy(&_handPosition, sourceBuffer, sizeof(float) * 3); sourceBuffer += sizeof(float) * 3; + + //printf( "_bodyYaw = %f", _bodyYaw ); + //std::cout << _handPosition.x << ", " << _handPosition.y << ", " << _handPosition.z << "\n"; //std::cout << _bodyPosition.x << ", " << _bodyPosition.y << ", " << _bodyPosition.z << "\n"; From 3538e2cf5b6e9930fb54ad0796c8f5ad6b7879f9 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Wed, 17 Apr 2013 17:59:59 -0700 Subject: [PATCH 21/29] fix the number of bytes used for head broadcast --- interface/src/main.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 1854992526..b2934cab17 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -454,6 +454,8 @@ void updateAvatar(float frametime) *broadcastString = PACKET_HEADER_HEAD_DATA; int broadcastBytes = myAvatar.getBroadcastData(broadcastString + 1); + broadcastBytes++; + const char broadcastReceivers[2] = {AGENT_TYPE_VOXEL, AGENT_TYPE_AVATAR_MIXER}; AgentList::getInstance()->broadcastToAgents(broadcastString, broadcastBytes, broadcastReceivers, 2); From 4e12f26467648e2b0e9a24db061629d790c5a6a9 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 17 Apr 2013 18:10:32 -0700 Subject: [PATCH 22/29] added _isMine check for my _bodyYaw update --- interface/src/Head.cpp | 13 ++++++------- interface/src/main.cpp | 9 ++++----- libraries/avatars/src/AvatarData.cpp | 2 +- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 0ee70d11cf..084d7a618d 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -388,6 +388,7 @@ void Head::simulate(float deltaTime) { } } + //---------------------------------------------------------- float translationalSpeed = glm::length( _avatar.velocity ); float rotationalSpeed = fabs( _bodyYawDelta ); @@ -403,8 +404,10 @@ void Head::simulate(float deltaTime) { //---------------------------------------------------------- // update body yaw by body yaw delta //---------------------------------------------------------- + if (_isMine) { _bodyYaw += _bodyYawDelta * deltaTime; - + } + //---------------------------------------------------------- // (for now) set head yaw to body yaw //---------------------------------------------------------- @@ -414,12 +417,12 @@ void Head::simulate(float deltaTime) { // decay body yaw delta //---------------------------------------------------------- const float TEST_YAW_DECAY = 5.0; - _bodyYawDelta *= ( 1.0 - TEST_YAW_DECAY * deltaTime ); + _bodyYawDelta *= (1.0 - TEST_YAW_DECAY * deltaTime); //---------------------------------------------------------- // add thrust to velocity //---------------------------------------------------------- - _avatar.velocity += glm::dvec3( _avatar.thrust * deltaTime ); + _avatar.velocity += glm::dvec3(_avatar.thrust * deltaTime); //---------------------------------------------------------- // update position by velocity @@ -432,8 +435,6 @@ void Head::simulate(float deltaTime) { const float LIN_VEL_DECAY = 5.0; _avatar.velocity *= ( 1.0 - LIN_VEL_DECAY * deltaTime ); - - if (!noise) { // Decay back toward center Pitch *= (1.f - DECAY*2*deltaTime); @@ -450,8 +451,6 @@ void Head::simulate(float deltaTime) { leanForward *= (1.f - DECAY*30.f*deltaTime); leanSideways *= (1.f - DECAY*30.f*deltaTime); - - // Update where the avatar's eyes are // // First, decide if we are making eye contact or not diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 62fa6c77a3..a0e4903bcd 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -1365,10 +1365,9 @@ void idle(void) { // updateAvatar( 1.f/FPS ); - - //test - /* - for(std::vector::iterator agent = agentList.getAgents().begin(); agent != agentList.getAgents().end(); agent++) + //loop through all the other avatars and simulate them. + AgentList * agentList = AgentList::getInstance(); + for(std::vector::iterator agent = agentList->getAgents().begin(); agent != agentList->getAgents().end(); agent++) { if (agent->getLinkedData() != NULL) { @@ -1376,7 +1375,7 @@ void idle(void) { agentHead->simulate(1.f/FPS); } } - */ + updateAvatarHand(1.f/FPS); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index f3a29179d0..4c9164de0b 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -58,7 +58,7 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyPitch); destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll); - //printf( "_bodyYaw = %f\n", _bodyYaw ); + //printf( "_bodyYaw = %f", _bodyYaw ); memcpy(destinationBuffer, &_handPosition, sizeof(float) * 3); destinationBuffer += sizeof(float) * 3; From a64fca17c567745531938791d7b1b63adf400a7c Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 17 Apr 2013 18:25:12 -0700 Subject: [PATCH 23/29] Added more tests for Orientation --- interface/src/Util.cpp | 86 ++++++++++++++++++++++++++++++++---------- 1 file changed, 66 insertions(+), 20 deletions(-) diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index 5c41318ec0..cfef44fa72 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -227,6 +227,13 @@ void renderOrientationDirections( glm::vec3 position, Orientation orientation, f glEnd(); } +bool closeEnoughForGovernmentWork(float a, float b) { + float distance = std::abs(a-b); + //printf("closeEnoughForGovernmentWork() a=%1.10f b=%1.10f distance=%1.10f\n",a,b,distance); + return (distance < 0.00001f); +} + + void testOrientationClass() { printf("\n----------\ntestOrientationClass()\n----------\n\n"); @@ -236,14 +243,45 @@ void testOrientationClass() { // ( 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 ), + 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(45.0f , 0.f , 0.f , 0.707107f , 0.f , 0.707107f , 0.f , 1.0f , 0.f , -0.707107f, 0.f , 0.707107f), + 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(135.0f, 0.f , 0.f , 0.707107f , 0.f ,-0.707107f , 0.f , 1.0f , 0.f , 0.707107f, 0.f , 0.707107f), + 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(225.0f, 0.f , 0.f , -0.707107f , 0.f ,-0.707107f , 0.f , 1.0f , 0.f , 0.707107f, 0.f , -0.707107f), + 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 ), + oTestCase(315.0f, 0.f , 0.f , -0.707107f , 0.f , 0.707107f , 0.f , 1.0f , 0.f , -0.707107f, 0.f , -0.707107f), + oTestCase(-45.0f, 0.f , 0.f , -0.707107f , 0.f , 0.707107f , 0.f , 1.0f , 0.f , -0.707107f, 0.f , -0.707107f), + 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(-135.0f,0.f , 0.f , -0.707107f , 0.f ,-0.707107f , 0.f , 1.0f , 0.f , 0.707107f, 0.f , -0.707107f), + 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(-225.0f,0.f , 0.f , 0.707107f , 0.f ,-0.707107f , 0.f , 1.0f , 0.f , 0.707107f, 0.f , 0.707107f), + 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 ), + oTestCase(-315.0f,0.f , 0.f , 0.707107f , 0.f , 0.707107f , 0.f , 1.0f , 0.f , -0.707107f, 0.f , 0.707107f), // 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 ), + 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( 0.f ,45.0f , 0.f , 0.f, 0.707107f , 0.707107f, 0.f ,0.707107f, -0.707107f, -1.0f , 0.f , 0.f ), + 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 ), + oTestCase( 0.f ,135.0f, 0.f , 0.f, 0.707107f , -0.707107f, 0.f ,-0.707107f, -0.707107f, -1.0f , 0.f , 0.f ), + oTestCase( 0.f ,180.f , 0.f , 0.f, 0.0f ,-1.0f , 0.f ,-1.0f , 0.f , -1.0f , 0.f , 0.f ), + oTestCase( 0.f ,225.0f, 0.f , 0.f,-0.707107f , -0.707107f, 0.f ,-0.707107f, 0.707107f, -1.0f , 0.f , 0.f ), + oTestCase( 0.f ,270.f , 0.f , 0.f,-1.0f , 0.0f , 0.f ,0.0f , 1.0f , -1.0f , 0.f , 0.f ), + oTestCase( 0.f ,315.0f, 0.f , 0.f,-0.707107f , 0.707107f, 0.f , 0.707107f, 0.707107f, -1.0f , 0.f , 0.f ), + // simple roll tests + oTestCase( 0.f , 0.f , 0.f , 0.f , 0.f , 1.0f , 0.f , 1.0f ,0.0f , -1.0f , 0.f , 0.0f ), + oTestCase( 0.f , 0.f ,45.0f , 0.f , 0.f , 1.0f , 0.707107f , 0.707107f ,0.0f , -0.707107f, 0.707107f, 0.0f ), + oTestCase( 0.f , 0.f ,90.f , 0.f , 0.f , 1.0f , 1.0f , 0.0f ,0.0f , 0.0f , 1.0f , 0.0f ), + oTestCase( 0.f , 0.f ,135.0f , 0.f , 0.f , 1.0f , 0.707107f , -0.707107f,0.0f , 0.707107f , 0.707107f, 0.0f ), + oTestCase( 0.f , 0.f ,180.f , 0.f , 0.f , 1.0f , 0.0f , -1.0f ,0.0f , 1.0f , 0.0f , 0.0f ), + oTestCase( 0.f , 0.f ,225.0f , 0.f , 0.f , 1.0f , -0.707107f, -0.707107f,0.0f , 0.707107f ,-0.707107f, 0.0f ), + oTestCase( 0.f , 0.f ,270.f , 0.f , 0.f , 1.0f , -1.0f , 0.0f ,0.0f , 0.0f , -1.0f , 0.0f ), + oTestCase( 0.f , 0.f ,315.0f , 0.f , 0.f , 1.0f , -0.707107f, 0.707107f ,0.0f , -0.707107f,-0.707107f, 0.0f ), + + // yaw combo tests + oTestCase( 90.f , 90.f , 0.f , 0.f , 1.0f , 0.0f , -1.0f , 0.0f , 0.f , 0.0f , 0.f , 1.0f ), + oTestCase( 90.f , 0.f , 90.f , 1.0f , 0.0f, 0.f , 0.0f , 0.0f , -1.f , 0.0f , 1.0f , 0.0f ), }; int failedCount = 0; @@ -267,33 +305,43 @@ void testOrientationClass() { 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("\n-----\nTest: %d - yaw=%f , pitch=%f , roll=%f \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("\nFRONT\n"); + printf(" + received: front.x=%f, front.y=%f, front.z=%f\n",front.x,front.y,front.z); + + if (closeEnoughForGovernmentWork(front.x, tests[i].frontX) + && closeEnoughForGovernmentWork(front.y, tests[i].frontY) + && closeEnoughForGovernmentWork(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); + printf(" expected: front.x=%f, front.y=%f, front.z=%f\n",tests[i].frontX,tests[i].frontY,tests[i].frontZ); + printf(" front vector FAILED! \n"); 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("\nUP\n"); + printf(" + received: up.x=%f, up.y=%f, up.z=%f\n",up.x,up.y,up.z); + if (closeEnoughForGovernmentWork(up.x, tests[i].upX) + && closeEnoughForGovernmentWork(up.y, tests[i].upY) + && closeEnoughForGovernmentWork(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); + printf(" expected: up.x=%f, up.y=%f, up.z=%f\n",tests[i].upX,tests[i].upY,tests[i].upZ); + printf(" up vector FAILED!\n"); 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("\nRIGHT\n"); + printf(" + received: right.x=%f, right.y=%f, right.z=%f\n",right.x,right.y,right.z); + if (closeEnoughForGovernmentWork(right.x, tests[i].rightX) + && closeEnoughForGovernmentWork(right.y, tests[i].rightY) + && closeEnoughForGovernmentWork(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); + printf(" expected: right.x=%f, right.y=%f, right.z=%f\n",tests[i].rightX,tests[i].rightY,tests[i].rightZ); + printf(" right vector FAILED!\n"); passed = false; } @@ -309,5 +357,3 @@ void testOrientationClass() { - - From 46c95ea4af904eb091e578b921a8fe2bd970f555 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 17 Apr 2013 18:28:26 -0700 Subject: [PATCH 24/29] did some code cleanup in Head class and added some _isMine checks to differentiate between my av and others --- interface/src/Head.cpp | 382 ++++++++++++++++++++--------------------- 1 file changed, 189 insertions(+), 193 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 084d7a618d..333fb356fb 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -275,50 +275,49 @@ void Head::setTriggeringAction( bool d ) { void Head::simulate(float deltaTime) { - - //------------------------------------- - // DEBUG - other avatars... - //------------------------------------- - //closeEnoughToInteract = 0.3f; - _closestOtherAvatar = -1; - float closestDistance = 10000.0f; - - - /* - AgentList * agentList = AgentList::getInstance(); + + //------------------------------------------------------------- + // if the avatar being simulated is mone, then loop through + // all the other avatars to get information about them... + //------------------------------------------------------------- + if ( _isMine ) + { + //------------------------------------- + // DEBUG - other avatars... + //------------------------------------- + _closestOtherAvatar = -1; + float closestDistance = 10000.0f; + + AgentList * agentList = AgentList::getInstance(); for(std::vector::iterator agent = agentList->getAgents().begin(); agent != agentList->getAgents().end(); agent++) { if (( agent->getLinkedData() != NULL && ( agent->getType() == AGENT_TYPE_INTERFACE ) )) { - Head *agentHead = (Head *)agent->getLinkedData(); + Head *otherAvatar = (Head *)agent->getLinkedData(); - // when this is working, I will grab the position here... - //glm::vec3 pos = agentHead->getPos(); - + // when this is working, I will grab the position here... + glm::vec3 otherAvatarPosition = otherAvatar->getBodyPosition(); } } - */ - - for (int o=0; osimulate(deltaTime); } @@ -557,31 +553,37 @@ void Head::render(int faceToFace) { //--------------------------------------------------- renderHead(faceToFace); - //--------------------------------------------------- - // render other avatars (DEBUG TEST) - //--------------------------------------------------- - for (int o=0; o BROW_LIFT_THRESHOLD) - browAudioLift += sqrt(audioAttack)/1000.0; - - browAudioLift *= .90; - - glPushMatrix(); - glTranslatef(-interBrowDistance/2.0,0.4,0.45); - for(side = 0; side < 2; side++) { - glColor3fv(browColor); - glPushMatrix(); - glTranslatef(0, 0.35 + browAudioLift, 0); - glRotatef(EyebrowPitch[side]/2.0, 1, 0, 0); - glRotatef(EyebrowRoll[side]/2.0, 0, 0, 1); - glScalef(browWidth, browThickness, 1); - glutSolidCube(0.5); - glPopMatrix(); - glTranslatef(interBrowDistance, 0, 0); - } - glPopMatrix(); - - - // Mouth - - glPushMatrix(); - glTranslatef(0,-0.35,0.75); - glColor3f(0,0,0); - glRotatef(MouthPitch, 1, 0, 0); - glRotatef(MouthYaw, 0, 0, 1); - glScalef(MouthWidth*(.7 + sqrt(averageLoudness)/60.0), MouthHeight*(1.0 + sqrt(averageLoudness)/30.0), 1); - glutSolidCube(0.5); - glPopMatrix(); - - glTranslatef(0, 1.0, 0); - - glTranslatef(-interPupilDistance/2.0,-0.68,0.7); - // Right Eye - glRotatef(-10, 1, 0, 0); - glColor3fv(eyeColor); - glPushMatrix(); - { - glTranslatef(interPupilDistance/10.0, 0, 0.05); - glRotatef(20, 0, 0, 1); - glScalef(EyeballScaleX, EyeballScaleY, EyeballScaleZ); - glutSolidSphere(0.25, 30, 30); - } - glPopMatrix(); - - // Right Pupil - if (sphere == NULL) { - sphere = gluNewQuadric(); - gluQuadricTexture(sphere, GL_TRUE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - gluQuadricOrientation(sphere, GLU_OUTSIDE); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, iris_texture_width, iris_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &iris_texture[0]); - } - - glPushMatrix(); - { - glRotatef(EyeballPitch[1], 1, 0, 0); - glRotatef(EyeballYaw[1] + PupilConverge, 0, 1, 0); - glTranslatef(0,0,.35); - glRotatef(-75,1,0,0); - glScalef(1.0, 0.4, 1.0); + glRotatef(_bodyYaw, 0, 1, 0);// should this use Yaw? - glEnable(GL_TEXTURE_2D); - gluSphere(sphere, PupilSize, 15, 15); - glDisable(GL_TEXTURE_2D); - } + glRotatef(Pitch, 1, 0, 0); + glRotatef(Roll, 0, 0, 1); + + // Overall scale of head + if (faceToFace) glScalef(2.0, 2.0, 2.0); + else glScalef(0.75, 1.0, 1.0); + + glColor3fv(skinColor); - glPopMatrix(); - // Left Eye - glColor3fv(eyeColor); - glTranslatef(interPupilDistance, 0, 0); - glPushMatrix(); - { - glTranslatef(-interPupilDistance/10.0, 0, .05); - glRotatef(-20, 0, 0, 1); - glScalef(EyeballScaleX, EyeballScaleY, EyeballScaleZ); - glutSolidSphere(0.25, 30, 30); + // Head + if (!_isMine) glColor3f(0,0,1); // Temp: Other people are BLUE + glutSolidSphere(1, 30, 30); + + // Ears + glPushMatrix(); + glTranslatef(1.0, 0, 0); + for(side = 0; side < 2; side++) { + glPushMatrix(); + glScalef(0.3, 0.65, .65); + glutSolidSphere(0.5, 30, 30); + glPopMatrix(); + glTranslatef(-2.0, 0, 0); } - glPopMatrix(); - // Left Pupil - glPushMatrix(); - { - glRotatef(EyeballPitch[0], 1, 0, 0); - glRotatef(EyeballYaw[0] - PupilConverge, 0, 1, 0); - glTranslatef(0, 0, .35); - glRotatef(-75, 1, 0, 0); - glScalef(1.0, 0.4, 1.0); + glPopMatrix(); - glEnable(GL_TEXTURE_2D); - gluSphere(sphere, PupilSize, 15, 15); - glDisable(GL_TEXTURE_2D); + // Eyebrows + audioAttack = 0.9*audioAttack + 0.1*fabs(loudness - lastLoudness); + lastLoudness = loudness; + + const float BROW_LIFT_THRESHOLD = 100; + if (audioAttack > BROW_LIFT_THRESHOLD) + browAudioLift += sqrt(audioAttack)/1000.0; + + browAudioLift *= .90; + + glPushMatrix(); + glTranslatef(-interBrowDistance/2.0,0.4,0.45); + for(side = 0; side < 2; side++) { + glColor3fv(browColor); + glPushMatrix(); + glTranslatef(0, 0.35 + browAudioLift, 0); + glRotatef(EyebrowPitch[side]/2.0, 1, 0, 0); + glRotatef(EyebrowRoll[side]/2.0, 0, 0, 1); + glScalef(browWidth, browThickness, 1); + glutSolidCube(0.5); + glPopMatrix(); + glTranslatef(interBrowDistance, 0, 0); } + glPopMatrix(); + + + // Mouth + + glPushMatrix(); + glTranslatef(0,-0.35,0.75); + glColor3f(0,0,0); + glRotatef(MouthPitch, 1, 0, 0); + glRotatef(MouthYaw, 0, 0, 1); + glScalef(MouthWidth*(.7 + sqrt(averageLoudness)/60.0), MouthHeight*(1.0 + sqrt(averageLoudness)/30.0), 1); + glutSolidCube(0.5); + glPopMatrix(); + + glTranslatef(0, 1.0, 0); + + glTranslatef(-interPupilDistance/2.0,-0.68,0.7); + // Right Eye + glRotatef(-10, 1, 0, 0); + glColor3fv(eyeColor); + glPushMatrix(); + { + glTranslatef(interPupilDistance/10.0, 0, 0.05); + glRotatef(20, 0, 0, 1); + glScalef(EyeballScaleX, EyeballScaleY, EyeballScaleZ); + glutSolidSphere(0.25, 30, 30); + } + glPopMatrix(); + + // Right Pupil + if (sphere == NULL) { + sphere = gluNewQuadric(); + gluQuadricTexture(sphere, GL_TRUE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + gluQuadricOrientation(sphere, GLU_OUTSIDE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, iris_texture_width, iris_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &iris_texture[0]); + } + + glPushMatrix(); + { + glRotatef(EyeballPitch[1], 1, 0, 0); + glRotatef(EyeballYaw[1] + PupilConverge, 0, 1, 0); + glTranslatef(0,0,.35); + glRotatef(-75,1,0,0); + glScalef(1.0, 0.4, 1.0); - glPopMatrix(); + glEnable(GL_TEXTURE_2D); + gluSphere(sphere, PupilSize, 15, 15); + glDisable(GL_TEXTURE_2D); + } + + glPopMatrix(); + // Left Eye + glColor3fv(eyeColor); + glTranslatef(interPupilDistance, 0, 0); + glPushMatrix(); + { + glTranslatef(-interPupilDistance/10.0, 0, .05); + glRotatef(-20, 0, 0, 1); + glScalef(EyeballScaleX, EyeballScaleY, EyeballScaleZ); + glutSolidSphere(0.25, 30, 30); + } + glPopMatrix(); + // Left Pupil + glPushMatrix(); + { + glRotatef(EyeballPitch[0], 1, 0, 0); + glRotatef(EyeballYaw[0] - PupilConverge, 0, 1, 0); + glTranslatef(0, 0, .35); + glRotatef(-75, 1, 0, 0); + glScalef(1.0, 0.4, 1.0); + + glEnable(GL_TEXTURE_2D); + gluSphere(sphere, PupilSize, 15, 15); + glDisable(GL_TEXTURE_2D); + } + + glPopMatrix(); + - //} glPopMatrix(); } From d2009366157701dc3157dc7262ce2c40751956ea Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 17 Apr 2013 21:10:31 -0700 Subject: [PATCH 25/29] Added eulerToOrthonormals function for Brad in Util.cpp, sample execution at start of main. --- interface/src/Util.cpp | 32 ++++++++++++++++++++++++++++++++ interface/src/Util.h | 1 + interface/src/main.cpp | 15 ++++++++++++++- 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index 5c41318ec0..ccd407e400 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -11,12 +11,44 @@ #include #include +#include #include #include "world.h" #include "Util.h" + +void eulerToOrthonormals(glm::vec3 * angles, glm::vec3 * fwd, glm::vec3 * left, glm::vec3 * up) { + // + // Converts from three euler angles to the associated orthonormal vectors + // + // Angles contains (pitch, yaw, roll) in radians + // + + // First, create the quaternion associated with these euler angles + glm::quat q(glm::vec3(angles->x, angles->y, angles->z)); + + // Next, create a rotation matrix from that quaternion + glm::mat4 rotation; + rotation = glm::mat4_cast(q); + + // Transform the original vectors by the rotation matrix to get the new vectors + glm::vec4 u(0,1,0,0); + glm::vec4 l(1,0,0,0); + glm::vec4 f(0,0,1,0); + glm::vec4 uNew = u*rotation; + glm::vec4 lNew = l*rotation; + glm::vec4 fNew = f*rotation; + + // Copy the answers to output vectors + up->x = uNew.x; up->y = uNew.y; up->z = uNew.z; + left->x = lNew.x; left->y = lNew.y; left->z = lNew.z; + fwd->x = fNew.x; fwd->y = fNew.y; fwd->z = fNew.z; + +} + + // 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; diff --git a/interface/src/Util.h b/interface/src/Util.h index f2adc918be..5a42884317 100644 --- a/interface/src/Util.h +++ b/interface/src/Util.h @@ -19,6 +19,7 @@ #include +void eulerToOrthonormals(glm::vec3 * angles, glm::vec3 * fwd, glm::vec3 * left, glm::vec3 * up); 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 b2934cab17..3d66828af6 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -1510,7 +1510,20 @@ 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(); + //testOrientationClass(); // PER - commented out to test orthonormal code + + // + // For Brad: Demo of function to test conversion of euler angles to orthonormals + // (Note that the euler angles order is Pitch, Yaw, Roll, and in radians) + // + glm::vec3 angles(0, PI/4, 0); + glm::vec3 fwd, left, up; + + eulerToOrthonormals(&angles, &fwd, &left, &up); + + printf("fwd: %4.2f, %4.2f, %4.2f\n", fwd.x, fwd.y, fwd.z); + printf("left: %4.2f, %4.2f, %4.2f\n", left.x, left.y, left.z); + printf("up: %4.2f, %4.2f, %4.2f\n", up.x, up.y, up.z); AgentList::createInstance(AGENT_TYPE_INTERFACE); From bb2cc54c97e60567d8885eba4f201aacba626d4b Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 17 Apr 2013 22:23:19 -0700 Subject: [PATCH 26/29] Stars turned back on by default - lemme know if anyone sees problems. --- interface/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index c770462cdc..694605b69b 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -148,7 +148,7 @@ float renderPitchRate = 0.f; glm::vec3 start_location(6.1f, 0, 1.4f); int statsOn = 0; // Whether to show onscreen text overlay with stats -bool starsOn = false; // Whether to display the stars +bool starsOn = true; // Whether to display the stars bool paintOn = false; // Whether to paint voxels as you fly around VoxelDetail paintingVoxel; // The voxel we're painting if we're painting unsigned char dominantColor = 0; // The dominant color of the voxel we're painting From bd0eb9f69c9d6267d9e1b064d53901e6acf26a46 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Wed, 17 Apr 2013 23:18:36 -0700 Subject: [PATCH 27/29] renamed Yaw Pitch Roll to _headYaw, _headPitch, _headRoll, in Head class. And also added a "bigSphere avatar collision test", also added a bone radius (for collision detection) --- interface/src/Head.cpp | 177 +++++++++++++++++++++++--------- interface/src/Head.h | 38 ++++--- interface/src/SerialInterface.h | 6 +- interface/src/main.cpp | 15 ++- 4 files changed, 162 insertions(+), 74 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 333fb356fb..059851ee0a 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -38,6 +38,8 @@ float MouthWidthChoices[3] = {0.5, 0.77, 0.3}; float browWidth = 0.8; float browThickness = 0.16; +bool usingBigSphereCollisionTest = false; + const float DECAY = 0.1; const float THRUST_MAG = 10.0; const float YAW_MAG = 300.0; @@ -65,13 +67,16 @@ Head::Head(bool isMine) { initializeSkeleton(); + _TEST_bigSphereRadius = 0.3f; + _TEST_bigSpherePosition = glm::vec3( 0.0f, _TEST_bigSphereRadius, 2.0f ); + for (int i = 0; i < MAX_DRIVE_KEYS; i++) driveKeys[i] = false; PupilSize = 0.10; interPupilDistance = 0.6; interBrowDistance = 0.75; NominalPupilSize = 0.10; - Yaw = 0.0; + _headYaw = 0.0; EyebrowPitch[0] = EyebrowPitch[1] = -30; EyebrowRoll[0] = 20; EyebrowRoll[1] = -20; @@ -153,7 +158,7 @@ Head::Head(const Head &otherHead) { interPupilDistance = otherHead.interPupilDistance; interBrowDistance = otherHead.interBrowDistance; NominalPupilSize = otherHead.NominalPupilSize; - Yaw = otherHead.Yaw; + _headYaw = otherHead._headYaw; EyebrowPitch[0] = otherHead.EyebrowPitch[0]; EyebrowPitch[1] = otherHead.EyebrowPitch[1]; EyebrowRoll[0] = otherHead.EyebrowRoll[0]; @@ -202,7 +207,7 @@ Head* Head::clone() const { } void Head::reset() { - Pitch = Yaw = Roll = 0; + _headPitch = _headYaw = _headRoll = 0; leanForward = leanSideways = 0; } @@ -214,13 +219,13 @@ void Head::UpdateGyros(float frametime, SerialInterface * serialInterface, int h { const float PITCH_ACCEL_COUPLING = 0.5; const float ROLL_ACCEL_COUPLING = -1.0; - float measured_pitch_rate = serialInterface->getRelativeValue(PITCH_RATE); - YawRate = serialInterface->getRelativeValue(YAW_RATE); + float measured_pitch_rate = serialInterface->getRelativeValue(HEAD_PITCH_RATE); + _headYawRate = serialInterface->getRelativeValue(HEAD_YAW_RATE); float measured_lateral_accel = serialInterface->getRelativeValue(ACCEL_X) - - ROLL_ACCEL_COUPLING*serialInterface->getRelativeValue(ROLL_RATE); + ROLL_ACCEL_COUPLING*serialInterface->getRelativeValue(HEAD_ROLL_RATE); float measured_fwd_accel = serialInterface->getRelativeValue(ACCEL_Z) - - PITCH_ACCEL_COUPLING*serialInterface->getRelativeValue(PITCH_RATE); - float measured_roll_rate = serialInterface->getRelativeValue(ROLL_RATE); + PITCH_ACCEL_COUPLING*serialInterface->getRelativeValue(HEAD_PITCH_RATE); + float measured_roll_rate = serialInterface->getRelativeValue(HEAD_ROLL_RATE); //std::cout << "Pitch Rate: " << serialInterface->getRelativeValue(PITCH_RATE) << // " fwd_accel: " << serialInterface->getRelativeValue(ACCEL_Z) << "\n"; @@ -237,18 +242,18 @@ void Head::UpdateGyros(float frametime, SerialInterface * serialInterface, int h const float MAX_YAW = 85; const float MIN_YAW = -85; - if ((Pitch < MAX_PITCH) && (Pitch > MIN_PITCH)) + if ((_headPitch < MAX_PITCH) && (_headPitch > MIN_PITCH)) addPitch(measured_pitch_rate * -HEAD_ROTATION_SCALE * frametime); addRoll(-measured_roll_rate * HEAD_ROLL_SCALE * frametime); if (head_mirror) { - if ((Yaw < MAX_YAW) && (Yaw > MIN_YAW)) - addYaw(-YawRate * HEAD_ROTATION_SCALE * frametime); + if ((_headYaw < MAX_YAW) && (_headYaw > MIN_YAW)) + addYaw(-_headYawRate * HEAD_ROTATION_SCALE * frametime); addLean(-measured_lateral_accel * frametime * HEAD_LEAN_SCALE, -measured_fwd_accel*frametime * HEAD_LEAN_SCALE); } else { - if ((Yaw < MAX_YAW) && (Yaw > MIN_YAW)) - addYaw(YawRate * -HEAD_ROTATION_SCALE * frametime); + if ((_headYaw < MAX_YAW) && (_headYaw > MIN_YAW)) + addYaw(_headYawRate * -HEAD_ROTATION_SCALE * frametime); addLean(measured_lateral_accel * frametime * -HEAD_LEAN_SCALE, measured_fwd_accel*frametime * HEAD_LEAN_SCALE); } } @@ -256,7 +261,7 @@ void Head::UpdateGyros(float frametime, SerialInterface * serialInterface, int h void Head::addLean(float x, float z) { // Add Body lean as impulse leanSideways += x; - leanForward += z; + leanForward += z; } @@ -277,7 +282,7 @@ void Head::setTriggeringAction( bool d ) { void Head::simulate(float deltaTime) { //------------------------------------------------------------- - // if the avatar being simulated is mone, then loop through + // if the avatar being simulated is mine, then loop through // all the other avatars to get information about them... //------------------------------------------------------------- if ( _isMine ) @@ -288,6 +293,7 @@ void Head::simulate(float deltaTime) { _closestOtherAvatar = -1; float closestDistance = 10000.0f; + /* AgentList * agentList = AgentList::getInstance(); for(std::vector::iterator agent = agentList->getAgents().begin(); @@ -297,10 +303,12 @@ void Head::simulate(float deltaTime) { Head *otherAvatar = (Head *)agent->getLinkedData(); // when this is working, I will grab the position here... - glm::vec3 otherAvatarPosition = otherAvatar->getBodyPosition(); + //glm::vec3 otherAvatarPosition = otherAvatar->getBodyPosition(); } } + */ + ///for testing only (prior to having real avs working) for (int o=0; o 0.0) + { + float amp = 1.0 - (distanceToBigSphereCenter / combinedRadius); + glm::vec3 collisionForce = vectorFromJointToBigSphere * amp; + _bone[b].springyVelocity += collisionForce * 8.0f * deltaTime; + _avatar.velocity += collisionForce * 18.0f * deltaTime; + } + } + } + + if ( jointCollision ) { + //---------------------------------------------------------- + // add gravity to velocity + //---------------------------------------------------------- + _avatar.velocity += glm::dvec3( 0.0, -1.0, 0.0 ) * 0.05; + + //---------------------------------------------------------- + // ground collisions + //---------------------------------------------------------- + if ( _bodyPosition.y < 0.0 ) { + _bodyPosition.y = 0.0; + if ( _avatar.velocity.y < 0.0 ) { + _avatar.velocity.y *= -0.7; + } + } + } + } +} + + + void Head::render(int faceToFace) { //--------------------------------------------------- // show avatar position //--------------------------------------------------- + glColor4f( 0.5f, 0.5f, 0.5f, 0.6 ); glPushMatrix(); glTranslatef(_bodyPosition.x, _bodyPosition.y, _bodyPosition.z); glScalef( 0.03, 0.03, 0.03 ); glutSolidSphere( 1, 10, 10 ); glPopMatrix(); + + if ( usingBigSphereCollisionTest ) { + //--------------------------------------------------- + // show TEST big sphere + //--------------------------------------------------- + glColor4f( 0.5f, 0.6f, 0.8f, 0.7 ); + glPushMatrix(); + glTranslatef(_TEST_bigSpherePosition.x, _TEST_bigSpherePosition.y, _TEST_bigSpherePosition.z); + glScalef( _TEST_bigSphereRadius, _TEST_bigSphereRadius, _TEST_bigSphereRadius ); + glutSolidSphere( 1, 20, 20 ); + glPopMatrix(); + } + //--------------------------------------------------- // show avatar orientation //--------------------------------------------------- @@ -645,19 +726,22 @@ void Head::renderHead(int faceToFace) { glScalef( 0.03, 0.03, 0.03 ); - glRotatef(_bodyYaw, 0, 1, 0);// should this use Yaw? - - glRotatef(Pitch, 1, 0, 0); - glRotatef(Roll, 0, 0, 1); + glRotatef(_headYaw, 0, 1, 0); + glRotatef(_headPitch, 1, 0, 0); + glRotatef(_headRoll, 0, 0, 1); // Overall scale of head if (faceToFace) glScalef(2.0, 2.0, 2.0); else glScalef(0.75, 1.0, 1.0); - glColor3fv(skinColor); // Head - if (!_isMine) glColor3f(0,0,1); // Temp: Other people are BLUE + if (_isMine) { + glColor3fv(skinColor); + } + else { + glColor3f(0,0,1); // Temp: Other people are BLUE + } glutSolidSphere(1, 30, 30); // Ears @@ -805,6 +889,7 @@ void Head::initializeSkeleton() { _bone[b].pitch = 0.0; _bone[b].roll = 0.0; _bone[b].length = 0.0; + _bone[b].radius = 0.02; //default _bone[b].springBodyTightness = 4.0; _bone[b].orientation.setToIdentity(); } @@ -1144,14 +1229,14 @@ void Head::renderBody() { glColor3fv( lightBlue ); glPushMatrix(); glTranslatef( _bone[b].springyPosition.x, _bone[b].springyPosition.y, _bone[b].springyPosition.z ); - glutSolidSphere( 0.02f, 10.0f, 5.0f ); + glutSolidSphere( _bone[b].radius, 10.0f, 5.0f ); glPopMatrix(); } else { glColor3fv( skinColor ); glPushMatrix(); glTranslatef( _bone[b].position.x, _bone[b].position.y, _bone[b].position.z ); - glutSolidSphere( 0.02f, 10.0f, 5.0f ); + glutSolidSphere( _bone[b].radius, 10.0f, 5.0f ); glPopMatrix(); } } diff --git a/interface/src/Head.h b/interface/src/Head.h index 55bb370524..a5c34ab272 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -90,6 +90,7 @@ struct AvatarBone float roll; // the roll Euler angle of the bone rotation off the parent Orientation orientation; // three orthogonal normals determined by yaw, pitch, roll float length; // the length of the bone + float radius; // used for detecting collisions for certain physical effects }; struct Avatar @@ -110,9 +111,9 @@ class Head : public AvatarData { void reset(); void UpdateGyros(float frametime, SerialInterface * serialInterface, int head_mirror, glm::vec3 * gravity); void setNoise (float mag) { noise = mag; } - void setPitch(float p) {Pitch = p; } - void setYaw(float y) {Yaw = y; } - void setRoll(float r) {Roll = r; }; + void setPitch(float p) {_headPitch = p; } + void setYaw(float y) {_headYaw = y; } + void setRoll(float r) {_headRoll = r; }; void setScale(float s) {scale = s; }; void setRenderYaw(float y) {renderYaw = y;} void setRenderPitch(float p) {renderPitch = p;} @@ -120,14 +121,14 @@ class Head : public AvatarData { float getRenderPitch() {return renderPitch;} void setLeanForward(float dist); void setLeanSideways(float dist); - void addPitch(float p) {Pitch -= p; } - void addYaw(float y){Yaw -= y; } - void addRoll(float r){Roll += r; } + void addPitch(float p) {_headPitch -= p; } + void addYaw(float y){_headYaw -= y; } + void addRoll(float r){_headRoll += r; } void addLean(float x, float z); - float getPitch() {return Pitch;} - float getRoll() {return Roll;} - float getYaw() {return Yaw;} - float getLastMeasuredYaw() {return YawRate;} + float getPitch() {return _headPitch;} + float getRoll() {return _headRoll;} + float getYaw() {return _headYaw;} + float getLastMeasuredYaw() {return _headYawRate;} float getBodyYaw() {return _bodyYaw;}; void addBodyYaw(float y) {_bodyYaw += y;}; @@ -179,12 +180,12 @@ class Head : public AvatarData { private: bool _isMine; float noise; - float Pitch; - float Yaw; - float Roll; - float PitchRate; - float YawRate; - float RollRate; + float _headPitch; + float _headYaw; + float _headRoll; + float _headPitchRate; + float _headYawRate; + float _headRollRate; float EyeballPitch[2]; float EyeballYaw[2]; float EyebrowPitch[2]; @@ -211,7 +212,9 @@ class Head : public AvatarData { float averageLoudness; float audioAttack; float browAudioLift; - + + glm::vec3 _TEST_bigSpherePosition; + float _TEST_bigSphereRadius; //temporary - placeholder for real other avs glm::vec3 DEBUG_otherAvatarListPosition [ NUM_OTHER_AVATARS ]; @@ -257,6 +260,7 @@ class Head : public AvatarData { void initializeBodySprings(); void updateBodySprings( float deltaTime ); void calculateBoneLengths(); + void updateBigSphereCollisionTest( float deltaTime ); void readSensors(); }; diff --git a/interface/src/SerialInterface.h b/interface/src/SerialInterface.h index 50fde4a13d..457c4b5efa 100644 --- a/interface/src/SerialInterface.h +++ b/interface/src/SerialInterface.h @@ -28,9 +28,9 @@ #define ACCEL_Z 5 // Gyro sensors, in coodinate system of head/airplane -#define PITCH_RATE 1 -#define YAW_RATE 0 -#define ROLL_RATE 2 +#define HEAD_PITCH_RATE 1 +#define HEAD_YAW_RATE 0 +#define HEAD_ROLL_RATE 2 class SerialInterface { public: diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 09bb296b45..2f75f03297 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -170,8 +170,8 @@ int headMouseX, headMouseY; int mouseX, mouseY; // Where is the mouse // Mouse location at start of last down click -int mouseStartX;// = WIDTH / 2; -int mouseStartY;// = HEIGHT / 2; +int mouseStartX = WIDTH / 2; +int mouseStartY = HEIGHT / 2; int mousePressed = 0; // true if mouse has been pressed (clear when finished) Menu menu; // main menu @@ -382,8 +382,8 @@ void updateAvatarHand(float deltaTime) { // void updateAvatar(float frametime) { - float gyroPitchRate = serialPort.getRelativeValue(PITCH_RATE); - float gyroYawRate = serialPort.getRelativeValue(YAW_RATE); + float gyroPitchRate = serialPort.getRelativeValue(HEAD_PITCH_RATE); + float gyroYawRate = serialPort.getRelativeValue(HEAD_YAW_RATE ); myAvatar.UpdateGyros(frametime, &serialPort, headMirror, &gravity); @@ -1334,22 +1334,21 @@ void idle(void) { // Only run simulation code if more than IDLE_SIMULATE_MSECS have passed since last time if (diffclock(&lastTimeIdle, &check) > IDLE_SIMULATE_MSECS) { - // If mouse is being dragged, update hand movement in the avatar - //if ( mousePressed == 1 ) - if ( myAvatar.getMode() == AVATAR_MODE_COMMUNICATING ) { + //if ( myAvatar.getMode() == AVATAR_MODE_COMMUNICATING ) { float leftRight = ( mouseX - mouseStartX ) / (float)WIDTH; float downUp = ( mouseY - mouseStartY ) / (float)HEIGHT; float backFront = 0.0; glm::vec3 handMovement( leftRight, downUp, backFront ); myAvatar.setHandMovement( handMovement ); - } + /*} else { mouseStartX = mouseX; mouseStartY = mouseY; //mouseStartX = (float)WIDTH / 2.0f; //mouseStartY = (float)HEIGHT / 2.0f; } + */ //-------------------------------------------------------- // when the mouse is being pressed, an 'action' is being From 8b9e252246bd24e83f6c3e0012fe4d7b85028616 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 17 Apr 2013 23:21:12 -0700 Subject: [PATCH 28/29] Updated Orientation class to use Philip's technique. - Changed Orientation class to use Philip's technique for determining vectors - updated main.cpp to take command line option to run Orientation tests - tweaked eulerToOrthonormals() to return right vector instead of left vector --- interface/src/Util.cpp | 26 +++--- interface/src/main.cpp | 18 +--- libraries/avatars/src/Orientation.cpp | 115 ++++++++++++++------------ libraries/avatars/src/Orientation.h | 7 ++ 4 files changed, 85 insertions(+), 81 deletions(-) diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index 591cc5024d..4ca77fcb68 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -19,7 +19,7 @@ -void eulerToOrthonormals(glm::vec3 * angles, glm::vec3 * fwd, glm::vec3 * left, glm::vec3 * up) { +void eulerToOrthonormals(glm::vec3 * angles, glm::vec3 * front, glm::vec3 * right, glm::vec3 * up) { // // Converts from three euler angles to the associated orthonormal vectors // @@ -27,28 +27,28 @@ void eulerToOrthonormals(glm::vec3 * angles, glm::vec3 * fwd, glm::vec3 * left, // // First, create the quaternion associated with these euler angles - glm::quat q(glm::vec3(angles->x, angles->y, angles->z)); - + glm::quat q(glm::vec3(angles->x, -(angles->y), angles->z)); + // Next, create a rotation matrix from that quaternion glm::mat4 rotation; rotation = glm::mat4_cast(q); // Transform the original vectors by the rotation matrix to get the new vectors - glm::vec4 u(0,1,0,0); - glm::vec4 l(1,0,0,0); - glm::vec4 f(0,0,1,0); - glm::vec4 uNew = u*rotation; - glm::vec4 lNew = l*rotation; - glm::vec4 fNew = f*rotation; + glm::vec4 qup(0,1,0,0); + glm::vec4 qright(-1,0,0,0); + glm::vec4 qfront(0,0,1,0); + glm::vec4 upNew = qup*rotation; + glm::vec4 rightNew = qright*rotation; + glm::vec4 frontNew = qfront*rotation; // Copy the answers to output vectors - up->x = uNew.x; up->y = uNew.y; up->z = uNew.z; - left->x = lNew.x; left->y = lNew.y; left->z = lNew.z; - fwd->x = fNew.x; fwd->y = fNew.y; fwd->z = fNew.z; - + up->x = upNew.x; up->y = upNew.y; up->z = upNew.z; + right->x = rightNew.x; right->y = rightNew.y; right->z = rightNew.z; + front->x = frontNew.x; front->y = frontNew.y; front->z = frontNew.z; } + // 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; diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 3d66828af6..9cb5e85cb5 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -1510,20 +1510,10 @@ 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(); // PER - commented out to test orthonormal code - - // - // For Brad: Demo of function to test conversion of euler angles to orthonormals - // (Note that the euler angles order is Pitch, Yaw, Roll, and in radians) - // - glm::vec3 angles(0, PI/4, 0); - glm::vec3 fwd, left, up; - - eulerToOrthonormals(&angles, &fwd, &left, &up); - - printf("fwd: %4.2f, %4.2f, %4.2f\n", fwd.x, fwd.y, fwd.z); - printf("left: %4.2f, %4.2f, %4.2f\n", left.x, left.y, left.z); - printf("up: %4.2f, %4.2f, %4.2f\n", up.x, up.y, up.z); + if (cmdOptionExists(argc, argv, "--testOrientation")) { + testOrientationClass(); + return EXIT_SUCCESS; + } AgentList::createInstance(AGENT_TYPE_INTERFACE); diff --git a/libraries/avatars/src/Orientation.cpp b/libraries/avatars/src/Orientation.cpp index f11f820c89..3d6734d92d 100755 --- a/libraries/avatars/src/Orientation.cpp +++ b/libraries/avatars/src/Orientation.cpp @@ -7,19 +7,26 @@ #include "Orientation.h" #include +#include +#include +//#include "Util.h" -static bool testingForNormalizationAndOrthogonality = true; +// XXXBHG - this test has not yet been reworked to match the correct vector orientation +// of the coordinate system, so don't use it for now. +static bool testingForNormalizationAndOrthogonality = false; Orientation::Orientation() { setToIdentity(); } - void Orientation::setToIdentity() { - right = glm::vec3( 1.0, 0.0, 0.0 ); - up = glm::vec3( 0.0, 1.0, 0.0 ); - front = glm::vec3( 0.0, 0.0, 1.0 ); + _yaw = 0.0; + _pitch = 0.0; + _roll = 0.0; + right = glm::vec3( -1.0f, 0.0f, 0.0f ); + up = glm::vec3( 0.0f, 1.0f, 0.0f ); + front = glm::vec3( 0.0f, 0.0f, 1.0f ); } void Orientation::set( Orientation o ) { @@ -28,72 +35,75 @@ void Orientation::set( Orientation o ) { front = o.front; } +void Orientation::update() { -void Orientation::yaw( float angle ) { - float r = angle * PI_OVER_180; - float s = sin(r); - float c = cos(r); - - glm::vec3 cosineFront = front * c; - glm::vec3 cosineRight = right * c; - glm::vec3 sineFront = front * s; - glm::vec3 sineRight = right * s; - - front = cosineFront + sineRight; - right = cosineRight - sineFront; + float pitchRads = _pitch * PI_OVER_180; + float yawRads = _yaw * PI_OVER_180; + float rollRads = _roll * PI_OVER_180; + + glm::quat q(glm::vec3(pitchRads, -(yawRads), rollRads)); + + // Next, create a rotation matrix from that quaternion + glm::mat4 rotation; + rotation = glm::mat4_cast(q); + + // Transform the original vectors by the rotation matrix to get the new vectors + glm::vec4 qup(0,1,0,0); + glm::vec4 qright(-1,0,0,0); + glm::vec4 qfront(0,0,1,0); + glm::vec4 upNew = qup*rotation; + glm::vec4 rightNew = qright*rotation; + glm::vec4 frontNew = qfront*rotation; + + // Copy the answers to output vectors + up.x = upNew.x; + up.y = upNew.y; + up.z = upNew.z; + + right.x = rightNew.x; + right.y = rightNew.y; + right.z = rightNew.z; + + front.x = frontNew.x; + front.y = frontNew.y; + front.z = frontNew.z; if ( testingForNormalizationAndOrthogonality ) { testForOrthogonalAndNormalizedVectors( EPSILON ); } } +void Orientation::yaw(float angle) { + // remember the value for any future changes to other angles + _yaw = angle; + update(); +} void Orientation::pitch( float angle ) { - float r = angle * PI_OVER_180; - float s = sin(r); - float c = cos(r); - - glm::vec3 cosineUp = up * c; - glm::vec3 cosineFront = front * c; - glm::vec3 sineUp = up * s; - glm::vec3 sineFront = front * s; - - up = cosineUp + sineFront; - front = cosineFront - sineUp; - - if ( testingForNormalizationAndOrthogonality ) { testForOrthogonalAndNormalizedVectors( EPSILON ); } + // remember the value for any future changes to other angles + _pitch = angle; + update(); } void Orientation::roll( float angle ) { - float r = angle * PI_OVER_180; - float s = sin(r); - float c = cos(r); - - glm::vec3 cosineUp = up * c; - glm::vec3 cosineRight = right * c; - glm::vec3 sineUp = up * s; - glm::vec3 sineRight = right * s; - - up = cosineUp + sineRight; - right = cosineRight - sineUp; - - if ( testingForNormalizationAndOrthogonality ) { testForOrthogonalAndNormalizedVectors( EPSILON ); } + _roll = angle; + update(); } void Orientation::setRightUpFront( const glm::vec3 &r, const glm::vec3 &u, const glm::vec3 &f ) { - right = r; - up = u; - front = f; + right = r; + up = u; + front = f; } - - -//---------------------------------------------------------------------- void Orientation::testForOrthogonalAndNormalizedVectors( float epsilon ) { - //------------------------------------------------------------------ + // XXXBHG - this test has not yet been reworked to match the correct vector orientation + // of the coordinate system + // bail for now, assume all is good + return; + // 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 ); @@ -122,10 +132,7 @@ void Orientation::testForOrthogonalAndNormalizedVectors( float epsilon ) { assert ( frontLength < 1.0f + epsilon ); - - //---------------------------------------------------------------- // make sure vectors are orthogonal (or close enough) - //---------------------------------------------------------------- glm::vec3 rightCross = glm::cross( up, front ); glm::vec3 upCross = glm::cross( front, right ); glm::vec3 frontCross = glm::cross( right, up ); diff --git a/libraries/avatars/src/Orientation.h b/libraries/avatars/src/Orientation.h index e088f40517..becddbd338 100755 --- a/libraries/avatars/src/Orientation.h +++ b/libraries/avatars/src/Orientation.h @@ -20,6 +20,13 @@ enum Axis class Orientation { +private: + float _yaw; + float _pitch; + float _roll; + + void update(); // actually updates the vectors from yaw, pitch, roll + public: Orientation(); From 44e6fcc5e91673d862bcb6ea11743d90b6b937cd Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 17 Apr 2013 23:42:39 -0700 Subject: [PATCH 29/29] remove pitch from camera since it still breaks Orientation --- interface/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 9cb5e85cb5..4d35006518 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -725,7 +725,7 @@ void display(void) //---------------------------------------------------- myCamera.setTargetPosition ( myAvatar.getBodyPosition() ); myCamera.setYaw ( 180.0 - myAvatar.getBodyYaw() ); - myCamera.setPitch ( 10.0 ); // temporarily, this must be 0.0 or else bad juju + myCamera.setPitch ( 0.0 ); // temporarily, this must be 0.0 or else bad juju myCamera.setRoll ( 0.0 ); myCamera.setUp ( 0.45); myCamera.setDistance ( 1.0 );