From 298bc7eee93fb3daaafeedff9b4ac451372c3a0f Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Thu, 18 Apr 2013 19:24:57 -0700 Subject: [PATCH 01/60] added more robust avatar hand movement algorithm in main.cpp --- interface/src/main.cpp | 123 ++++++++++++++++++++++++++--------------- 1 file changed, 79 insertions(+), 44 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 6f5c1ed7d5..cbf280ce06 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -167,16 +167,73 @@ int displayField = 0; int displayHeadMouse = 1; // Display sample mouse pointer controlled by head movement int headMouseX, headMouseY; -int mouseX, mouseY; // Where is the mouse +int mouseX = 0; +int mouseY = 0; // Mouse location at start of last down click -int mouseStartX = WIDTH / 2; -int mouseStartY = HEIGHT / 2; int mousePressed = 0; // true if mouse has been pressed (clear when finished) Menu menu; // main menu int menuOn = 1; // Whether to show onscreen menu +struct HandMovement +{ + bool enabled = false; + int startX = WIDTH / 2; + int startY = HEIGHT / 2; + int x = 0; + int y = 0; + int lastX = 0; + int lastY = 0; + int velocityX = 0; + int velocityY = 0; + float rampUpRate = 0.05; + float rampDownRate = 0.02; + float envelope = 0.0f; +}; + +HandMovement handMovement; + +void updateHandMovement( int x, int y ) { + handMovement.lastX = handMovement.x; + handMovement.lastY = handMovement.y; + handMovement.x = x; + handMovement.y = y; + handMovement.velocityX = handMovement.x - handMovement.lastX; + handMovement.velocityY = handMovement.y - handMovement.lastY; + + if (( handMovement.velocityX != 0 ) + || ( handMovement.velocityY != 0 )) { + handMovement.enabled = true; + if ( handMovement.envelope < 1.0 ) { + handMovement.envelope += handMovement.rampUpRate; + if ( handMovement.envelope >= 1.0 ) { + handMovement.envelope = 1.0; + } + } + } + + if ( ! handMovement.enabled ) { + if ( handMovement.envelope > 0.0 ) { + handMovement.envelope -= handMovement.rampDownRate; + if ( handMovement.envelope <= 0.0 ) { + handMovement.startX = WIDTH / 2; + handMovement.startY = HEIGHT / 2; + handMovement.envelope = 0.0; + } + } + } + + if ( handMovement.envelope > 0.0 ) { + float leftRight = ( ( handMovement.x - handMovement.startX ) / (float)WIDTH ) * handMovement.envelope; + float downUp = ( ( handMovement.y - handMovement.startY ) / (float)HEIGHT ) * handMovement.envelope; + float backFront = 0.0; + myAvatar.setHandMovement( glm::vec3( leftRight, downUp, backFront ) ); + } +} + + + // // Serial USB Variables // @@ -363,22 +420,6 @@ void reset_sensors() } } -/* -void updateAvatarHand(float deltaTime) { - // If mouse is being dragged, send current force to the hand controller - if (mousePressed == 1) - { - // NOTE--PER: Need to re-implement when ready for new avatar hand movements - - const float MOUSE_HAND_FORCE = 1.5; - float dx = mouseX - mouseStartX; - float dy = mouseY - mouseStartY; - glm::vec3 vel(dx*MOUSE_HAND_FORCE, -dy*MOUSE_HAND_FORCE*(WIDTH/HEIGHT), 0); - //myAvatar.hand->addVelocity(vel*deltaTime); - } -} -*/ - // // Using gyro data, update both view frustum and avatar head position // @@ -830,10 +871,10 @@ void display(void) agent != agentList->getAgents().end(); agent++) { if (agent->getLinkedData() != NULL) { - Head *agentHead = (Head *)agent->getLinkedData(); - glPushMatrix(); - agentHead->render(0); - glPopMatrix(); + Head *avatar = (Head *)agent->getLinkedData(); + //glPushMatrix(); + avatar->render(0); + //glPopMatrix(); } } @@ -1332,25 +1373,13 @@ void idle(void) { if (diffclock(&lastTimeIdle, &check) > IDLE_SIMULATE_MSECS) { - //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; - } - */ - - //-------------------------------------------------------- + float deltaTime = 1.f/FPS; + + // update behaviors for avatar hand movement + updateHandMovement( mouseX, mouseY ); + // when the mouse is being pressed, an 'action' is being // triggered in the avatar. The action is context-based. - //-------------------------------------------------------- if ( mousePressed == 1 ) { myAvatar.setTriggeringAction( true ); } @@ -1358,8 +1387,11 @@ void idle(void) { myAvatar.setTriggeringAction( false ); } - float deltaTime = 1.f/FPS; - + // walking triggers the handMovement to stop + if ( myAvatar.getMode() == AVATAR_MODE_WALKING ) { + handMovement.enabled = false; + } + // // Sample hardware, update view frustum if needed, Lsend avatar data to mixer/agents // @@ -1457,8 +1489,6 @@ void mouseFunc( int button, int state, int x, int y ) mouseX = x; mouseY = y; mousePressed = 1; - //mouseStartX = x; - //mouseStartY = y; } } if( button == GLUT_LEFT_BUTTON && state == GLUT_UP ) { @@ -1478,12 +1508,17 @@ void motionFunc( int x, int y) void mouseoverFunc( int x, int y) { menu.mouseOver(x, y); + mouseX = x; mouseY = y; if (mousePressed == 0) {} } + + + + void attachNewHeadToAgent(Agent *newAgent) { if (newAgent->getLinkedData() == NULL) { newAgent->setLinkedData(new Head(false)); From 9dd423f5448ecd9724cf0185b727208b810c63f7 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Thu, 18 Apr 2013 19:30:27 -0700 Subject: [PATCH 02/60] removed updateAvatarHand function --- interface/src/main.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 75b6132be6..80341e5f3b 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -426,6 +426,22 @@ void reset_sensors() } } +/* +void updateAvatarHand(float deltaTime) { + // If mouse is being dragged, send current force to the hand controller + if (mousePressed == 1) + { + // NOTE--PER: Need to re-implement when ready for new avatar hand movements + + const float MOUSE_HAND_FORCE = 1.5; + float dx = mouseX - mouseStartX; + float dy = mouseY - mouseStartY; + glm::vec3 vel(dx*MOUSE_HAND_FORCE, -dy*MOUSE_HAND_FORCE*(WIDTH/HEIGHT), 0); + //myAvatar.hand->addVelocity(vel*deltaTime); + } +} +*/ + // // Using gyro data, update both view frustum and avatar head position // From 623c99843951b1d4d8a4be3d9741de7ad5bb6550 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Thu, 18 Apr 2013 21:31:20 -0700 Subject: [PATCH 03/60] removed init values in HandMovement structure --- interface/src/main.cpp | 46 +++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 80341e5f3b..117c94a053 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -174,27 +174,43 @@ int mouseY = 0; // Mouse location at start of last down click int mousePressed = 0; // true if mouse has been pressed (clear when finished) -Menu menu; // main menu -int menuOn = 1; // Whether to show onscreen menu +Menu menu; // main menu +int menuOn = 1; // Whether to show onscreen menu struct HandMovement { - bool enabled = false; - int startX = WIDTH / 2; - int startY = HEIGHT / 2; - int x = 0; - int y = 0; - int lastX = 0; - int lastY = 0; - int velocityX = 0; - int velocityY = 0; - float rampUpRate = 0.05; - float rampDownRate = 0.02; - float envelope = 0.0f; + bool enabled; + int startX; + int startY; + int x; + int y; + int lastX; + int lastY; + int velocityX; + int velocityY; + float rampUpRate; + float rampDownRate; + float envelope; }; HandMovement handMovement; +void initializeHandMovement() { + handMovement.enabled = false; + handMovement.startX = WIDTH / 2; + handMovement.startY = HEIGHT / 2; + handMovement.x = 0; + handMovement.y = 0; + handMovement.lastX = 0; + handMovement.lastY = 0; + handMovement.velocityX = 0; + handMovement.velocityY = 0; + handMovement.rampUpRate = 0.05; + handMovement.rampDownRate = 0.02; + handMovement.envelope = 0.0f; + +} + void updateHandMovement( int x, int y ) { handMovement.lastX = handMovement.x; handMovement.lastY = handMovement.y; @@ -361,6 +377,8 @@ void init(void) voxels.init(); voxels.setViewerHead(&myAvatar); myAvatar.setRenderYaw(startYaw); + + initializeHandMovement(); headMouseX = WIDTH/2; headMouseY = HEIGHT/2; From d962230556ccefd6e6edca73b496e6ea1956367c Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 19 Apr 2013 12:44:09 -0700 Subject: [PATCH 04/60] fixed sneaky array-out-of-bounds error in avatar bones and cleaned up some of the code for testing hand shake target positions --- interface/src/Head.cpp | 58 +++++++++++++++------------ interface/src/Head.h | 1 - libraries/avatars/src/Orientation.cpp | 3 +- 3 files changed, 33 insertions(+), 29 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 6f77ee66dc..b191c454d6 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -120,20 +120,18 @@ Head::Head(bool isMine) { printLog("error %u: %s\n", error, lodepng_error_text(error)); } } - - for (int o=0; o Date: Fri, 19 Apr 2013 14:34:01 -0700 Subject: [PATCH 05/60] cleaned up logic for body springs mode and moving hand mode --- interface/src/Head.cpp | 75 +++++++++++++++-------------- interface/src/Head.h | 20 ++++++-- interface/src/main.cpp | 106 ++++++++++++++++++----------------------- 3 files changed, 99 insertions(+), 102 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index b191c454d6..442c5eefba 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -33,7 +33,7 @@ float MouthWidthChoices[3] = {0.5, 0.77, 0.3}; float browWidth = 0.8; float browThickness = 0.16; -bool usingBigSphereCollisionTest = false; +bool usingBigSphereCollisionTest = true; const float DECAY = 0.1; const float THRUST_MAG = 10.0; @@ -104,10 +104,8 @@ Head::Head(bool isMine) { _lastLoudness = 0.0; _browAudioLift = 0.0; _noise = 0; - _handBeingMoved = false; - _previousHandBeingMoved = false; _movedHandOffset = glm::vec3( 0.0, 0.0, 0.0 ); - _usingSprings = false; + _usingBodySprings = false; _springForce = 6.0f; _springVelocityDecay = 16.0f; @@ -338,32 +336,15 @@ void Head::simulate(float deltaTime) { //------------------------ updateSkeleton(); - //------------------------------------------------------------------------ - // reset hand and elbow position according to hand movement - //------------------------------------------------------------------------ - if ( _handBeingMoved ){ - if (! _previousHandBeingMoved ){ - initializeBodySprings(); - _usingSprings = true; - //printLog( "just started moving hand\n" ); - } - } - else { - if ( _previousHandBeingMoved ){ - _usingSprings = false; - //printLog( "just stopped moving hand\n" ); - } - } - - if ( _handBeingMoved ) { + //------------------------------------------------------------ + // reset hand and arm positions according to hand movement + //------------------------------------------------------------ + if (_usingBodySprings) { updateHandMovement(); updateBodySprings( deltaTime ); } - - _previousHandBeingMoved = _handBeingMoved; - _handBeingMoved = false; - if ( _isMine ) { // driving the avatar around should only apply is this is my avatar (as opposed to an avatar being driven remotely) + if ( _isMine ) { // driving the avatar around should only apply if this is my avatar (as opposed to an avatar being driven remotely) //------------------------------------------------- // this handles the avatar being driven around... //------------------------------------------------- @@ -411,7 +392,7 @@ void Head::simulate(float deltaTime) { } else { - _mode = AVATAR_MODE_COMMUNICATING; + _mode = AVATAR_MODE_INTERACTING; } //---------------------------------------------------------- @@ -571,6 +552,18 @@ void Head::updateBigSphereCollisionTest( float deltaTime ) { } if ( jointCollision ) { + if (!_usingBodySprings) { + _usingBodySprings = true; + initializeBodySprings(); + } + /* + else { + if (_usingSprings) { + _usingSprings = false; + } + } + */ + //---------------------------------------------------------- // add gravity to velocity //---------------------------------------------------------- @@ -648,7 +641,7 @@ void Head::render(int faceToFace) { glPopMatrix(); } - if ( _usingSprings ) { + if (_usingBodySprings) { if ( _closestOtherAvatar != -1 ) { glm::vec3 v1( _bone[ AVATAR_BONE_RIGHT_HAND ].position ); @@ -704,7 +697,7 @@ void Head::renderHead(int faceToFace) { glPushMatrix(); - if (_usingSprings) { + if (_usingBodySprings) { glTranslatef ( _bone[ AVATAR_BONE_HEAD ].springyPosition.x, @@ -862,10 +855,19 @@ void Head::renderHead(int faceToFace) { } - +void Head::startHandMovement() { -void Head::setHandMovement( glm::vec3 handOffset ) { - _handBeingMoved = true; + if (!_usingBodySprings) { + initializeBodySprings(); + _usingBodySprings = true; + } +} + +void Head::stopHandMovement() { + _usingBodySprings = false; +} + +void Head::setHandMovementValues( glm::vec3 handOffset ) { _movedHandOffset = handOffset; } @@ -873,7 +875,6 @@ AvatarMode Head::getMode() { return _mode; } - void Head::initializeSkeleton() { for (int b=0; b #include //looks like we might not need this + +// Note to self: +// modes I might need to implement for avatar +// +// walking usingSprings - ramping down +// bumping into sphere usingSprings is on +// moving hand usingSprings is on +// stuck to another hand usingSprings is on + + enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH}; #define FWD 0 @@ -40,7 +50,7 @@ enum AvatarMode { AVATAR_MODE_STANDING = 0, AVATAR_MODE_WALKING, - AVATAR_MODE_COMMUNICATING, + AVATAR_MODE_INTERACTING, NUM_AVATAR_MODES }; @@ -149,7 +159,9 @@ class Head : public AvatarData { void simulate(float); - void setHandMovement( glm::vec3 movement ); + void startHandMovement(); + void stopHandMovement(); + void setHandMovementValues( glm::vec3 movement ); void updateHandMovement(); float getLoudness() {return _loudness;}; @@ -218,9 +230,7 @@ class Head : public AvatarData { float _bodyYawDelta; float _closeEnoughToInteract; int _closestOtherAvatar; - bool _usingSprings; - bool _handBeingMoved; - bool _previousHandBeingMoved; + bool _usingBodySprings; glm::vec3 _movedHandOffset; float _springVelocityDecay; float _springForce; diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 117c94a053..cf3745fc4c 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -177,7 +177,7 @@ int mousePressed = 0; // true if mouse has been pressed (clear when finished) Menu menu; // main menu int menuOn = 1; // Whether to show onscreen menu -struct HandMovement +struct HandController { bool enabled; int startX; @@ -193,59 +193,61 @@ struct HandMovement float envelope; }; -HandMovement handMovement; +HandController handController; -void initializeHandMovement() { - handMovement.enabled = false; - handMovement.startX = WIDTH / 2; - handMovement.startY = HEIGHT / 2; - handMovement.x = 0; - handMovement.y = 0; - handMovement.lastX = 0; - handMovement.lastY = 0; - handMovement.velocityX = 0; - handMovement.velocityY = 0; - handMovement.rampUpRate = 0.05; - handMovement.rampDownRate = 0.02; - handMovement.envelope = 0.0f; +void initializeHandController() { + handController.enabled = false; + handController.startX = WIDTH / 2; + handController.startY = HEIGHT / 2; + handController.x = 0; + handController.y = 0; + handController.lastX = 0; + handController.lastY = 0; + handController.velocityX = 0; + handController.velocityY = 0; + handController.rampUpRate = 0.05; + handController.rampDownRate = 0.02; + handController.envelope = 0.0f; } -void updateHandMovement( int x, int y ) { - handMovement.lastX = handMovement.x; - handMovement.lastY = handMovement.y; - handMovement.x = x; - handMovement.y = y; - handMovement.velocityX = handMovement.x - handMovement.lastX; - handMovement.velocityY = handMovement.y - handMovement.lastY; +void updateHandController( int x, int y ) { + handController.lastX = handController.x; + handController.lastY = handController.y; + handController.x = x; + handController.y = y; + handController.velocityX = handController.x - handController.lastX; + handController.velocityY = handController.y - handController.lastY; - if (( handMovement.velocityX != 0 ) - || ( handMovement.velocityY != 0 )) { - handMovement.enabled = true; - if ( handMovement.envelope < 1.0 ) { - handMovement.envelope += handMovement.rampUpRate; - if ( handMovement.envelope >= 1.0 ) { - handMovement.envelope = 1.0; + if (( handController.velocityX != 0 ) + || ( handController.velocityY != 0 )) { + handController.enabled = true; + myAvatar.startHandMovement(); + if ( handController.envelope < 1.0 ) { + handController.envelope += handController.rampUpRate; + if ( handController.envelope >= 1.0 ) { + handController.envelope = 1.0; } } } - if ( ! handMovement.enabled ) { - if ( handMovement.envelope > 0.0 ) { - handMovement.envelope -= handMovement.rampDownRate; - if ( handMovement.envelope <= 0.0 ) { - handMovement.startX = WIDTH / 2; - handMovement.startY = HEIGHT / 2; - handMovement.envelope = 0.0; + if ( ! handController.enabled ) { + if ( handController.envelope > 0.0 ) { + handController.envelope -= handController.rampDownRate; + if ( handController.envelope <= 0.0 ) { + handController.startX = WIDTH / 2; + handController.startY = HEIGHT / 2; + handController.envelope = 0.0; + myAvatar.stopHandMovement(); } } } - if ( handMovement.envelope > 0.0 ) { - float leftRight = ( ( handMovement.x - handMovement.startX ) / (float)WIDTH ) * handMovement.envelope; - float downUp = ( ( handMovement.y - handMovement.startY ) / (float)HEIGHT ) * handMovement.envelope; + if ( handController.envelope > 0.0 ) { + float leftRight = ( ( handController.x - handController.startX ) / (float)WIDTH ) * handController.envelope; + float downUp = ( ( handController.y - handController.startY ) / (float)HEIGHT ) * handController.envelope; float backFront = 0.0; - myAvatar.setHandMovement( glm::vec3( leftRight, downUp, backFront ) ); + myAvatar.setHandMovementValues( glm::vec3( leftRight, downUp, backFront ) ); } } @@ -378,7 +380,7 @@ void init(void) voxels.setViewerHead(&myAvatar); myAvatar.setRenderYaw(startYaw); - initializeHandMovement(); + initializeHandController(); headMouseX = WIDTH/2; headMouseY = HEIGHT/2; @@ -444,22 +446,6 @@ void reset_sensors() } } -/* -void updateAvatarHand(float deltaTime) { - // If mouse is being dragged, send current force to the hand controller - if (mousePressed == 1) - { - // NOTE--PER: Need to re-implement when ready for new avatar hand movements - - const float MOUSE_HAND_FORCE = 1.5; - float dx = mouseX - mouseStartX; - float dy = mouseY - mouseStartY; - glm::vec3 vel(dx*MOUSE_HAND_FORCE, -dy*MOUSE_HAND_FORCE*(WIDTH/HEIGHT), 0); - //myAvatar.hand->addVelocity(vel*deltaTime); - } -} -*/ - // // Using gyro data, update both view frustum and avatar head position // @@ -1416,7 +1402,7 @@ void idle(void) { float deltaTime = 1.f/FPS; // update behaviors for avatar hand movement - updateHandMovement( mouseX, mouseY ); + updateHandController( mouseX, mouseY ); // when the mouse is being pressed, an 'action' is being // triggered in the avatar. The action is context-based. @@ -1427,9 +1413,9 @@ void idle(void) { myAvatar.setTriggeringAction( false ); } - // walking triggers the handMovement to stop + // walking triggers the handController to stop if ( myAvatar.getMode() == AVATAR_MODE_WALKING ) { - handMovement.enabled = false; + handController.enabled = false; } // From 06f8990d42cab394477466ac525cdbc796eb8e58 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 19 Apr 2013 14:52:06 -0700 Subject: [PATCH 06/60] removed avatar structure from Head class (leftover from the start of the prototyping phase) --- interface/src/Head.cpp | 131 ++++++++++++++++------------------------- interface/src/Head.h | 29 +++------ 2 files changed, 58 insertions(+), 102 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 442c5eefba..7cf053d0a0 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -47,9 +47,9 @@ unsigned int iris_texture_height = 256; Head::Head(bool isMine) { - _avatar.orientation.setToIdentity(); - _avatar.velocity = glm::vec3( 0.0, 0.0, 0.0 ); - _avatar.thrust = glm::vec3( 0.0, 0.0, 0.0 ); + _orientation.setToIdentity(); + _velocity = glm::vec3( 0.0, 0.0, 0.0 ); + _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; @@ -134,9 +134,9 @@ Head::Head(bool isMine) { Head::Head(const Head &otherHead) { - _avatar.orientation.set( otherHead._avatar.orientation ); - _avatar.velocity = otherHead._avatar.velocity; - _avatar.thrust = otherHead._avatar.thrust; + _orientation.set( otherHead._orientation ); + _velocity = otherHead._velocity; + _thrust = otherHead._thrust; _rotation = otherHead._rotation; _closestOtherAvatar = otherHead._closestOtherAvatar; _bodyYaw = otherHead._bodyYaw; @@ -314,7 +314,7 @@ void Head::simulate(float deltaTime) { float distance = glm::length( v ); - if ( distance < _avatar.maxArmLength ) { + if ( distance < _maxArmLength ) { if ( distance < closestDistance ) { closestDistance = distance; _closestOtherAvatar = o; @@ -348,31 +348,31 @@ void Head::simulate(float deltaTime) { //------------------------------------------------- // this handles the avatar being driven around... //------------------------------------------------- - _avatar.thrust = glm::vec3( 0.0, 0.0, 0.0 ); + _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( _orientation.getFront().x, _orientation.getFront().y, _orientation.getFront().z ); + _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( _orientation.getFront().x, _orientation.getFront().y, _orientation.getFront().z ); + _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( _orientation.getRight().x, _orientation.getRight().y, _orientation.getRight().z ); + _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( _orientation.getRight().x, _orientation.getRight().y, _orientation.getRight().z ); + _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( _orientation.getUp().x, _orientation.getUp().y, _orientation.getUp().z ); + _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( _orientation.getUp().x, _orientation.getUp().y, _orientation.getUp().z ); + _thrust -= up * THRUST_MAG; } if (_driveKeys[ROT_RIGHT]) { _bodyYawDelta -= YAW_MAG * deltaTime; @@ -384,7 +384,7 @@ void Head::simulate(float deltaTime) { //---------------------------------------------------------- - float translationalSpeed = glm::length( _avatar.velocity ); + float translationalSpeed = glm::length( _velocity ); float rotationalSpeed = fabs( _bodyYawDelta ); if ( translationalSpeed + rotationalSpeed > 0.2 ) { @@ -416,18 +416,18 @@ void Head::simulate(float deltaTime) { //---------------------------------------------------------- // add thrust to velocity //---------------------------------------------------------- - _avatar.velocity += glm::dvec3(_avatar.thrust * deltaTime); + _velocity += glm::dvec3(_thrust * deltaTime); //---------------------------------------------------------- // update position by velocity //---------------------------------------------------------- - _bodyPosition += (glm::vec3)_avatar.velocity * deltaTime; + _bodyPosition += (glm::vec3)_velocity * deltaTime; //---------------------------------------------------------- // decay velocity //---------------------------------------------------------- const float LIN_VEL_DECAY = 5.0; - _avatar.velocity *= ( 1.0 - LIN_VEL_DECAY * deltaTime ); + _velocity *= ( 1.0 - LIN_VEL_DECAY * deltaTime ); if (!_noise) { // Decay back toward center @@ -546,7 +546,7 @@ void Head::updateBigSphereCollisionTest( float deltaTime ) { float amp = 1.0 - (distanceToBigSphereCenter / combinedRadius); glm::vec3 collisionForce = vectorFromJointToBigSphere * amp; _bone[b].springyVelocity += collisionForce * 8.0f * deltaTime; - _avatar.velocity += collisionForce * 18.0f * deltaTime; + _velocity += collisionForce * 18.0f * deltaTime; } } } @@ -567,15 +567,15 @@ void Head::updateBigSphereCollisionTest( float deltaTime ) { //---------------------------------------------------------- // add gravity to velocity //---------------------------------------------------------- - _avatar.velocity += glm::dvec3( 0.0, -1.0, 0.0 ) * 0.05; + _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; + if ( _velocity.y < 0.0 ) { + _velocity.y *= -0.7; } } } @@ -658,35 +658,6 @@ void Head::render(int faceToFace) { } } - - -//this has been moved to Utils.cpp -/* -void Head::renderOrientationDirections( glm::vec3 position, Orientation orientation, float size ) { - glm::vec3 pRight = position + orientation.right * size; - glm::vec3 pUp = position + orientation.up * size; - glm::vec3 pFront = position + orientation.front * size; - - glColor3f( 1.0f, 0.0f, 0.0f ); - glBegin( GL_LINE_STRIP ); - glVertex3f( position.x, position.y, position.z ); - glVertex3f( pRight.x, pRight.y, pRight.z ); - glEnd(); - - glColor3f( 0.0f, 1.0f, 0.0f ); - glBegin( GL_LINE_STRIP ); - glVertex3f( position.x, position.y, position.z ); - glVertex3f( pUp.x, pUp.y, pUp.z ); - glEnd(); - - glColor3f( 0.0f, 0.0f, 1.0f ); - glBegin( GL_LINE_STRIP ); - glVertex3f( position.x, position.y, position.z ); - glVertex3f( pFront.x, pFront.y, pFront.z ); - glEnd(); -} -*/ - void Head::renderHead(int faceToFace) { @@ -986,7 +957,7 @@ void Head::calculateBoneLengths() { _bone[b].length = glm::length( _bone[b].defaultPosePosition ); } - _avatar.maxArmLength + _maxArmLength = _bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].length + _bone[ AVATAR_BONE_RIGHT_FOREARM ].length + _bone[ AVATAR_BONE_RIGHT_HAND ].length; @@ -996,13 +967,13 @@ void Head::updateSkeleton() { //---------------------------------- // rotate body... //---------------------------------- - _avatar.orientation.setToIdentity(); - _avatar.orientation.yaw( _bodyYaw ); + _orientation.setToIdentity(); + _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, _orientation.up ); - //glm::quat yaw_rotation = glm::angleAxis( _bodyYaw, _avatar.orientation.up ); + //glm::quat yaw_rotation = glm::angleAxis( _bodyYaw, _orientation.up ); //------------------------------------------------------------------------ @@ -1010,7 +981,7 @@ void Head::updateSkeleton() { //------------------------------------------------------------------------ for (int b=0; b _avatar.maxArmLength ) { + if ( distance > _maxArmLength ) { //------------------------------------------------------------------------------- // reset right hand to be constrained to maximum arm length //------------------------------------------------------------------------------- _bone[ AVATAR_BONE_RIGHT_HAND ].position = _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position; glm::vec3 armNormal = armVector / distance; - armVector = armNormal * _avatar.maxArmLength; - distance = _avatar.maxArmLength; + armVector = armNormal * _maxArmLength; + distance = _maxArmLength; glm::vec3 constrainedPosition = _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position; constrainedPosition += armVector; _bone[ AVATAR_BONE_RIGHT_HAND ].position = constrainedPosition; @@ -1200,9 +1171,9 @@ void Head::updateHandMovement() { //----------------------------------------------------------------------------- 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( _orientation.getFront(), armVector ); - newElbowPosition += perpendicular * ( 1.0f - ( _avatar.maxArmLength / distance ) ) * ONE_HALF; + newElbowPosition += perpendicular * ( 1.0f - ( _maxArmLength / distance ) ) * ONE_HALF; _bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].position = newElbowPosition; //----------------------------------------------------------------------------- diff --git a/interface/src/Head.h b/interface/src/Head.h index 554ab3eafe..9ab60f2e73 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -22,16 +22,6 @@ #include #include //looks like we might not need this - -// Note to self: -// modes I might need to implement for avatar -// -// walking usingSprings - ramping down -// bumping into sphere usingSprings is on -// moving hand usingSprings is on -// stuck to another hand usingSprings is on - - enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH}; #define FWD 0 @@ -101,14 +91,6 @@ struct AvatarBone float radius; // used for detecting collisions for certain physical effects }; -struct Avatar -{ - glm::dvec3 velocity; - glm::vec3 thrust; - float maxArmLength; - Orientation orientation; -}; - class Head : public AvatarData { public: Head(bool isMine); @@ -176,9 +158,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) { _thrust = newThrust; }; + void addThrust(glm::vec3 newThrust) { _thrust += newThrust; }; + glm::vec3 getThrust() { return _thrust; }; // // Related to getting transmitter UDP data used to animate the avatar hand @@ -237,7 +219,10 @@ class Head : public AvatarData { glm::quat _rotation; // the rotation of the avatar body as a whole AvatarBone _bone[ NUM_AVATAR_BONES ]; AvatarMode _mode; - Avatar _avatar; + glm::dvec3 _velocity; + glm::vec3 _thrust; + float _maxArmLength; + Orientation _orientation; int _driveKeys[MAX_DRIVE_KEYS]; int _eyeContact; eyeContactTargets _eyeContactTarget; From 08105c38985c3e833457ac1e684e2cec1cadfedd Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Fri, 19 Apr 2013 17:09:28 -0700 Subject: [PATCH 07/60] I did a major cleanup of the Head class, including putting all the "head"-related members into a single structure. We may consider making a separate class just to handle the head. --- interface/src/Head.cpp | 408 ++++++++++++++++++++++------------------- interface/src/Head.h | 139 +++++++------- 2 files changed, 293 insertions(+), 254 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 7cf053d0a0..821ff2e111 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -48,8 +48,8 @@ unsigned int iris_texture_height = 256; Head::Head(bool isMine) { _orientation.setToIdentity(); - _velocity = glm::vec3( 0.0, 0.0, 0.0 ); - _thrust = glm::vec3( 0.0, 0.0, 0.0 ); + _velocity = glm::vec3( 0.0, 0.0, 0.0 ); + _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; @@ -59,6 +59,10 @@ Head::Head(bool isMine) { _triggeringAction = false; _mode = AVATAR_MODE_STANDING; _isMine = isMine; + _maxArmLength = 0.0; + //_transmitterTimer = 0; + _transmitterHz = 0.0; + _transmitterPackets = 0; initializeSkeleton(); @@ -67,47 +71,53 @@ Head::Head(bool isMine) { for (int i = 0; i < MAX_DRIVE_KEYS; i++) _driveKeys[i] = false; - _pupilSize = 0.10; - _interPupilDistance = 0.6; - _interBrowDistance = 0.75; - _nominalPupilSize = 0.10; - _headYaw = 0.0; - _eyebrowPitch[0] = -30; - _eyebrowPitch[1] = -30; - _eyebrowRoll [0] = 20; - _eyebrowRoll [1] = -20; - _mouthPitch = 0; - _mouthYaw = 0; - _mouthWidth = 1.0; - _mouthHeight = 0.2; - _eyeballPitch[0] = 0; - _eyeballPitch[1] = 0; - _eyeballScaleX = 1.2; - _eyeballScaleY = 1.5; - _eyeballScaleZ = 1.0; - _eyeballYaw[0] = 0; - _eyeballYaw[1] = 0; - _pitchTarget = 0; - _yawTarget = 0; - _noiseEnvelope = 1.0; - _pupilConverge = 10.0; - _leanForward = 0.0; - _leanSideways = 0.0; - _eyeContact = 1; - _eyeContactTarget = LEFT_EYE; - _scale = 1.0; - _renderYaw = 0.0; - _renderPitch = 0.0; - _audioAttack = 0.0; - _loudness = 0.0; - _averageLoudness = 0.0; - _lastLoudness = 0.0; - _browAudioLift = 0.0; - _noise = 0; - _movedHandOffset = glm::vec3( 0.0, 0.0, 0.0 ); - _usingBodySprings = false; - _springForce = 6.0f; - _springVelocityDecay = 16.0f; + _head.pupilSize = 0.10; + _head.interPupilDistance = 0.6; + _head.interBrowDistance = 0.75; + _head.nominalPupilSize = 0.10; + _head.yaw = 0.0; + _head.pitch = 0.0; + _head.roll = 0.0; + _head.pitchRate = 0.0; + _head.yawRate = 0.0; + _head.rollRate = 0.0; + _head.eyebrowPitch[0] = -30; + _head.eyebrowPitch[1] = -30; + _head.eyebrowRoll [0] = 20; + _head.eyebrowRoll [1] = -20; + _head.mouthPitch = 0; + _head.mouthYaw = 0; + _head.mouthWidth = 1.0; + _head.mouthHeight = 0.2; + _head.eyeballPitch[0] = 0; + _head.eyeballPitch[1] = 0; + _head.eyeballScaleX = 1.2; + _head.eyeballScaleY = 1.5; + _head.eyeballScaleZ = 1.0; + _head.eyeballYaw[0] = 0; + _head.eyeballYaw[1] = 0; + _head.pitchTarget = 0; + _head.yawTarget = 0; + _head.noiseEnvelope = 1.0; + _head.pupilConverge = 10.0; + _head.leanForward = 0.0; + _head.leanSideways = 0.0; + _head.eyeContact = 1; + _head.eyeContactTarget = LEFT_EYE; + _head.scale = 1.0; + _head.audioAttack = 0.0; + _head.loudness = 0.0; + _head.averageLoudness = 0.0; + _head.lastLoudness = 0.0; + _head.browAudioLift = 0.0; + _head.noise = 0; + + _movedHandOffset = glm::vec3( 0.0, 0.0, 0.0 ); + _usingBodySprings = false; + _springForce = 6.0f; + _springVelocityDecay = 16.0f; + _renderYaw = 0.0; + _renderPitch = 0.0; _sphere = NULL; @@ -119,77 +129,103 @@ Head::Head(bool isMine) { } } - if (_isMine) - { - //-------------------------------------------------- - // test... just slam them into random positions... - //-------------------------------------------------- - _DEBUG_otherAvatarListPosition[ 0 ] = glm::vec3( 0.0f, 0.3f, 2.0f ); - _DEBUG_otherAvatarListPosition[ 1 ] = glm::vec3( 4.0f, 0.3f, 2.0f ); - _DEBUG_otherAvatarListPosition[ 2 ] = glm::vec3( 2.0f, 0.3f, 2.0f ); - _DEBUG_otherAvatarListPosition[ 3 ] = glm::vec3( 1.0f, 0.3f, -4.0f ); - _DEBUG_otherAvatarListPosition[ 4 ] = glm::vec3( -2.0f, 0.3f, -2.0f ); - } + //-------------------------------------------------- + // test... just slam them into random positions... + //-------------------------------------------------- + _DEBUG_otherAvatarListPosition[ 0 ] = glm::vec3( 0.0f, 0.3f, 2.0f ); + _DEBUG_otherAvatarListPosition[ 1 ] = glm::vec3( 4.0f, 0.3f, 2.0f ); + _DEBUG_otherAvatarListPosition[ 2 ] = glm::vec3( 2.0f, 0.3f, 2.0f ); + _DEBUG_otherAvatarListPosition[ 3 ] = glm::vec3( 1.0f, 0.3f, -4.0f ); + _DEBUG_otherAvatarListPosition[ 4 ] = glm::vec3( -2.0f, 0.3f, -2.0f ); } -Head::Head(const Head &otherHead) { +Head::Head(const Head &otherAvatar) { + + _velocity = otherAvatar._velocity; + _thrust = otherAvatar._thrust; + _rotation = otherAvatar._rotation; + _closestOtherAvatar = otherAvatar._closestOtherAvatar; + _bodyYaw = otherAvatar._bodyYaw; + _bodyPitch = otherAvatar._bodyPitch; + _bodyRoll = otherAvatar._bodyRoll; + _bodyYawDelta = otherAvatar._bodyYawDelta; + _triggeringAction = otherAvatar._triggeringAction; + _mode = otherAvatar._mode; + _isMine = otherAvatar._isMine; + _renderYaw = otherAvatar._renderYaw; + _renderPitch = otherAvatar._renderPitch; + _maxArmLength = otherAvatar._maxArmLength; + _transmitterTimer = otherAvatar._transmitterTimer; + _transmitterHz = otherAvatar._transmitterHz; + _transmitterPackets = otherAvatar._transmitterPackets; + _TEST_bigSphereRadius = otherAvatar._TEST_bigSphereRadius; + _TEST_bigSpherePosition = otherAvatar._TEST_bigSpherePosition; + _movedHandOffset = otherAvatar._movedHandOffset; + _usingBodySprings = otherAvatar._usingBodySprings; + _springForce = otherAvatar._springForce; + _springVelocityDecay = otherAvatar._springVelocityDecay; + + _orientation.set( otherAvatar._orientation ); - _orientation.set( otherHead._orientation ); - _velocity = otherHead._velocity; - _thrust = otherHead._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; + //for (int o=0;ogetRelativeValue(HEAD_PITCH_RATE); - _headYawRate = serialInterface->getRelativeValue(HEAD_YAW_RATE); + _head.yawRate = serialInterface->getRelativeValue(HEAD_YAW_RATE); float measured_lateral_accel = serialInterface->getRelativeValue(ACCEL_X) - ROLL_ACCEL_COUPLING*serialInterface->getRelativeValue(HEAD_ROLL_RATE); float measured_fwd_accel = serialInterface->getRelativeValue(ACCEL_Z) - @@ -238,35 +274,35 @@ void Head::UpdateGyros(float frametime, SerialInterface * serialInterface, int h const float MAX_YAW = 85; const float MIN_YAW = -85; - if ((_headPitch < MAX_PITCH) && (_headPitch > MIN_PITCH)) + if ((_head.pitch < MAX_PITCH) && (_head.pitch > MIN_PITCH)) addPitch(measured_pitch_rate * -HEAD_ROTATION_SCALE * frametime); addRoll(-measured_roll_rate * HEAD_ROLL_SCALE * frametime); if (head_mirror) { - if ((_headYaw < MAX_YAW) && (_headYaw > MIN_YAW)) - addYaw(-_headYawRate * HEAD_ROTATION_SCALE * frametime); + if ((_head.yaw < MAX_YAW) && (_head.yaw > MIN_YAW)) + addYaw(-_head.yawRate * HEAD_ROTATION_SCALE * frametime); addLean(-measured_lateral_accel * frametime * HEAD_LEAN_SCALE, -measured_fwd_accel*frametime * HEAD_LEAN_SCALE); } else { - if ((_headYaw < MAX_YAW) && (_headYaw > MIN_YAW)) - addYaw(_headYawRate * -HEAD_ROTATION_SCALE * frametime); + if ((_head.yaw < MAX_YAW) && (_head.yaw > MIN_YAW)) + addYaw(_head.yawRate * -HEAD_ROTATION_SCALE * frametime); addLean(measured_lateral_accel * frametime * -HEAD_LEAN_SCALE, measured_fwd_accel*frametime * HEAD_LEAN_SCALE); } } void Head::addLean(float x, float z) { // Add Body lean as impulse - _leanSideways += x; - _leanForward += z; + _head.leanSideways += x; + _head.leanForward += z; } void Head::setLeanForward(float dist){ - _leanForward = dist; + _head.leanForward = dist; } void Head::setLeanSideways(float dist){ - _leanSideways = dist; + _head.leanSideways = dist; } void Head::setTriggeringAction( bool d ) { @@ -403,9 +439,9 @@ void Head::simulate(float deltaTime) { } // we will be eventually getting head rotation from elsewhere. For now, just setting it to body rotation - _headYaw = _bodyYaw; - _headPitch = _bodyPitch; - _headRoll = _bodyRoll; + _head.yaw = _bodyYaw; + _head.pitch = _bodyPitch; + _head.roll = _bodyRoll; //---------------------------------------------------------- // decay body yaw delta @@ -429,32 +465,32 @@ void Head::simulate(float deltaTime) { const float LIN_VEL_DECAY = 5.0; _velocity *= ( 1.0 - LIN_VEL_DECAY * deltaTime ); - if (!_noise) { + if (!_head.noise) { // Decay back toward center - _headPitch *= (1.0f - DECAY*2*deltaTime); - _headYaw *= (1.0f - DECAY*2*deltaTime); - _headRoll *= (1.0f - DECAY*2*deltaTime); + _head.pitch *= (1.0f - DECAY*2*deltaTime); + _head.yaw *= (1.0f - DECAY*2*deltaTime); + _head.roll *= (1.0f - DECAY*2*deltaTime); } else { // Move toward new target - _headPitch += (_pitchTarget - _headPitch)*10*deltaTime; // (1.f - DECAY*deltaTime)*Pitch + ; - _headYaw += (_yawTarget - _headYaw)*10*deltaTime; // (1.f - DECAY*deltaTime); - _headRoll *= (1.f - DECAY*deltaTime); + _head.pitch += (_head.pitchTarget - _head.pitch)*10*deltaTime; // (1.f - DECAY*deltaTime)*Pitch + ; + _head.yaw += (_head.yawTarget - _head.yaw )*10*deltaTime; // (1.f - DECAY*deltaTime); + _head.roll *= (1.f - DECAY*deltaTime); } - _leanForward *= (1.f - DECAY*30.f*deltaTime); - _leanSideways *= (1.f - DECAY*30.f*deltaTime); + _head.leanForward *= (1.f - DECAY*30.f*deltaTime); + _head.leanSideways *= (1.f - DECAY*30.f*deltaTime); // Update where the avatar's eyes are // // First, decide if we are making eye contact or not if (randFloat() < 0.005) { - _eyeContact = !_eyeContact; - _eyeContact = 1; - if (!_eyeContact) { + _head.eyeContact = !_head.eyeContact; + _head.eyeContact = 1; + if (!_head.eyeContact) { // If we just stopped making eye contact,move the eyes markedly away - _eyeballPitch[0] = _eyeballPitch[1] = _eyeballPitch[0] + 5.0 + (randFloat() - 0.5)*10; - _eyeballYaw[0] = _eyeballYaw[1] = _eyeballYaw[0] + 5.0 + (randFloat()- 0.5)*5; + _head.eyeballPitch[0] = _head.eyeballPitch[1] = _head.eyeballPitch[0] + 5.0 + (randFloat() - 0.5)*10; + _head.eyeballYaw [0] = _head.eyeballYaw [1] = _head.eyeballYaw [0] + 5.0 + (randFloat() - 0.5)*5; } else { // If now making eye contact, turn head to look right at viewer SetNewHeadTarget(0,0); @@ -464,56 +500,56 @@ void Head::simulate(float deltaTime) { const float DEGREES_BETWEEN_VIEWER_EYES = 3; const float DEGREES_TO_VIEWER_MOUTH = 7; - if (_eyeContact) { + if (_head.eyeContact) { // Should we pick a new eye contact target? if (randFloat() < 0.01) { // Choose where to look next if (randFloat() < 0.1) { - _eyeContactTarget = MOUTH; + _head.eyeContactTarget = MOUTH; } else { - if (randFloat() < 0.5) _eyeContactTarget = LEFT_EYE; else _eyeContactTarget = RIGHT_EYE; + if (randFloat() < 0.5) _head.eyeContactTarget = LEFT_EYE; else _head.eyeContactTarget = RIGHT_EYE; } } // Set eyeball pitch and yaw to make contact float eye_target_yaw_adjust = 0; float eye_target_pitch_adjust = 0; - if (_eyeContactTarget == LEFT_EYE) eye_target_yaw_adjust = DEGREES_BETWEEN_VIEWER_EYES; - if (_eyeContactTarget == RIGHT_EYE) eye_target_yaw_adjust = -DEGREES_BETWEEN_VIEWER_EYES; - if (_eyeContactTarget == MOUTH) eye_target_pitch_adjust = DEGREES_TO_VIEWER_MOUTH; + if (_head.eyeContactTarget == LEFT_EYE) eye_target_yaw_adjust = DEGREES_BETWEEN_VIEWER_EYES; + if (_head.eyeContactTarget == RIGHT_EYE) eye_target_yaw_adjust = -DEGREES_BETWEEN_VIEWER_EYES; + if (_head.eyeContactTarget == MOUTH) eye_target_pitch_adjust = DEGREES_TO_VIEWER_MOUTH; - _eyeballPitch[0] = _eyeballPitch[1] = -_headPitch + eye_target_pitch_adjust; - _eyeballYaw[0] = _eyeballYaw[1] = -_headYaw + eye_target_yaw_adjust; + _head.eyeballPitch[0] = _head.eyeballPitch[1] = -_head.pitch + eye_target_pitch_adjust; + _head.eyeballYaw[0] = _head.eyeballYaw[1] = -_head.yaw + eye_target_yaw_adjust; } - if (_noise) + if (_head.noise) { - _headPitch += (randFloat() - 0.5)*0.2*_noiseEnvelope; - _headYaw += (randFloat() - 0.5)*0.3*_noiseEnvelope; + _head.pitch += (randFloat() - 0.5)*0.2*_head.noiseEnvelope; + _head.yaw += (randFloat() - 0.5)*0.3*_head.noiseEnvelope; //PupilSize += (randFloat() - 0.5)*0.001*NoiseEnvelope; - if (randFloat() < 0.005) _mouthWidth = MouthWidthChoices[rand()%3]; + if (randFloat() < 0.005) _head.mouthWidth = MouthWidthChoices[rand()%3]; - if (!_eyeContact) { - if (randFloat() < 0.01) _eyeballPitch[0] = _eyeballPitch[1] = (randFloat() - 0.5)*20; - if (randFloat() < 0.01) _eyeballYaw[0] = _eyeballYaw[1] = (randFloat()- 0.5)*10; + if (!_head.eyeContact) { + if (randFloat() < 0.01) _head.eyeballPitch[0] = _head.eyeballPitch[1] = (randFloat() - 0.5)*20; + if (randFloat() < 0.01) _head.eyeballYaw[0] = _head.eyeballYaw[1] = (randFloat()- 0.5)*10; } - if ((randFloat() < 0.005) && (fabs(_pitchTarget - _headPitch) < 1.0) && (fabs(_yawTarget - _headYaw) < 1.0)) { + if ((randFloat() < 0.005) && (fabs(_head.pitchTarget - _head.pitch) < 1.0) && (fabs(_head.yawTarget - _head.yaw) < 1.0)) { SetNewHeadTarget((randFloat()-0.5)*20.0, (randFloat()-0.5)*45.0); } if (0) { // Pick new target - _pitchTarget = (randFloat() - 0.5)*45; - _yawTarget = (randFloat() - 0.5)*22; + _head.pitchTarget = (randFloat() - 0.5)*45; + _head.yawTarget = (randFloat() - 0.5)*22; } if (randFloat() < 0.01) { - _eyebrowPitch[0] = _eyebrowPitch[1] = BrowPitchAngle[rand()%3]; - _eyebrowRoll[0] = _eyebrowRoll[1] = BrowRollAngle[rand()%5]; - _eyebrowRoll[1]*=-1; + _head.eyebrowPitch[0] = _head.eyebrowPitch[1] = BrowPitchAngle[rand()%3]; + _head.eyebrowRoll [0] = _head.eyebrowRoll[1] = BrowRollAngle[rand()%5]; + _head.eyebrowRoll [1]*=-1; } } } @@ -688,9 +724,9 @@ void Head::renderHead(int faceToFace) { glScalef( 0.03, 0.03, 0.03 ); - glRotatef(_headYaw, 0, 1, 0); - glRotatef(_headPitch, 1, 0, 0); - glRotatef(_headRoll, 0, 0, 1); + glRotatef(_head.yaw, 0, 1, 0); + glRotatef(_head.pitch, 1, 0, 0); + glRotatef(_head.roll, 0, 0, 1); // Overall scale of head if (faceToFace) glScalef(2.0, 2.0, 2.0); @@ -719,27 +755,27 @@ void Head::renderHead(int faceToFace) { glPopMatrix(); // _eyebrows - _audioAttack = 0.9*_audioAttack + 0.1*fabs(_loudness - _lastLoudness); - _lastLoudness = _loudness; + _head.audioAttack = 0.9*_head.audioAttack + 0.1*fabs(_head.loudness - _head.lastLoudness); + _head.lastLoudness = _head.loudness; const float BROW_LIFT_THRESHOLD = 100; - if (_audioAttack > BROW_LIFT_THRESHOLD) - _browAudioLift += sqrt(_audioAttack)/1000.0; + if (_head.audioAttack > BROW_LIFT_THRESHOLD) + _head.browAudioLift += sqrt(_head.audioAttack)/1000.0; - _browAudioLift *= .90; + _head.browAudioLift *= .90; glPushMatrix(); - glTranslatef(-_interBrowDistance/2.0,0.4,0.45); + glTranslatef(-_head.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); + glTranslatef(0, 0.35 + _head.browAudioLift, 0); + glRotatef(_head.eyebrowPitch[side]/2.0, 1, 0, 0); + glRotatef(_head.eyebrowRoll[side]/2.0, 0, 0, 1); glScalef(browWidth, browThickness, 1); glutSolidCube(0.5); glPopMatrix(); - glTranslatef(_interBrowDistance, 0, 0); + glTranslatef(_head.interBrowDistance, 0, 0); } glPopMatrix(); @@ -749,23 +785,23 @@ void Head::renderHead(int faceToFace) { 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); + glRotatef(_head.mouthPitch, 1, 0, 0); + glRotatef(_head.mouthYaw, 0, 0, 1); + glScalef(_head.mouthWidth*(.7 + sqrt(_head.averageLoudness)/60.0), _head.mouthHeight*(1.0 + sqrt(_head.averageLoudness)/30.0), 1); glutSolidCube(0.5); glPopMatrix(); glTranslatef(0, 1.0, 0); - glTranslatef(-_interPupilDistance/2.0,-0.68,0.7); + glTranslatef(-_head.interPupilDistance/2.0,-0.68,0.7); // Right Eye glRotatef(-10, 1, 0, 0); glColor3fv(eyeColor); glPushMatrix(); { - glTranslatef(_interPupilDistance/10.0, 0, 0.05); + glTranslatef(_head.interPupilDistance/10.0, 0, 0.05); glRotatef(20, 0, 0, 1); - glScalef(_eyeballScaleX, _eyeballScaleY, _eyeballScaleZ); + glScalef(_head.eyeballScaleX, _head.eyeballScaleY, _head.eyeballScaleZ); glutSolidSphere(0.25, 30, 30); } glPopMatrix(); @@ -782,40 +818,40 @@ void Head::renderHead(int faceToFace) { glPushMatrix(); { - glRotatef(_eyeballPitch[1], 1, 0, 0); - glRotatef(_eyeballYaw[1] + _pupilConverge, 0, 1, 0); + glRotatef(_head.eyeballPitch[1], 1, 0, 0); + glRotatef(_head.eyeballYaw[1] + _head.yaw + _head.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); + gluSphere(_sphere, _head.pupilSize, 15, 15); glDisable(GL_TEXTURE_2D); } glPopMatrix(); // Left Eye glColor3fv(eyeColor); - glTranslatef(_interPupilDistance, 0, 0); + glTranslatef(_head.interPupilDistance, 0, 0); glPushMatrix(); { - glTranslatef(-_interPupilDistance/10.0, 0, .05); + glTranslatef(-_head.interPupilDistance/10.0, 0, .05); glRotatef(-20, 0, 0, 1); - glScalef(_eyeballScaleX, _eyeballScaleY, _eyeballScaleZ); + glScalef(_head.eyeballScaleX, _head.eyeballScaleY, _head.eyeballScaleZ); glutSolidSphere(0.25, 30, 30); } glPopMatrix(); // Left Pupil glPushMatrix(); { - glRotatef(_eyeballPitch[0], 1, 0, 0); - glRotatef(_eyeballYaw[0] - _pupilConverge, 0, 1, 0); + glRotatef(_head.eyeballPitch[0], 1, 0, 0); + glRotatef(_head.eyeballYaw[0] + _head.yaw - _head.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); + gluSphere(_sphere, _head.pupilSize, 15, 15); glDisable(GL_TEXTURE_2D); } @@ -1260,8 +1296,8 @@ void Head::renderBody() { } void Head::SetNewHeadTarget(float pitch, float yaw) { - _pitchTarget = pitch; - _yawTarget = yaw; + _head.pitchTarget = pitch; + _head.yawTarget = yaw; } // getting data from Android transmitte app diff --git a/interface/src/Head.h b/interface/src/Head.h index 9ab60f2e73..72cf750d69 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -91,6 +91,48 @@ struct AvatarBone float radius; // used for detecting collisions for certain physical effects }; +struct AvatarHead +{ + float pitch; + float yaw; + float roll; + float pitchRate; + float yawRate; + float rollRate; + float noise; + float eyeballPitch[2]; + float eyeballYaw [2]; + float eyebrowPitch[2]; + float eyebrowRoll [2]; + float eyeballScaleX; + float eyeballScaleY; + float eyeballScaleZ; + float interPupilDistance; + float interBrowDistance; + float nominalPupilSize; + float pupilSize; + float mouthPitch; + float mouthYaw; + float mouthWidth; + float mouthHeight; + float leanForward; + float leanSideways; + float pitchTarget; + float yawTarget; + float noiseEnvelope; + float pupilConverge; + float scale; + int eyeContact; + float browAudioLift; + eyeContactTargets eyeContactTarget; + + // Sound loudness information + float loudness, lastLoudness; + float averageLoudness; + float audioAttack; +}; + + class Head : public AvatarData { public: Head(bool isMine); @@ -98,30 +140,29 @@ class Head : public AvatarData { Head(const Head &otherHead); Head* clone() const; - void reset(); - void UpdateGyros(float frametime, SerialInterface * serialInterface, int head_mirror, glm::vec3 * gravity); - void setNoise (float mag) { _noise = mag; } - 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;} + void reset(); + void UpdateGyros(float frametime, SerialInterface * serialInterface, int head_mirror, glm::vec3 * gravity); + void setNoise (float mag) { _head.noise = mag; } + void setPitch(float p) {_head.pitch = p; } + void setYaw(float y) {_head.yaw = y; } + void setRoll(float r) {_head.roll = r; }; + void setScale(float s) {_head.scale = s; }; + void setRenderYaw(float y) {_renderYaw = y;} + void setRenderPitch(float p) {_renderPitch = p;} float getRenderYaw() {return _renderYaw;} float getRenderPitch() {return _renderPitch;} - void setLeanForward(float dist); - void setLeanSideways(float dist); - 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 _headPitch;} - float getRoll() {return _headRoll;} - float getYaw() {return _headYaw;} - float getLastMeasuredYaw() {return _headYawRate;} - + void setLeanForward(float dist); + void setLeanSideways(float dist); + void addPitch(float p) {_head.pitch -= p; } + void addYaw(float y){_head.yaw -= y; } + void addRoll(float r){_head.roll += r; } + void addLean(float x, float z); + float getPitch() {return _head.pitch;} + float getRoll() {return _head.roll;} + float getYaw() {return _head.yaw;} + float getLastMeasuredYaw() {return _head.yawRate;} float getBodyYaw() {return _bodyYaw;}; - void addBodyYaw(float y) {_bodyYaw += y;}; + void addBodyYaw(float y) {_bodyYaw += y;}; glm::vec3 getHeadLookatDirection(); glm::vec3 getHeadLookatDirectionUp(); @@ -137,7 +178,6 @@ class Head : public AvatarData { void renderBody(); void renderHead( int faceToFace); - //void renderOrientationDirections( glm::vec3 position, Orientation orientation, float size ); void simulate(float); @@ -146,10 +186,10 @@ class Head : public AvatarData { void setHandMovementValues( glm::vec3 movement ); void updateHandMovement(); - float getLoudness() {return _loudness;}; - float getAverageLoudness() {return _averageLoudness;}; - void setAverageLoudness(float al) {_averageLoudness = al;}; - void setLoudness(float l) {_loudness = l;}; + float getLoudness() {return _head.loudness;}; + float getAverageLoudness() {return _head.averageLoudness;}; + void setAverageLoudness(float al) {_head.averageLoudness = al;}; + void setLoudness(float l) {_head.loudness = l;}; void SetNewHeadTarget(float, float); @@ -170,41 +210,8 @@ class Head : public AvatarData { float getTransmitterHz() { return _transmitterHz; }; private: - bool _isMine; - float _noise; - float _headPitch; - float _headYaw; - float _headRoll; - float _headPitchRate; - float _headYawRate; - float _headRollRate; - float _eyeballPitch[2]; - float _eyeballYaw[2]; - float _eyebrowPitch[2]; - float _eyebrowRoll[2]; - float _eyeballScaleX, _eyeballScaleY, _eyeballScaleZ; - float _interPupilDistance; - float _interBrowDistance; - float _nominalPupilSize; - float _pupilSize; - float _mouthPitch; - float _mouthYaw; - float _mouthWidth; - float _mouthHeight; - float _leanForward; - float _leanSideways; - float _pitchTarget; - float _yawTarget; - float _noiseEnvelope; - float _pupilConverge; - float _scale; - - // Sound loudness information - float _loudness, _lastLoudness; - float _averageLoudness; - float _audioAttack; - float _browAudioLift; - + AvatarHead _head; + bool _isMine; glm::vec3 _TEST_bigSpherePosition; float _TEST_bigSphereRadius; glm::vec3 _DEBUG_otherAvatarListPosition[ NUM_OTHER_AVATARS ]; @@ -224,13 +231,9 @@ class Head : public AvatarData { float _maxArmLength; Orientation _orientation; int _driveKeys[MAX_DRIVE_KEYS]; - int _eyeContact; - eyeContactTargets _eyeContactTarget; - - GLUquadric *_sphere; - - float _renderYaw; - float _renderPitch; // Pitch from view frustum when this is own head. + GLUquadric* _sphere; + float _renderYaw; + float _renderPitch; // Pitch from view frustum when this is own head. // // Related to getting transmitter UDP data used to animate the avatar hand From 9c601cedd06bc516ac6c100efdf980decc99cb55 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 19 Apr 2013 18:05:38 -0700 Subject: [PATCH 08/60] Adding support for false color to voxel nodes, also added AABox to get voxel bounding box --- libraries/voxels/src/VoxelNode.cpp | 88 +++++++++++++++++++++++------- libraries/voxels/src/VoxelNode.h | 21 ++++++- 2 files changed, 87 insertions(+), 22 deletions(-) diff --git a/libraries/voxels/src/VoxelNode.cpp b/libraries/voxels/src/VoxelNode.cpp index 5f36ad9e59..7cae90f744 100644 --- a/libraries/voxels/src/VoxelNode.cpp +++ b/libraries/voxels/src/VoxelNode.cpp @@ -6,17 +6,21 @@ // // +#include #include #include "SharedUtil.h" //#include "voxels_Log.h" #include "VoxelNode.h" #include "OctalCode.h" +#include "AABox.h" // using voxels_lib::printLog; VoxelNode::VoxelNode() { octalCode = NULL; + _falseColored = false; // assume true color + // default pointers to child nodes to NULL for (int i = 0; i < 8; i++) { children[i] = NULL; @@ -28,10 +32,21 @@ VoxelNode::~VoxelNode() { // delete all of this node's children for (int i = 0; i < 8; i++) { - delete children[i]; + if (children[i]) { + delete children[i]; + } } } +void VoxelNode::getAABox(AABox& box) const { + // copy corner into box + copyFirstVertexForCode(octalCode,(float*)&box.corner); + + // this tells you the "size" of the voxel + float voxelScale = 1 / powf(2, *octalCode); + box.x = box.y = box.z = voxelScale; +} + void VoxelNode::addChildAtIndex(int childIndex) { children[childIndex] = new VoxelNode(); @@ -43,28 +58,54 @@ void VoxelNode::addChildAtIndex(int childIndex) { void VoxelNode::setColorFromAverageOfChildren() { int colorArray[4] = {0,0,0,0}; for (int i = 0; i < 8; i++) { - if (children[i] != NULL && children[i]->color[3] == 1) { + if (children[i] != NULL && children[i]->isColored()) { for (int j = 0; j < 3; j++) { - colorArray[j] += children[i]->color[j]; + colorArray[j] += children[i]->getTrueColor()[j]; // color averaging should always be based on true colors } colorArray[3]++; } } + nodeColor newColor = { 0, 0, 0, 0}; if (colorArray[3] > 4) { // we need at least 4 colored children to have an average color value // or if we have none we generate random values for (int c = 0; c < 3; c++) { // set the average color value - color[c] = colorArray[c] / colorArray[3]; + newColor[c] = colorArray[c] / colorArray[3]; } // set the alpha to 1 to indicate that this isn't transparent - color[3] = 1; - } else { - // some children, but not enough - // set this node's alpha to 0 - color[3] = 0; - } + newColor[3] = 1; + } + // actually set our color, note, if we didn't have enough children + // this will be the default value all zeros, and therefore be marked as + // transparent with a 4th element of 0 + setColor(newColor); +} + +void VoxelNode::setFalseColor(colorPart red, colorPart green, colorPart blue) { + _falseColored=true; + _currentColor[0] = red; + _currentColor[1] = green; + _currentColor[2] = blue; + _currentColor[3] = 1; // XXXBHG - False colors are always considered set +} + +void VoxelNode::setFalseColored(bool isFalseColored) { + // if we were false colored, and are no longer false colored, then swap back + if (_falseColored && !isFalseColored) { + memcpy(&_currentColor,&_trueColor,sizeof(nodeColor)); + } + _falseColored = isFalseColored; +}; + + +void VoxelNode::setColor(const nodeColor& color) { + //printf("VoxelNode::setColor() isFalseColored=%s\n",_falseColored ? "Yes" : "No"); + memcpy(&_trueColor,&color,sizeof(nodeColor)); + if (!_falseColored) { + memcpy(&_currentColor,&color,sizeof(nodeColor)); + } } // will detect if children are leaves AND the same color @@ -77,16 +118,17 @@ bool VoxelNode::collapseIdenticalLeaves() { int red,green,blue; for (int i = 0; i < 8; i++) { // if no child, or child doesn't have a color - if (children[i] == NULL || children[i]->color[3] != 1) { + if (children[i] == NULL || !children[i]->isColored()) { allChildrenMatch=false; //printLog("SADNESS child missing or not colored! i=%d\n",i); break; } else { if (i==0) { - red = children[i]->color[0]; - green = children[i]->color[1]; - blue = children[i]->color[2]; - } else if (red != children[i]->color[0] || green != children[i]->color[1] || blue != children[i]->color[2]) { + red = children[i]->getColor()[0]; + green = children[i]->getColor()[1]; + blue = children[i]->getColor()[2]; + } else if (red != children[i]->getColor()[0] || + green != children[i]->getColor()[1] || blue != children[i]->getColor()[2]) { allChildrenMatch=false; break; } @@ -100,18 +142,22 @@ bool VoxelNode::collapseIdenticalLeaves() { delete children[i]; // delete all the child nodes children[i]=NULL; // set it to NULL } - color[0]=red; - color[1]=green; - color[2]=blue; - color[3]=1; // color is set + nodeColor collapsedColor; + collapsedColor[0]=red; + collapsedColor[1]=green; + collapsedColor[2]=blue; + collapsedColor[3]=1; // color is set + setColor(collapsedColor); } return allChildrenMatch; } void VoxelNode::setRandomColor(int minimumBrightness) { + nodeColor newColor; for (int c = 0; c < 3; c++) { - color[c] = randomColorValue(minimumBrightness); + newColor[c] = randomColorValue(minimumBrightness); } - color[3] = 1; + newColor[3] = 1; + setColor(newColor); } diff --git a/libraries/voxels/src/VoxelNode.h b/libraries/voxels/src/VoxelNode.h index b82c07a09d..42b4331440 100644 --- a/libraries/voxels/src/VoxelNode.h +++ b/libraries/voxels/src/VoxelNode.h @@ -9,7 +9,16 @@ #ifndef __hifi__VoxelNode__ #define __hifi__VoxelNode__ +#include "AABox.h" + +typedef unsigned char colorPart; +typedef unsigned char nodeColor[4]; + class VoxelNode { +private: + nodeColor _trueColor; + nodeColor _currentColor; + bool _falseColored; public: VoxelNode(); ~VoxelNode(); @@ -20,8 +29,18 @@ public: bool collapseIdenticalLeaves(); unsigned char *octalCode; - unsigned char color[4]; VoxelNode *children[8]; + + bool isColored() const { return (_trueColor[3]==1); }; + void setFalseColor(colorPart red, colorPart green, colorPart blue); + void setFalseColored(bool isFalseColored); + bool getFalseColored() { return _falseColored; }; + + void setColor(const nodeColor& color); + const nodeColor& getTrueColor() const { return _trueColor; }; + const nodeColor& getColor() const { return _currentColor; }; + + void getAABox(AABox& box) const; }; #endif /* defined(__hifi__VoxelNode__) */ From b8692d8f46bbecf99fbddaec957784d00cc1b05c Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 19 Apr 2013 18:07:03 -0700 Subject: [PATCH 09/60] add glm to voxel-server build scripts --- voxel-server/CMakeLists.txt | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/voxel-server/CMakeLists.txt b/voxel-server/CMakeLists.txt index 5f9ff87fd7..99b72be9cb 100644 --- a/voxel-server/CMakeLists.txt +++ b/voxel-server/CMakeLists.txt @@ -5,6 +5,14 @@ set(TARGET_NAME voxel-server) set(ROOT_DIR ..) set(MACRO_DIR ${ROOT_DIR}/cmake/macros) +# setup for find modules +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/modules/") +set(GLM_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external) + +# set up the external glm library +include(${MACRO_DIR}/IncludeGLM.cmake) +include_glm(${TARGET_NAME} ${ROOT_DIR}) + include(${MACRO_DIR}/SetupHifiProject.cmake) setup_hifi_project(${TARGET_NAME}) @@ -14,4 +22,7 @@ include(${MACRO_DIR}/LinkHifiLibrary.cmake) link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) # link in the hifi voxels library -link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR}) \ No newline at end of file +link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR}) + +# find required libraries +find_package(GLM REQUIRED) From 4085c94aa71fa257612f6d80d0d8bc3eedc7f184 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 19 Apr 2013 18:11:28 -0700 Subject: [PATCH 10/60] made a version of firstVertexForCode() that doesn't allocate memory, for improved performance and use - created new copyFirstVertexForCode(code,output) which copies to the output buffer - converted firstVertexForCode() to behave same way as before, but use copy version --- libraries/shared/src/OctalCode.cpp | 14 +++++++++----- libraries/shared/src/OctalCode.h | 5 +++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/libraries/shared/src/OctalCode.cpp b/libraries/shared/src/OctalCode.cpp index 2a687f1cd4..898eaed377 100644 --- a/libraries/shared/src/OctalCode.cpp +++ b/libraries/shared/src/OctalCode.cpp @@ -104,9 +104,8 @@ unsigned char * childOctalCode(unsigned char * parentOctalCode, char childNumber return newCode; } -float * firstVertexForCode(unsigned char * octalCode) { - float * firstVertex = new float[3]; - memset(firstVertex, 0, 3 * sizeof(float)); +void copyFirstVertexForCode(unsigned char * octalCode, float* output) { + memset(output, 0, 3 * sizeof(float)); float currentScale = 0.5; @@ -114,11 +113,16 @@ float * firstVertexForCode(unsigned char * octalCode) { int sectionIndex = sectionValue(octalCode + 1 + (3 * i / 8), (3 * i) % 8); for (int j = 0; j < 3; j++) { - firstVertex[j] += currentScale * (int)oneAtBit(sectionIndex, 5 + j); + output[j] += currentScale * (int)oneAtBit(sectionIndex, 5 + j); } currentScale *= 0.5; } - +} + +float * firstVertexForCode(unsigned char * octalCode) { + float * firstVertex = new float[3]; + copyFirstVertexForCode(octalCode, firstVertex); return firstVertex; } + diff --git a/libraries/shared/src/OctalCode.h b/libraries/shared/src/OctalCode.h index d5367fbddf..7569e99868 100644 --- a/libraries/shared/src/OctalCode.h +++ b/libraries/shared/src/OctalCode.h @@ -16,6 +16,11 @@ int bytesRequiredForCodeLength(unsigned char threeBitCodes); bool isDirectParentOfChild(unsigned char *parentOctalCode, unsigned char * childOctalCode); int branchIndexWithDescendant(unsigned char * ancestorOctalCode, unsigned char * descendantOctalCode); unsigned char * childOctalCode(unsigned char * parentOctalCode, char childNumber); + + +// Note: copyFirstVertexForCode() is preferred because it doesn't allocate memory for the return +// but other than that these do the same thing. float * firstVertexForCode(unsigned char * octalCode); +void copyFirstVertexForCode(unsigned char * octalCode, float* output); #endif /* defined(__hifi__OctalCode__) */ From 3ec920d1b81271d7138ae88b59a722956f22f473 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 19 Apr 2013 18:14:10 -0700 Subject: [PATCH 11/60] added scale() method to AABox --- libraries/voxels/src/AABox.cpp | 11 ++++++++++- libraries/voxels/src/AABox.h | 2 ++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/libraries/voxels/src/AABox.cpp b/libraries/voxels/src/AABox.cpp index bc36bca7a9..4c2f18f863 100755 --- a/libraries/voxels/src/AABox.cpp +++ b/libraries/voxels/src/AABox.cpp @@ -19,8 +19,17 @@ AABox::AABox(void) { } -AABox::~AABox() {} +AABox::~AABox() { + // nothing to do +} + +void AABox::scale(float scale) { + corner = corner*scale; + x *= scale; + y *= scale; + z *= scale; +} void AABox::setBox(const glm::vec3& corner, float x, float y, float z) { diff --git a/libraries/voxels/src/AABox.h b/libraries/voxels/src/AABox.h index abc20f38d5..a00cda24c8 100755 --- a/libraries/voxels/src/AABox.h +++ b/libraries/voxels/src/AABox.h @@ -27,6 +27,8 @@ public: // for use in frustum computations glm::vec3 getVertexP(const glm::vec3& normal); glm::vec3 getVertexN(const glm::vec3& normal); + + void scale(float scale); }; From 2752918573e3a3dbf872d58ffc7d9525f336c176 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 19 Apr 2013 18:15:50 -0700 Subject: [PATCH 12/60] Fixed LOD bug, added recurseTree helper, change tree to use safe/true/false colors - Fixed LOD bug in server side sending - added recurseTreeWithOperation() helper - changed tree to use new VoxelNode color related API --- libraries/voxels/src/VoxelTree.cpp | 61 ++++++++++++++++++++++++------ libraries/voxels/src/VoxelTree.h | 7 ++++ 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 173fe1a38b..dc0913c513 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -69,6 +69,27 @@ VoxelTree::~VoxelTree() { } } +// Recurses voxel tree calling the RecurseVoxelTreeOperation function for each node. +// stops recursion if operation function returns false. +void VoxelTree::recurseTreeWithOperation(RecurseVoxelTreeOperation operation, void* extraData) { + recurseNodeWithOperation(rootNode, operation,extraData); +} + +// Recurses voxel node with an operation function +void VoxelTree::recurseNodeWithOperation(VoxelNode* node,RecurseVoxelTreeOperation operation, void* extraData) { + // call the operation function going "down" first, stop deeper recursion if function returns false + if (operation(node,true,extraData)) { + for (int i = 0; i < sizeof(node->children)/sizeof(node->children[0]); i++) { + VoxelNode* child = node->children[i]; + if (child) { + recurseNodeWithOperation(child,operation,extraData); + } + } + // call operation on way back up + operation(node,false,extraData); + } +} + VoxelNode * VoxelTree::nodeForOctalCode(VoxelNode *ancestorNode, unsigned char * needleCode, VoxelNode** parentOfFoundNode) { // find the appropriate branch index based on this ancestorNode if (*needleCode > 0) { @@ -130,8 +151,10 @@ int VoxelTree::readNodeData(VoxelNode *destinationNode, } // pull the color for this child - memcpy(destinationNode->children[i]->color, nodeData + bytesRead, 3); - destinationNode->children[i]->color[3] = 1; + nodeColor newColor; + memcpy(newColor, nodeData + bytesRead, 3); + newColor[3] = 1; + destinationNode->children[i]->setColor(newColor); this->voxelsColored++; this->voxelsColoredStats.recordSample(this->voxelsColored); @@ -236,8 +259,11 @@ void VoxelTree::readCodeColorBufferToTree(unsigned char *codeColorBuffer) { // give this node its color int octalCodeBytes = bytesRequiredForCodeLength(*codeColorBuffer); - memcpy(lastCreatedNode->color, codeColorBuffer + octalCodeBytes, 3); - lastCreatedNode->color[3] = 1; + + nodeColor newColor; + memcpy(newColor, codeColorBuffer + octalCodeBytes, 3); + newColor[3] = 1; + lastCreatedNode->setColor(newColor); } unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer, @@ -276,7 +302,7 @@ unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer, // coords of the voxel space. This flip flop causes LOD behavior to be extremely odd. This is my temporary hack // to fix this behavior. To disable this swap, set swapXandZ to false. // XXXBHG - 2013/04/11 - adding a note to my branch, I think this code is now broken. - bool swapXandZ=true; + bool swapXandZ=false; float agentX = swapXandZ ? agentPosition[2] : agentPosition[0]; float agentZ = swapXandZ ? agentPosition[0] : agentPosition[2]; @@ -320,10 +346,10 @@ unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer, // check if the child exists and is not transparent if (currentVoxelNode->children[i] != NULL - && currentVoxelNode->children[i]->color[3] != 0) { + && currentVoxelNode->children[i]->isColored()) { // copy in the childs color to bitstreamBuffer - memcpy(colorPointer, currentVoxelNode->children[i]->color, 3); + memcpy(colorPointer, currentVoxelNode->children[i]->getTrueColor(), 3); colorPointer += 3; // set the colorMask by bitshifting the value of childExists @@ -361,9 +387,19 @@ unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer, currentMarkerNode->children[i] = new MarkerNode(); } - // calculate the child's position based on the parent position float childNodePosition[3]; - + copyFirstVertexForCode(currentVoxelNode->children[i]->octalCode,(float*)&childNodePosition); + childNodePosition[0] *= TREE_SCALE; // scale it up + childNodePosition[1] *= TREE_SCALE; // scale it up + childNodePosition[2] *= TREE_SCALE; // scale it up + + /**** disabled ***************************************************************************************** + // Note: Stephen, I intentionally left this in so you would talk to me about it. Here's the deal, this + // code doesn't seem to work correctly. It returns X and Z flipped and the values are negative. Since + // we use the firstVertexForCode() function in VoxelSystem to calculate the child vertex and that DOES + // work, I've decided to use that function to calculate our position for LOD handling. + // + // calculate the child's position based on the parent position for (int j = 0; j < 3; j++) { childNodePosition[j] = thisNodePosition[j]; @@ -373,6 +409,7 @@ unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer, childNodePosition[j] -= (powf(0.5, *currentVoxelNode->children[i]->octalCode) * TREE_SCALE); } } + **** disabled *****************************************************************************************/ // ask the child to load the bitstream buffer with their data childStopOctalCode = loadBitstreamBuffer(bitstreamBuffer, @@ -440,7 +477,7 @@ void VoxelTree::printTreeForDebugging(VoxelNode *startNode) { // create the color mask for (int i = 0; i < 8; i++) { - if (startNode->children[i] != NULL && startNode->children[i]->color[3] != 0) { + if (startNode->children[i] != NULL && startNode->children[i]->isColored()) { colorMask += (1 << (7 - i)); } } @@ -449,9 +486,9 @@ void VoxelTree::printTreeForDebugging(VoxelNode *startNode) { // output the colors we have for (int j = 0; j < 8; j++) { - if (startNode->children[j] != NULL && startNode->children[j]->color[3] != 0) { + if (startNode->children[j] != NULL && startNode->children[j]->isColored()) { for (int c = 0; c < 3; c++) { - outputBits(startNode->children[j]->color[c]); + outputBits(startNode->children[j]->getTrueColor()[c]); } } } diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 618a3710ae..79c7b75fa4 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -18,6 +18,9 @@ const int MAX_VOXEL_PACKET_SIZE = 1492; const int MAX_TREE_SLICE_BYTES = 26; const int TREE_SCALE = 10; +// Callback function, for recuseTreeWithOperation +typedef bool (*RecurseVoxelTreeOperation)(VoxelNode* node, bool down, void* extraData); + class VoxelTree { public: long voxelsCreated; @@ -51,7 +54,11 @@ public: void loadVoxelsFile(const char* fileName, bool wantColorRandomizer); void createSphere(float r,float xc, float yc, float zc, float s, bool solid, bool wantColorRandomizer); + + void recurseTreeWithOperation(RecurseVoxelTreeOperation operation, void* extraData=NULL); + private: + void recurseNodeWithOperation(VoxelNode* node,RecurseVoxelTreeOperation operation, void* extraData); VoxelNode * nodeForOctalCode(VoxelNode *ancestorNode, unsigned char * needleCode, VoxelNode** parentOfFoundNode); VoxelNode * createMissingNode(VoxelNode *lastParentNode, unsigned char *deepestCodeToCreate); int readNodeData(VoxelNode *destinationNode, unsigned char * nodeData, int bufferSizeBytes); From 8ad51b6c0833ca2112f65162c6c086ccc6760901 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 19 Apr 2013 19:56:03 -0700 Subject: [PATCH 13/60] got rid of a bunch of this-> at Stephen's request. Added debuging for box in view --- libraries/voxels/src/ViewFrustum.cpp | 127 ++++++++++++++++----------- 1 file changed, 76 insertions(+), 51 deletions(-) diff --git a/libraries/voxels/src/ViewFrustum.cpp b/libraries/voxels/src/ViewFrustum.cpp index 867b47922f..704289d977 100644 --- a/libraries/voxels/src/ViewFrustum.cpp +++ b/libraries/voxels/src/ViewFrustum.cpp @@ -53,92 +53,92 @@ void ViewFrustum::calculate() { glm::vec3 front = _direction; // Calculating field of view. - float fovInRadians = this->_fieldOfView * PI_OVER_180; + float fovInRadians = _fieldOfView * PI_OVER_180; float twoTimesTanHalfFOV = 2.0f * tan(fovInRadians/2.0f); // Do we need this? //tang = (float)tan(ANG2RAD * angle * 0.5) ; - float nearClip = this->_nearClip; - float farClip = this->_farClip; + float nearClip = _nearClip; + float farClip = _farClip; - this->_nearHeight = (twoTimesTanHalfFOV * nearClip); - this->_nearWidth = this->_nearHeight * this->_aspectRatio; - this->_farHeight = (twoTimesTanHalfFOV * farClip); - this->_farWidth = this->_farHeight * this->_aspectRatio; + _nearHeight = (twoTimesTanHalfFOV * nearClip); + _nearWidth = _nearHeight * _aspectRatio; + _farHeight = (twoTimesTanHalfFOV * farClip); + _farWidth = _farHeight * _aspectRatio; - float farHalfHeight = (this->_farHeight * 0.5f); - float farHalfWidth = (this->_farWidth * 0.5f); - this->_farCenter = this->_position+front * farClip; - this->_farTopLeft = this->_farCenter + (this->_up * farHalfHeight) - (this->_right * farHalfWidth); - this->_farTopRight = this->_farCenter + (this->_up * farHalfHeight) + (this->_right * farHalfWidth); - this->_farBottomLeft = this->_farCenter - (this->_up * farHalfHeight) - (this->_right * farHalfWidth); - this->_farBottomRight = this->_farCenter - (this->_up * farHalfHeight) + (this->_right * farHalfWidth); + float farHalfHeight = (_farHeight * 0.5f); + float farHalfWidth = (_farWidth * 0.5f); + _farCenter = _position+front * farClip; + _farTopLeft = _farCenter + (_up * farHalfHeight) - (_right * farHalfWidth); + _farTopRight = _farCenter + (_up * farHalfHeight) + (_right * farHalfWidth); + _farBottomLeft = _farCenter - (_up * farHalfHeight) - (_right * farHalfWidth); + _farBottomRight = _farCenter - (_up * farHalfHeight) + (_right * farHalfWidth); - float nearHalfHeight = (this->_nearHeight * 0.5f); - float nearHalfWidth = (this->_nearWidth * 0.5f); - this->_nearCenter = this->_position+front * nearClip; - this->_nearTopLeft = this->_nearCenter + (this->_up * nearHalfHeight) - (this->_right * nearHalfWidth); - this->_nearTopRight = this->_nearCenter + (this->_up * nearHalfHeight) + (this->_right * nearHalfWidth); - this->_nearBottomLeft = this->_nearCenter - (this->_up * nearHalfHeight) - (this->_right * nearHalfWidth); - this->_nearBottomRight = this->_nearCenter - (this->_up * nearHalfHeight) + (this->_right * nearHalfWidth); + float nearHalfHeight = (_nearHeight * 0.5f); + float nearHalfWidth = (_nearWidth * 0.5f); + _nearCenter = _position+front * nearClip; + _nearTopLeft = _nearCenter + (_up * nearHalfHeight) - (_right * nearHalfWidth); + _nearTopRight = _nearCenter + (_up * nearHalfHeight) + (_right * nearHalfWidth); + _nearBottomLeft = _nearCenter - (_up * nearHalfHeight) - (_right * nearHalfWidth); + _nearBottomRight = _nearCenter - (_up * nearHalfHeight) + (_right * nearHalfWidth); // compute the six planes // the function set3Points assumes that the points // are given in counter clockwise order - this->_planes[TOPP].set3Points(this->_nearTopRight,this->_nearTopLeft,this->_farTopLeft); - this->_planes[BOTTOMP].set3Points(this->_nearBottomLeft,this->_nearBottomRight,this->_farBottomRight); - this->_planes[LEFTP].set3Points(this->_nearTopLeft,this->_nearBottomLeft,this->_farBottomLeft); - this->_planes[RIGHTP].set3Points(this->_nearBottomRight,this->_nearTopRight,this->_farBottomRight); - this->_planes[NEARP].set3Points(this->_nearTopLeft,this->_nearTopRight,this->_nearBottomRight); - this->_planes[FARP].set3Points(this->_farTopRight,this->_farTopLeft,this->_farBottomLeft); + _planes[TOPP].set3Points(_nearTopRight,_nearTopLeft,_farTopLeft); + _planes[BOTTOMP].set3Points(_nearBottomLeft,_nearBottomRight,_farBottomRight); + _planes[LEFTP].set3Points(_nearTopLeft,_nearBottomLeft,_farBottomLeft); + _planes[RIGHTP].set3Points(_nearBottomRight,_nearTopRight,_farBottomRight); + _planes[NEARP].set3Points(_nearTopLeft,_nearTopRight,_nearBottomRight); + _planes[FARP].set3Points(_farTopRight,_farTopLeft,_farBottomLeft); } void ViewFrustum::dump() { - printLog("position.x=%f, position.y=%f, position.z=%f\n", this->_position.x, this->_position.y, this->_position.z); - printLog("direction.x=%f, direction.y=%f, direction.z=%f\n", this->_direction.x, this->_direction.y, this->_direction.z); - printLog("up.x=%f, up.y=%f, up.z=%f\n", this->_up.x, this->_up.y, this->_up.z); - printLog("right.x=%f, right.y=%f, right.z=%f\n", this->_right.x, this->_right.y, this->_right.z); + printLog("position.x=%f, position.y=%f, position.z=%f\n", _position.x, _position.y, _position.z); + printLog("direction.x=%f, direction.y=%f, direction.z=%f\n", _direction.x, _direction.y, _direction.z); + printLog("up.x=%f, up.y=%f, up.z=%f\n", _up.x, _up.y, _up.z); + printLog("right.x=%f, right.y=%f, right.z=%f\n", _right.x, _right.y, _right.z); - printLog("farDist=%f\n", this->_farClip); - printLog("farHeight=%f\n", this->_farHeight); - printLog("farWidth=%f\n", this->_farWidth); + printLog("farDist=%f\n", _farClip); + printLog("farHeight=%f\n", _farHeight); + printLog("farWidth=%f\n", _farWidth); - printLog("nearDist=%f\n", this->_nearClip); - printLog("nearHeight=%f\n", this->_nearHeight); - printLog("nearWidth=%f\n", this->_nearWidth); + printLog("nearDist=%f\n", _nearClip); + printLog("nearHeight=%f\n", _nearHeight); + printLog("nearWidth=%f\n", _nearWidth); printLog("farCenter.x=%f, farCenter.y=%f, farCenter.z=%f\n", - this->_farCenter.x, this->_farCenter.y, this->_farCenter.z); + _farCenter.x, _farCenter.y, _farCenter.z); printLog("farTopLeft.x=%f, farTopLeft.y=%f, farTopLeft.z=%f\n", - this->_farTopLeft.x, this->_farTopLeft.y, this->_farTopLeft.z); + _farTopLeft.x, _farTopLeft.y, _farTopLeft.z); printLog("farTopRight.x=%f, farTopRight.y=%f, farTopRight.z=%f\n", - this->_farTopRight.x, this->_farTopRight.y, this->_farTopRight.z); + _farTopRight.x, _farTopRight.y, _farTopRight.z); printLog("farBottomLeft.x=%f, farBottomLeft.y=%f, farBottomLeft.z=%f\n", - this->_farBottomLeft.x, this->_farBottomLeft.y, this->_farBottomLeft.z); + _farBottomLeft.x, _farBottomLeft.y, _farBottomLeft.z); printLog("farBottomRight.x=%f, farBottomRight.y=%f, farBottomRight.z=%f\n", - this->_farBottomRight.x, this->_farBottomRight.y, this->_farBottomRight.z); + _farBottomRight.x, _farBottomRight.y, _farBottomRight.z); printLog("nearCenter.x=%f, nearCenter.y=%f, nearCenter.z=%f\n", - this->_nearCenter.x, this->_nearCenter.y, this->_nearCenter.z); + _nearCenter.x, _nearCenter.y, _nearCenter.z); printLog("nearTopLeft.x=%f, nearTopLeft.y=%f, nearTopLeft.z=%f\n", - this->_nearTopLeft.x, this->_nearTopLeft.y, this->_nearTopLeft.z); + _nearTopLeft.x, _nearTopLeft.y, _nearTopLeft.z); printLog("nearTopRight.x=%f, nearTopRight.y=%f, nearTopRight.z=%f\n", - this->_nearTopRight.x, this->_nearTopRight.y, this->_nearTopRight.z); + _nearTopRight.x, _nearTopRight.y, _nearTopRight.z); printLog("nearBottomLeft.x=%f, nearBottomLeft.y=%f, nearBottomLeft.z=%f\n", - this->_nearBottomLeft.x, this->_nearBottomLeft.y, this->_nearBottomLeft.z); + _nearBottomLeft.x, _nearBottomLeft.y, _nearBottomLeft.z); printLog("nearBottomRight.x=%f, nearBottomRight.y=%f, nearBottomRight.z=%f\n", - this->_nearBottomRight.x, this->_nearBottomRight.y, this->_nearBottomRight.z); + _nearBottomRight.x, _nearBottomRight.y, _nearBottomRight.z); } int ViewFrustum::pointInFrustum(glm::vec3 &p) { int result = INSIDE; for(int i=0; i < 6; i++) { - if (this->_planes[i].distance(p) < 0) + if (_planes[i].distance(p) < 0) return OUTSIDE; } return(result); @@ -148,7 +148,7 @@ int ViewFrustum::sphereInFrustum(glm::vec3 ¢er, float radius) { int result = INSIDE; float distance; for(int i=0; i < 6; i++) { - distance = this->_planes[i].distance(center); + distance = _planes[i].distance(center); if (distance < -radius) return OUTSIDE; else if (distance < radius) @@ -159,12 +159,37 @@ int ViewFrustum::sphereInFrustum(glm::vec3 ¢er, float radius) { int ViewFrustum::boxInFrustum(AABox &b) { + +printf("ViewFrustum::boxInFrustum() box.corner=%f,%f,%f x=%f\n",b.corner.x,b.corner.y,b.corner.z,b.x); int result = INSIDE; for(int i=0; i < 6; i++) { - if (this->_planes[i].distance(b.getVertexP(this->_planes[i].normal)) < 0) + + printf("plane[%d] -- point(%f,%f,%f) normal(%f,%f,%f) d=%f \n",i, + _planes[i].point.x, _planes[i].point.y, _planes[i].point.z, + _planes[i].normal.x, _planes[i].normal.y, _planes[i].normal.z, + _planes[i].d + ); + + glm::vec3 normal = _planes[i].normal; + glm::vec3 boxVertexP = b.getVertexP(normal); + float planeToBoxVertexPDistance = _planes[i].distance(boxVertexP); + + glm::vec3 boxVertexN = b.getVertexN(normal); + float planeToBoxVertexNDistance = _planes[i].distance(boxVertexN); + + + + printf("plane[%d] normal=(%f,%f,%f) bVertexP=(%f,%f,%f) planeToBoxVertexPDistance=%f boxVertexN=(%f,%f,%f) planeToBoxVertexNDistance=%f\n",i, + normal.x,normal.y,normal.z, + boxVertexP.x,boxVertexP.y,boxVertexP.z,planeToBoxVertexPDistance, + boxVertexN.x,boxVertexN.y,boxVertexN.z,planeToBoxVertexNDistance + ); + + if (planeToBoxVertexPDistance < 0) { return OUTSIDE; - else if (this->_planes[i].distance(b.getVertexN(this->_planes[i].normal)) < 0) + } else if (planeToBoxVertexNDistance < 0) { result = INTERSECT; + } } return(result); } From 7dbc6bc986eb99b7a502c6237ca075b1b5fdacef Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 19 Apr 2013 19:56:53 -0700 Subject: [PATCH 14/60] Added inline getters for camera attributes --- libraries/voxels/src/ViewFrustum.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libraries/voxels/src/ViewFrustum.h b/libraries/voxels/src/ViewFrustum.h index 15bdb484fb..9b496544c5 100644 --- a/libraries/voxels/src/ViewFrustum.h +++ b/libraries/voxels/src/ViewFrustum.h @@ -54,6 +54,12 @@ public: void setOrientation (const glm::vec3& d, const glm::vec3& u, const glm::vec3& r ) { _direction = d; _up = u; _right = r; } + // getters for camera attributes + const glm::vec3& getPosition() const { return _position; }; + const glm::vec3& getDirection() const { return _direction; }; + const glm::vec3& getUp() const { return _up; }; + const glm::vec3& getRight() const { return _right; }; + // setters for lens attributes void setFieldOfView ( float f ) { _fieldOfView = f; } void setAspectRatio ( float a ) { _aspectRatio = a; } From 75a79a09ed3a95db066d430fb84ba63efc218b8b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 19 Apr 2013 19:58:37 -0700 Subject: [PATCH 15/60] fixed LOD bug, added support for false colors - fixed LOD bug related to mismatch with getting node position - changed VoxelSystem to honor new VoxelNode color support for false color - added some implementations of tree recursion that do things like false color the tree for distance, randomly, or resetting to true color, or stomping on the local version of the true color to debug packet sending --- interface/src/VoxelSystem.cpp | 334 ++++++++++++++++++++++++++++++---- interface/src/VoxelSystem.h | 23 ++- 2 files changed, 316 insertions(+), 41 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 412c0aac75..5b388d351c 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -161,9 +161,8 @@ void VoxelSystem::setupNewVoxelsForDrawing() { writeVerticesEndPointer = writeVerticesArray; // call recursive function to populate in memory arrays // it will return the number of voxels added - float treeRoot[3] = {0,0,0}; + glm::vec3 treeRoot = glm::vec3(0,0,0); voxelsRendered = treeToArrays(tree->rootNode, treeRoot); - // copy the newly written data to the arrays designated for reading copyWrittenDataToReadArrays(); } @@ -176,42 +175,35 @@ void VoxelSystem::copyWrittenDataToReadArrays() { // copy the vertices and colors memcpy(readVerticesArray, writeVerticesArray, (endOfCurrentVerticesData - writeVerticesArray) * sizeof(GLfloat)); memcpy(readColorsArray, writeColorsArray, (endOfCurrentVerticesData - writeVerticesArray) * sizeof(GLubyte)); - // set the read vertices end pointer to the correct spot so the GPU knows how much to pull readVerticesEndPointer = readVerticesArray + (endOfCurrentVerticesData - writeVerticesArray); pthread_mutex_unlock(&bufferWriteLock); } -int VoxelSystem::treeToArrays(VoxelNode *currentNode, float nodePosition[3]) { +int VoxelSystem::treeToArrays(VoxelNode *currentNode, const glm::vec3& nodePosition) { int voxelsAdded = 0; float halfUnitForVoxel = powf(0.5, *currentNode->octalCode) * (0.5 * TREE_SCALE); glm::vec3 viewerPosition = viewerHead->getBodyPosition(); - // XXXBHG - Note: It appears as if the X and Z coordinates of Head or Agent are flip-flopped relative to the - // coords of the voxel space. This flip flop causes LOD behavior to be extremely odd. This is my temporary hack - // to fix this behavior. To disable this swap, set swapXandZ to false. - bool swapXandZ=true; - float viewerX = swapXandZ ? viewerPosition[2] : viewerPosition[0]; - float viewerZ = swapXandZ ? viewerPosition[0] : viewerPosition[2]; + // debug LOD code + glm::vec3 debugNodePosition; + copyFirstVertexForCode(currentNode->octalCode,(float*)&debugNodePosition); - // debugging code. - //printLog("treeToArrays() halfUnitForVoxel=%f\n",halfUnitForVoxel); - //printLog("treeToArrays() viewerPosition {x,y,z or [0],[1],[2]} ={%f,%f,%f}\n", - // viewerPosition[0],viewerPosition[1],viewerPosition[2]); - //printLog("treeToArrays() nodePosition {x,y,z or [0],[1],[2]} = {%f,%f,%f}\n", - // nodePosition[0],nodePosition[1],nodePosition[2]); - //float* vertices = firstVertexForCode(currentNode->octalCode); - //printLog("treeToArrays() firstVerticesForCode(currentNode->octalCode)={x,y,z or [0],[1],[2]} = {%f,%f,%f}\n", - // vertices[0],vertices[1],vertices[2]); - //delete []vertices; - - float distanceToVoxelCenter = sqrtf(powf(viewerX - nodePosition[0] - halfUnitForVoxel, 2) + - powf(viewerPosition[1] - nodePosition[1] - halfUnitForVoxel, 2) + - powf(viewerZ - nodePosition[2] - halfUnitForVoxel, 2)); + //printf("-----------------\n"); + //printf("halfUnitForVoxel=%f\n",halfUnitForVoxel); + //printf("viewer.x=%f y=%f z=%f \n", viewerPosition.x, viewerPosition.y, viewerPosition.z); + //printf("node.x=%f y=%f z=%f \n", nodePosition[0], nodePosition[1], nodePosition[2]); + //printf("debugNodePosition.x=%f y=%f z=%f \n", debugNodePosition[0], debugNodePosition[1], debugNodePosition[2]); - int boundaryPosition = boundaryDistanceForRenderLevel(*currentNode->octalCode + 1); - //printLog("treeToArrays() distanceToVoxelCenter=%f boundaryPosition=%d\n",distanceToVoxelCenter,boundaryPosition); + float distanceToVoxelCenter = sqrtf(powf(viewerPosition.x - nodePosition[0] - halfUnitForVoxel, 2) + + powf(viewerPosition.y - nodePosition[1] - halfUnitForVoxel, 2) + + powf(viewerPosition.z - nodePosition[2] - halfUnitForVoxel, 2)); + + int renderLevel = *currentNode->octalCode + 1; + int boundaryPosition = boundaryDistanceForRenderLevel(renderLevel); + //printLog("treeToArrays() renderLevel=%d distanceToVoxelCenter=%f boundaryPosition=%d\n", + // renderLevel,distanceToVoxelCenter,boundaryPosition); bool alwaysDraw = false; // XXXBHG - temporary debug code. Flip this to true to disable LOD blurring @@ -220,43 +212,46 @@ int VoxelSystem::treeToArrays(VoxelNode *currentNode, float nodePosition[3]) { // check if there is a child here if (currentNode->children[i] != NULL) { - // calculate the child's position based on the parent position - float childNodePosition[3]; + glm::vec3 childNodePosition; + copyFirstVertexForCode(currentNode->children[i]->octalCode,(float*)&childNodePosition); + childNodePosition *= (float)TREE_SCALE; // scale it up + /**** disabled ************************************************************************************************ + // Note: Stephen, I intentionally left this in so you would talk to me about it. Here's the deal, this code + // doesn't seem to work correctly. It returns X and Z flipped and the values are negative. Since we use the + // firstVertexForCode() function below to calculate the child vertex and that DOES work, I've decided to use + // that function to calculate our position for LOD handling. + // + // calculate the child's position based on the parent position for (int j = 0; j < 3; j++) { childNodePosition[j] = nodePosition[j]; - if (oneAtBit(branchIndexWithDescendant(currentNode->octalCode, - currentNode->children[i]->octalCode), - (7 - j))) { + if (oneAtBit(branchIndexWithDescendant(currentNode->octalCode,currentNode->children[i]->octalCode),(7 - j))) { childNodePosition[j] -= (powf(0.5, *currentNode->children[i]->octalCode) * TREE_SCALE); } } + **** disabled ************************************************************************************************/ voxelsAdded += treeToArrays(currentNode->children[i], childNodePosition); } } } - - - + // if we didn't get any voxels added then we're a leaf // add our vertex and color information to the interleaved array - if (voxelsAdded == 0 && currentNode->color[3] == 1) { - float * startVertex = firstVertexForCode(currentNode->octalCode); + if (voxelsAdded == 0 && currentNode->isColored()) { + float startVertex[3]; + copyFirstVertexForCode(currentNode->octalCode,(float*)&startVertex); float voxelScale = 1 / powf(2, *currentNode->octalCode); // populate the array with points for the 8 vertices // and RGB color for each added vertex for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) { *writeVerticesEndPointer = startVertex[j % 3] + (identityVertices[j] * voxelScale); - *(writeColorsArray + (writeVerticesEndPointer - writeVerticesArray)) = currentNode->color[j % 3]; + *(writeColorsArray + (writeVerticesEndPointer - writeVerticesArray)) = currentNode->getColor()[j % 3]; writeVerticesEndPointer++; } - voxelsAdded++; - - delete [] startVertex; } return voxelsAdded; @@ -363,4 +358,263 @@ void VoxelSystem::simulate(float deltaTime) { } +int VoxelSystem::_nodeCount = 0; +bool VoxelSystem::randomColorOperation(VoxelNode* node, bool down, void* extraData) { + + // we do our operations on the way up! + if (down) { + return true; + } + + _nodeCount++; + if (node->isColored()) { + nodeColor newColor = { 0,0,0,1 }; + newColor[0] = randomColorValue(150); + newColor[1] = randomColorValue(150); + newColor[1] = randomColorValue(150); + + //printf("randomize color node %d was %x,%x,%x NOW %x,%x,%x\n", + // _nodeCount,node->getTrueColor()[0],node->getTrueColor()[1],node->getTrueColor()[2], + // newColor[0],newColor[1],newColor[2]); + node->setColor(newColor); + } else { + //printf("not randomizing color node of %d since it has no color\n",_nodeCount); + } + return true; +} + +void VoxelSystem::randomizeVoxelColors() { + _nodeCount = 0; + tree->recurseTreeWithOperation(randomColorOperation); + printf("setting randomized true color for %d nodes\n",_nodeCount); + setupNewVoxelsForDrawing(); +} + +bool VoxelSystem::falseColorizeRandomOperation(VoxelNode* node, bool down, void* extraData) { + + // we do our operations on the way up! + if (down) { + return true; + } + + _nodeCount++; + + // always false colorize + unsigned char newR = randomColorValue(150); + unsigned char newG = randomColorValue(150); + unsigned char newB = randomColorValue(150); + + printf("randomize FALSE color node %d was %x,%x,%x NOW %x,%x,%x\n", + _nodeCount,node->getTrueColor()[0],node->getTrueColor()[1],node->getTrueColor()[2], + newR,newG,newB); + node->setFalseColor(newR,newG,newB); + + return true; // keep going! +} + +void VoxelSystem::falseColorizeRandom() { + _nodeCount = 0; + tree->recurseTreeWithOperation(falseColorizeRandomOperation); + printf("setting randomized false color for %d nodes\n",_nodeCount); + setupNewVoxelsForDrawing(); +} + +bool VoxelSystem::trueColorizeOperation(VoxelNode* node, bool down, void* extraData) { + + // we do our operations on the way up! + if (down) { + return true; + } + + _nodeCount++; + node->setFalseColored(false); + //printf("setting true color for node %d\n",_nodeCount); + return true; +} + +void VoxelSystem::trueColorize() { + _nodeCount = 0; + tree->recurseTreeWithOperation(trueColorizeOperation); + printf("setting true color for %d nodes\n",_nodeCount); + setupNewVoxelsForDrawing(); +} + +// Will false colorize voxels that are not in view +bool VoxelSystem::falseColorizeInViewOperation(VoxelNode* node, bool down, void* extraData) { + + // we do our operations on the way up! + if (down) { + return true; + } + + ViewFrustum* viewFrustum = (ViewFrustum*) extraData; + + _nodeCount++; + + // only do this for truely colored voxels... + if (node->isColored()) { + // first calculate the AAbox for the voxel + AABox voxelBox; + node->getAABox(voxelBox); + + voxelBox.scale(TREE_SCALE); + + printf("voxelBox corner=(%f,%f,%f) x=%f y=%f z=%f\n", + voxelBox.corner.x, voxelBox.corner.y, voxelBox.corner.z, + voxelBox.x, voxelBox.y, voxelBox.z); + + // If the voxel is outside of the view frustum, then false color it red + if (ViewFrustum::OUTSIDE == viewFrustum->boxInFrustum(voxelBox)) { + // Out of view voxels are colored RED + unsigned char newR = 255; + unsigned char newG = 0; + unsigned char newB = 0; + + //printf("voxel OUTSIDE view - FALSE colorizing node %d TRUE color is %x,%x,%x \n", + // _nodeCount,node->getTrueColor()[0],node->getTrueColor()[1],node->getTrueColor()[2]); + node->setFalseColor(newR,newG,newB); + } else { + printf("voxel NOT OUTSIDE view\n"); + } + } else { + printf("voxel not colored, don't consider it\n"); + } + + return true; // keep going! +} + +void VoxelSystem::falseColorizeInView(ViewFrustum* viewFrustum) { + _nodeCount = 0; + tree->recurseTreeWithOperation(falseColorizeInViewOperation,(void*)viewFrustum); + printf("setting in view false color for %d nodes\n",_nodeCount); + setupNewVoxelsForDrawing(); +} + +// Will false colorize voxels based on distance from view +bool VoxelSystem::falseColorizeDistanceFromViewOperation(VoxelNode* node, bool down, void* extraData) { + + //printf("falseColorizeDistanceFromViewOperation() down=%s\n",(down ? "TRUE" : "FALSE")); + + // we do our operations on the way up! + if (down) { + return true; + } + + ViewFrustum* viewFrustum = (ViewFrustum*) extraData; + + // only do this for truly colored voxels... + if (node->isColored()) { + + // We need our distance for both up and down + glm::vec3 nodePosition; + float* startVertex = firstVertexForCode(node->octalCode); + nodePosition.x = startVertex[0]; + nodePosition.y = startVertex[1]; + nodePosition.z = startVertex[2]; + delete startVertex; + + // scale up the node position + nodePosition = nodePosition*(float)TREE_SCALE; + + float halfUnitForVoxel = powf(0.5, *node->octalCode) * (0.5 * TREE_SCALE); + glm::vec3 viewerPosition = viewFrustum->getPosition(); + + //printf("halfUnitForVoxel=%f\n",halfUnitForVoxel); + //printf("viewer.x=%f y=%f z=%f \n", viewerPosition.x, viewerPosition.y, viewerPosition.z); + //printf("node.x=%f y=%f z=%f \n", nodePosition.x, nodePosition.y, nodePosition.z); + + float distance = sqrtf(powf(viewerPosition.x - nodePosition.x - halfUnitForVoxel, 2) + + powf(viewerPosition.y - nodePosition.y - halfUnitForVoxel, 2) + + powf(viewerPosition.z - nodePosition.z - halfUnitForVoxel, 2)); + + // actually colorize + _nodeCount++; + + float distanceRatio = (_minDistance==_maxDistance) ? 1 : (distance - _minDistance)/(_maxDistance - _minDistance); + + // We want to colorize this in 16 bug chunks of color + const unsigned char maxColor = 255; + const unsigned char colorBands = 16; + const unsigned char gradientOver = 128; + unsigned char colorBand = (colorBands*distanceRatio); + unsigned char newR = (colorBand*(gradientOver/colorBands))+(maxColor-gradientOver); + unsigned char newG = 0; + unsigned char newB = 0; + //printf("Setting color down=%s distance=%f min=%f max=%f distanceRatio=%f color=%d \n", + // (down ? "TRUE" : "FALSE"), distance, _minDistance, _maxDistance, distanceRatio, (int)newR); + + node->setFalseColor(newR,newG,newB); + } else { + //printf("voxel not colored, don't consider it - down=%s\n",(down ? "TRUE" : "FALSE")); + } + return true; // keep going! +} + +float VoxelSystem::_maxDistance = 0.0; +float VoxelSystem::_minDistance = FLT_MAX; + +// Helper function will get the distance from view range, would be nice if you could just keep track +// of this as voxels are created and/or colored... seems like some transform math could do that so +// we wouldn't need to do two passes of the tree +bool VoxelSystem::getDistanceFromViewRangeOperation(VoxelNode* node, bool down, void* extraData) { + + // we do our operations on the way up! + if (down) { + return true; + } + + //printf("getDistanceFromViewRangeOperation() down=%s\n",(down ? "TRUE" : "FALSE")); + + ViewFrustum* viewFrustum = (ViewFrustum*) extraData; + + // only do this for truly colored voxels... + if (node->isColored()) { + + // We need our distance for both up and down + glm::vec3 nodePosition; + float* startVertex = firstVertexForCode(node->octalCode); + nodePosition.x = startVertex[0]; + nodePosition.y = startVertex[1]; + nodePosition.z = startVertex[2]; + delete startVertex; + + // scale up the node position + nodePosition = nodePosition*(float)TREE_SCALE; + + float halfUnitForVoxel = powf(0.5, *node->octalCode) * (0.5 * TREE_SCALE); + glm::vec3 viewerPosition = viewFrustum->getPosition(); + + float distance = sqrtf(powf(viewerPosition.x - nodePosition.x - halfUnitForVoxel, 2) + + powf(viewerPosition.y - nodePosition.y - halfUnitForVoxel, 2) + + powf(viewerPosition.z - nodePosition.z - halfUnitForVoxel, 2)); + + // on way down, calculate the range of distances + if (distance > _maxDistance) { + _maxDistance = distance; + //printf("new maxDistance=%f down=%s\n",_maxDistance, (down ? "TRUE" : "FALSE")); + } + if (distance < _minDistance) { + _minDistance = distance; + //printf("new minDistance=%f down=%s\n",_minDistance, (down ? "TRUE" : "FALSE")); + } + + _nodeCount++; + } + return true; // keep going! +} + +void VoxelSystem::falseColorizeDistanceFromView(ViewFrustum* viewFrustum) { + _nodeCount = 0; + + _maxDistance = 0.0; + _minDistance = FLT_MAX; + tree->recurseTreeWithOperation(getDistanceFromViewRangeOperation,(void*)viewFrustum); + printf("determining distance range for %d nodes\n",_nodeCount); + + _nodeCount = 0; + + tree->recurseTreeWithOperation(falseColorizeDistanceFromViewOperation,(void*)viewFrustum); + printf("setting in distance false color for %d nodes\n",_nodeCount); + setupNewVoxelsForDrawing(); +} diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 5395ce700a..6c9b5d972e 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -14,6 +14,7 @@ #include #include #include +#include #include "Head.h" #include "Util.h" #include "world.h" @@ -44,7 +45,27 @@ public: long int getVoxelsColoredRunningAverage(); long int getVoxelsBytesReadRunningAverage(); + // Methods that recurse tree + void randomizeVoxelColors(); + void falseColorizeRandom(); + void trueColorize(); + void falseColorizeInView(ViewFrustum* viewFrustum); + void falseColorizeDistanceFromView(ViewFrustum* viewFrustum); + private: + // Operation functions for tree recursion methods + static int _nodeCount; + static bool randomColorOperation(VoxelNode* node, bool down, void* extraData); + static bool falseColorizeRandomOperation(VoxelNode* node, bool down, void* extraData); + static bool trueColorizeOperation(VoxelNode* node, bool down, void* extraData); + static bool falseColorizeInViewOperation(VoxelNode* node, bool down, void* extraData); + static bool falseColorizeDistanceFromViewOperation(VoxelNode* node, bool down, void* extraData); + static bool getDistanceFromViewRangeOperation(VoxelNode* node, bool down, void* extraData); + + // these are kinda hacks, used by getDistanceFromViewRangeOperation() probably shouldn't be here + static float _maxDistance; + static float _minDistance; + int voxelsRendered; Head *viewerHead; VoxelTree *tree; @@ -59,7 +80,7 @@ private: GLuint vboIndicesID; pthread_mutex_t bufferWriteLock; - int treeToArrays(VoxelNode *currentNode, float nodePosition[3]); + int treeToArrays(VoxelNode *currentNode, const glm::vec3& nodePosition); void setupNewVoxelsForDrawing(); void copyWrittenDataToReadArrays(); }; From 8c4536199f58f2dba3010e11fe6b98726058e1b4 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 19 Apr 2013 20:02:14 -0700 Subject: [PATCH 16/60] added menu items for false color operations --- interface/src/main.cpp | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 0b02b9ecf3..86b39fee2f 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -1021,6 +1021,39 @@ int setFrustumRenderMode(int state) { return ::frustumDrawingMode; } +int doRandomizeVoxelColors(int state) { + if (state == MENU_ROW_PICKED) { + ::voxels.randomizeVoxelColors(); + } + return state; +} + + +int doFalseRandomizeVoxelColors(int state) { + if (state == MENU_ROW_PICKED) { + ::voxels.falseColorizeRandom(); + } + return state; +} + +int doTrueVoxelColors(int state) { + if (state == MENU_ROW_PICKED) { + ::voxels.trueColorize(); + } + return state; +} + +int doFalseColorizeInView(int state) { + if (state == MENU_ROW_PICKED) { + if (::frustumOn) { + // we probably want to make sure the viewFrustum is initialized first + voxels.falseColorizeDistanceFromView(&::viewFrustum); + } + } + return state; +} + + const char* modeAll = " - All "; const char* modeVectors = " - Vectors "; const char* modePlanes = " - Planes "; @@ -1075,7 +1108,10 @@ void initMenu() { // Debug menuColumnDebug = menu.addColumn("Debug"); - + menuColumnDebug->addRow("Randomize Voxel Colors (Z)", doRandomizeVoxelColors); + menuColumnDebug->addRow("Randomize FALSE Voxel Colors", doFalseRandomizeVoxelColors); + menuColumnDebug->addRow("FALSE Color Voxel Out of View", doFalseColorizeInView); + menuColumnDebug->addRow("True Colors", doTrueVoxelColors); } void testPointToVoxel() @@ -1239,6 +1275,8 @@ void key(unsigned char k, int x, int y) // if (k == '\\') ViewFrustum::fovAngleAdust += 0.05; if (k == 'R') setFrustumRenderMode(MENU_ROW_PICKED); + + if (k == 'Z') doRandomizeVoxelColors(MENU_ROW_PICKED); if (k == '&') { ::paintOn = !::paintOn; // toggle paint From 34b401d13fe6261984f8e3c25e450a53ac62158d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sun, 21 Apr 2013 12:01:54 -0700 Subject: [PATCH 17/60] changed render_view_frustum() to match coding standard, added menu items, cleanup - split render_view_frustum() into two parts: loadViewFrustum() and renderViewFrustum() - cleaned up debug menu items to match actual false color behaviors - coding standard cleanup --- interface/src/main.cpp | 99 +++++++++++++++++++++++++----------------- 1 file changed, 60 insertions(+), 39 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index fba8633ac1..8d996d85e5 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -555,34 +555,14 @@ void updateAvatar(float frametime) } ///////////////////////////////////////////////////////////////////////////////////// -// render_view_frustum() +// renderViewFrustum() // -// Description: this will render the view frustum bounds for EITHER the head +// Description: this will load the view frustum bounds for EITHER the head // or the "myCamera". // -// Frustum rendering mode. For debug purposes, we allow drawing the frustum in a couple of different ways. -// We can draw it with each of these parts: -// * Origin Direction/Up/Right vectors - these will be drawn at the point of the camera -// * Near plane - this plane is drawn very close to the origin point. -// * Right/Left planes - these two planes are drawn between the near and far planes. -// * Far plane - the plane is drawn in the distance. -// Modes - the following modes, will draw the following parts. -// * All - draws all the parts listed above -// * Planes - draws the planes but not the origin vectors -// * Origin Vectors - draws the origin vectors ONLY -// * Near Plane - draws only the near plane -// * Far Plane - draws only the far plane -#define FRUSTUM_DRAW_MODE_ALL 0 -#define FRUSTUM_DRAW_MODE_VECTORS 1 -#define FRUSTUM_DRAW_MODE_PLANES 2 -#define FRUSTUM_DRAW_MODE_NEAR_PLANE 3 -#define FRUSTUM_DRAW_MODE_FAR_PLANE 4 -#define FRUSTUM_DRAW_MODE_COUNT 5 -// These global scoped variables are used by our render_view_frustum() function below, but are also available as globals -// so that the keyboard and menu can manipulate them. - -int frustumDrawingMode = FRUSTUM_DRAW_MODE_ALL; // the mode we're drawing the frustum in, see notes above +// These global scoped variables are used by our loadViewFrustum() and renderViewFrustum functions below, but are also +// available as globals so that the keyboard and menu can manipulate them. bool frustumOn = false; // Whether or not to display the debug view frustum bool cameraFrustum = true; // which frustum to look at @@ -594,8 +574,7 @@ float viewFrustumOffsetRoll = 0.0; float viewFrustumOffsetDistance = 25.0; float viewFrustumOffsetUp = 0.0; -void render_view_frustum() { - +void loadViewFrustum(ViewFrustum& viewFrustum) { // We will use these below, from either the camera or head vectors calculated above glm::vec3 position; glm::vec3 direction; @@ -654,8 +633,44 @@ void render_view_frustum() { // Ask the ViewFrustum class to calculate our corners viewFrustum.calculate(); - - //viewFrustum.dump(); +} + +///////////////////////////////////////////////////////////////////////////////////// +// renderViewFrustum() +// +// Description: this will render the view frustum bounds for EITHER the head +// or the "myCamera". +// +// Frustum rendering mode. For debug purposes, we allow drawing the frustum in a couple of different ways. +// We can draw it with each of these parts: +// * Origin Direction/Up/Right vectors - these will be drawn at the point of the camera +// * Near plane - this plane is drawn very close to the origin point. +// * Right/Left planes - these two planes are drawn between the near and far planes. +// * Far plane - the plane is drawn in the distance. +// Modes - the following modes, will draw the following parts. +// * All - draws all the parts listed above +// * Planes - draws the planes but not the origin vectors +// * Origin Vectors - draws the origin vectors ONLY +// * Near Plane - draws only the near plane +// * Far Plane - draws only the far plane +#define FRUSTUM_DRAW_MODE_ALL 0 +#define FRUSTUM_DRAW_MODE_VECTORS 1 +#define FRUSTUM_DRAW_MODE_PLANES 2 +#define FRUSTUM_DRAW_MODE_NEAR_PLANE 3 +#define FRUSTUM_DRAW_MODE_FAR_PLANE 4 +#define FRUSTUM_DRAW_MODE_COUNT 5 + +int frustumDrawingMode = FRUSTUM_DRAW_MODE_ALL; // the mode we're drawing the frustum in, see notes above + +void renderViewFrustum(ViewFrustum& viewFrustum) { + + // Load it with the latest details! + loadViewFrustum(viewFrustum); + + glm::vec3 position = viewFrustum.getPosition(); + glm::vec3 direction = viewFrustum.getDirection(); + glm::vec3 up = viewFrustum.getUp(); + glm::vec3 right = viewFrustum.getRight(); // Get ready to draw some lines glDisable(GL_LIGHTING); @@ -816,7 +831,7 @@ void display(void) // is the viewFrustumOffsetCamera. But theoretically, we could use this same mechanism // to add other cameras. // - // Why have two cameras? Well, one reason is that because in the case of the render_view_frustum() + // Why have two cameras? Well, one reason is that because in the case of the renderViewFrustum() // code, we want to keep the state of "myCamera" intact, so we can render what the view frustum of // myCamera is. But we also want to do meaningful camera transforms on OpenGL for the offset camera Camera whichCamera = myCamera; @@ -910,7 +925,7 @@ void display(void) if (!displayHead && statsOn) render_world_box(); // brad's frustum for debugging - if (::frustumOn) render_view_frustum(); + if (::frustumOn) renderViewFrustum(::viewFrustum); //Render my own avatar myAvatar.render(true); @@ -1112,12 +1127,19 @@ int doTrueVoxelColors(int state) { return state; } +int doFalseColorizeByDistance(int state) { + if (state == MENU_ROW_PICKED) { + loadViewFrustum(::viewFrustum); + voxels.falseColorizeDistanceFromView(&::viewFrustum); + } + return state; +} + int doFalseColorizeInView(int state) { if (state == MENU_ROW_PICKED) { - if (::frustumOn) { - // we probably want to make sure the viewFrustum is initialized first - voxels.falseColorizeDistanceFromView(&::viewFrustum); - } + loadViewFrustum(::viewFrustum); + // we probably want to make sure the viewFrustum is initialized first + voxels.falseColorizeInView(&::viewFrustum); } return state; } @@ -1177,10 +1199,11 @@ void initMenu() { // Debug menuColumnDebug = menu.addColumn("Debug"); - menuColumnDebug->addRow("Randomize Voxel Colors (Z)", doRandomizeVoxelColors); - menuColumnDebug->addRow("Randomize FALSE Voxel Colors", doFalseRandomizeVoxelColors); + menuColumnDebug->addRow("Randomize Voxel TRUE Colors", doRandomizeVoxelColors); + menuColumnDebug->addRow("FALSE Color Voxels Randomly", doFalseRandomizeVoxelColors); + menuColumnDebug->addRow("FALSE Color Voxels by Distance", doFalseColorizeByDistance); menuColumnDebug->addRow("FALSE Color Voxel Out of View", doFalseColorizeInView); - menuColumnDebug->addRow("True Colors", doTrueVoxelColors); + menuColumnDebug->addRow("Show TRUE Colors", doTrueVoxelColors); } void testPointToVoxel() @@ -1345,8 +1368,6 @@ void key(unsigned char k, int x, int y) if (k == 'R') setFrustumRenderMode(MENU_ROW_PICKED); - if (k == 'Z') doRandomizeVoxelColors(MENU_ROW_PICKED); - if (k == '&') { ::paintOn = !::paintOn; // toggle paint ::setupPaintingVoxel(); // also randomizes colors From 7a632115e412fe22ac842269fcc7bd00efcd6f00 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sun, 21 Apr 2013 12:18:42 -0700 Subject: [PATCH 18/60] fixed crash when no avatar mixer is present and display stats is enabled --- interface/src/main.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 8d996d85e5..8712700efc 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -341,11 +341,15 @@ void displayStats(void) Agent *avatarMixer = AgentList::getInstance()->soloAgentOfType(AGENT_TYPE_AVATAR_MIXER); char avatarMixerStats[200]; - sprintf(avatarMixerStats, "Avatar Mixer - %.f kbps, %.f pps", - roundf(avatarMixer->getAverageKilobitsPerSecond()), - roundf(avatarMixer->getAveragePacketsPerSecond())); + if (avatarMixer) { + sprintf(avatarMixerStats, "Avatar Mixer - %.f kbps, %.f pps", + roundf(avatarMixer->getAverageKilobitsPerSecond()), + roundf(avatarMixer->getAveragePacketsPerSecond())); + } else { + sprintf(avatarMixerStats, "No Avatar Mixer"); + } drawtext(10, statsVerticalOffset + 330, 0.10f, 0, 1.0, 0, avatarMixerStats); - + if (::perfStatsOn) { // Get the PerfStats group details. We need to allocate and array of char* long enough to hold 1+groups char** perfStatLinesArray = new char*[PerfStat::getGroupCount()+1]; From 8a150d27b8ad84754739a570011294b7a8e6a3b4 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sun, 21 Apr 2013 15:18:17 -0700 Subject: [PATCH 19/60] Cleanup for coding standard fix bug in creation of plane from points - cleaned up code to match HiFi Coding standard - fixed bug in creation of plane related to cross product --- libraries/voxels/src/Plane.cpp | 109 ++++++++++++++++++--------------- libraries/voxels/src/Plane.h | 39 +++++++----- 2 files changed, 84 insertions(+), 64 deletions(-) diff --git a/libraries/voxels/src/Plane.cpp b/libraries/voxels/src/Plane.cpp index 2f0d43925b..10d1e2fb6b 100755 --- a/libraries/voxels/src/Plane.cpp +++ b/libraries/voxels/src/Plane.cpp @@ -1,6 +1,12 @@ -// Plane.cpp // -////////////////////////////////////////////////////////////////////// +// Plane.h +// hifi +// +// Created by Brad Hefta-Gaub on 04/11/13. +// Originally from lighthouse3d. Modified to utilize glm::vec3 and clean up to our coding standards +// +// Simple plane class. +// #include "Plane.h" #include @@ -10,78 +16,83 @@ using voxels_lib::printLog; // These are some useful utilities that vec3 is missing -float vec3_length(const glm::vec3& v) { - return((float)sqrt(v.x*v.x + v.y*v.y + v.z*v.z)); +float length(const glm::vec3& v) { + return((float)sqrt(v.x * v.x + v.y * v.y + v.z * v.z)); } -void vec3_normalize(glm::vec3& v) { - - float len; - - len = vec3_length(v); - if (len) { - v.x /= len;; - v.y /= len; - v.z /= len; - } +void normalize(glm::vec3& v) { + float len; + len = length(v); + if (len) { + v.x /= len;; + v.y /= len; + v.z /= len; + } } -float vec3_innerProduct(const glm::vec3& v1,const glm::vec3& v2) { - - return (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z); +// cross product +glm::vec3 crossProduct(const glm::vec3& lhs, const glm::vec3& rhs) { + glm::vec3 result; + result.x = lhs.y * rhs.z - lhs.z * rhs.y; + result.y = lhs.z * rhs.x - lhs.x * rhs.z; + result.z = lhs.x * rhs.y - lhs.y * rhs.x; + return result; } - -Plane::Plane(const glm::vec3 &v1, const glm::vec3 &v2, const glm::vec3 &v3) { - - set3Points(v1,v2,v3); +float innerProduct(const glm::vec3& v1,const glm::vec3& v2) { + return (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z); } - -Plane::Plane() {} - -Plane::~Plane() {} - +void printVec3(const char* name, const glm::vec3& v) { + printf("%s x=%f y=%f z=%f\n", name, v.x, v.y, v.z); +} void Plane::set3Points(const glm::vec3 &v1, const glm::vec3 &v2, const glm::vec3 &v3) { + glm::vec3 linev1v2, linev1v3; + linev1v2 = v2 - v1; + linev1v3 = v3 - v1; - glm::vec3 aux1, aux2; + // this will be perpendicular to both lines + _normal = crossProduct(linev1v2,linev1v3); + normalize(_normal); - aux1 = v1 - v2; - aux2 = v3 - v2; + // this is a point on the plane + _point = v2; - normal = aux2 * aux1; - - vec3_normalize(normal); - point = v2; - d = -(vec3_innerProduct(normal,point)); + // the D coefficient from the form Ax+By+Cz=D + _dCoefficient = -(innerProduct(_normal,_point)); } void Plane::setNormalAndPoint(const glm::vec3 &normal, const glm::vec3 &point) { + _point = point; + _normal = normal; + normalize(_normal); - this->normal = normal; - vec3_normalize(this->normal); - d = -(vec3_innerProduct(this->normal,point)); + // the D coefficient from the form Ax+By+Cz=D + _dCoefficient = -(innerProduct(_normal,_point)); } void Plane::setCoefficients(float a, float b, float c, float d) { + // set the normal vector + _normal = glm::vec3(a,b,c); - // set the normal vector - normal = glm::vec3(a,b,c); - //compute the lenght of the vector - float l = normal.length(); - // normalize the vector - normal = glm::vec3(a/l,b/l,c/l); - // and divide d by th length as well - this->d = d/l; + //compute the lenght of the vector + float l = length(_normal); + + // normalize the vector + _normal = glm::vec3(a/l,b/l,c/l); + + // and divide d by th length as well + _dCoefficient = d/l; } -float Plane::distance(const glm::vec3 &p) { - return (d + vec3_innerProduct(normal,p)); +float Plane::distance(const glm::vec3 &point) const { + return (_dCoefficient + innerProduct(_normal,point)); } -void Plane::print() { - //printLog("Plane(");normal.print();printLog("# %f)",d); +void Plane::print() const { + printf("Plane - point (x=%f y=%f z=%f) normal (x=%f y=%f z=%f) d=%f\n", + _point.x, _point.y, _point.z, _normal.x, _normal.y, _normal.z, _dCoefficient); } diff --git a/libraries/voxels/src/Plane.h b/libraries/voxels/src/Plane.h index 5c23993dc9..8ce0e5042e 100755 --- a/libraries/voxels/src/Plane.h +++ b/libraries/voxels/src/Plane.h @@ -1,34 +1,43 @@ -////////////////////////////////////////////////////////////////////// -// Plane.h - inspired and modified from lighthouse3d.com // - +// Plane.h +// hifi +// +// Created by Brad Hefta-Gaub on 04/11/13. +// Originally from lighthouse3d. Modified to utilize glm::vec3 and clean up to our coding standards +// +// Simple plane class. +// #ifndef _PLANE_ #define _PLANE_ #include - class Plane { - public: + Plane(const glm::vec3 &v1, const glm::vec3 &v2, const glm::vec3 &v3) { set3Points(v1,v2,v3); } + Plane() : _normal(0,0,0), _point(0,0,0), _dCoefficient(0) {}; + ~Plane() {} ; - glm::vec3 normal,point; - float d; - - - Plane(const glm::vec3 &v1, const glm::vec3 &v2, const glm::vec3 &v3); - Plane(void); - ~Plane(); - + // methods for defining the plane void set3Points(const glm::vec3 &v1, const glm::vec3 &v2, const glm::vec3 &v3); void setNormalAndPoint(const glm::vec3 &normal, const glm::vec3 &point); void setCoefficients(float a, float b, float c, float d); - float distance(const glm::vec3 &p); - void print(); + // getters + const glm::vec3& getNormal() const { return _normal; }; + const glm::vec3& getPoint() const { return _point; }; + float getDCoefficient() const { return _dCoefficient; }; + // utilities + float distance(const glm::vec3 &point) const; + void print() const; + +private: + glm::vec3 _normal; + glm::vec3 _point; + float _dCoefficient; }; From a02a75f5166ee8fe43ed794481fffdd382f6e778 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sun, 21 Apr 2013 15:21:03 -0700 Subject: [PATCH 20/60] fix bug in definition of frustum planes, and general code cleanup - Fixed bug in definition of frustum planes, namely making sure the points are given in the correct order so that our plane normals point in correct direction - general code cleanup to match coding standard --- libraries/voxels/src/ViewFrustum.cpp | 52 ++++++++++++++++++++-------- libraries/voxels/src/ViewFrustum.h | 4 ++- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/libraries/voxels/src/ViewFrustum.cpp b/libraries/voxels/src/ViewFrustum.cpp index 704289d977..53371d5268 100644 --- a/libraries/voxels/src/ViewFrustum.cpp +++ b/libraries/voxels/src/ViewFrustum.cpp @@ -85,14 +85,23 @@ void ViewFrustum::calculate() { _nearBottomRight = _nearCenter - (_up * nearHalfHeight) + (_right * nearHalfWidth); // compute the six planes - // the function set3Points assumes that the points - // are given in counter clockwise order - _planes[TOPP].set3Points(_nearTopRight,_nearTopLeft,_farTopLeft); - _planes[BOTTOMP].set3Points(_nearBottomLeft,_nearBottomRight,_farBottomRight); - _planes[LEFTP].set3Points(_nearTopLeft,_nearBottomLeft,_farBottomLeft); - _planes[RIGHTP].set3Points(_nearBottomRight,_nearTopRight,_farBottomRight); - _planes[NEARP].set3Points(_nearTopLeft,_nearTopRight,_nearBottomRight); - _planes[FARP].set3Points(_farTopRight,_farTopLeft,_farBottomLeft); + // The planes are defined such that the normal points towards the inside of the view frustum. + // Testing if an object is inside the view frustum is performed by computing on which side of + // the plane the object resides. This can be done computing the signed distance from the point + // to the plane. If it is on the side that the normal is pointing, i.e. the signed distance + // is positive, then it is on the right side of the respective plane. If an object is on the + // right side of all six planes then the object is inside the frustum. + + // the function set3Points assumes that the points are given in counter clockwise order, assume you + // are inside the frustum, facing the plane. Start with any point, and go counter clockwise for + // three consecutive points + + _planes[TOP_PLANE ].set3Points(_nearTopRight,_nearTopLeft,_farTopLeft); + _planes[BOTTOM_PLANE].set3Points(_nearBottomLeft,_nearBottomRight,_farBottomRight); + _planes[LEFT_PLANE ].set3Points(_nearBottomLeft,_farBottomLeft,_farTopLeft); + _planes[RIGHT_PLANE ].set3Points(_farBottomRight,_nearBottomRight,_nearTopRight); + _planes[NEAR_PLANE ].set3Points(_nearBottomRight,_nearBottomLeft,_nearTopLeft); + _planes[FAR_PLANE ].set3Points(_farBottomLeft,_farBottomRight,_farTopRight); } @@ -135,11 +144,26 @@ void ViewFrustum::dump() { } +//enum { TOP_PLANE = 0, BOTTOM_PLANE, LEFT_PLANE, RIGHT_PLANE, NEAR_PLANE, FAR_PLANE }; +const char* ViewFrustum::debugPlaneName (int plane) const { + switch (plane) { + case TOP_PLANE: return "Top Plane"; + case BOTTOM_PLANE: return "Bottom Plane"; + case LEFT_PLANE: return "Left Plane"; + case RIGHT_PLANE: return "Right Plane"; + case NEAR_PLANE: return "Near Plane"; + case FAR_PLANE: return "Far Plane"; + } + return "Unknown"; +} + + int ViewFrustum::pointInFrustum(glm::vec3 &p) { int result = INSIDE; for(int i=0; i < 6; i++) { - if (_planes[i].distance(p) < 0) + if (_planes[i].distance(p) < 0) { return OUTSIDE; + } } return(result); } @@ -160,17 +184,17 @@ int ViewFrustum::sphereInFrustum(glm::vec3 ¢er, float radius) { int ViewFrustum::boxInFrustum(AABox &b) { -printf("ViewFrustum::boxInFrustum() box.corner=%f,%f,%f x=%f\n",b.corner.x,b.corner.y,b.corner.z,b.x); + printf("ViewFrustum::boxInFrustum() box.corner=%f,%f,%f x=%f\n",b.corner.x,b.corner.y,b.corner.z,b.x); int result = INSIDE; for(int i=0; i < 6; i++) { printf("plane[%d] -- point(%f,%f,%f) normal(%f,%f,%f) d=%f \n",i, - _planes[i].point.x, _planes[i].point.y, _planes[i].point.z, - _planes[i].normal.x, _planes[i].normal.y, _planes[i].normal.z, - _planes[i].d + _planes[i].getPoint().x, _planes[i].getPoint().y, _planes[i].getPoint().z, + _planes[i].getNormal().x, _planes[i].getNormal().y, _planes[i].getNormal().z, + _planes[i].getDCoefficient() ); - glm::vec3 normal = _planes[i].normal; + glm::vec3 normal = _planes[i].getNormal(); glm::vec3 boxVertexP = b.getVertexP(normal); float planeToBoxVertexPDistance = _planes[i].distance(boxVertexP); diff --git a/libraries/voxels/src/ViewFrustum.h b/libraries/voxels/src/ViewFrustum.h index 9b496544c5..5746f21cb8 100644 --- a/libraries/voxels/src/ViewFrustum.h +++ b/libraries/voxels/src/ViewFrustum.h @@ -45,9 +45,11 @@ private: glm::vec3 _nearTopRight; glm::vec3 _nearBottomLeft; glm::vec3 _nearBottomRight; - enum { TOPP = 0, BOTTOMP, LEFTP, RIGHTP, NEARP, FARP }; + enum { TOP_PLANE = 0, BOTTOM_PLANE, LEFT_PLANE, RIGHT_PLANE, NEAR_PLANE, FAR_PLANE }; Plane _planes[6]; // How will this be used? + const char* debugPlaneName (int plane) const; + public: // setters for camera attributes void setPosition (const glm::vec3& p) { _position = p; } From 3dc818d31e479eff88f844cabaab6d4d250ff33b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sun, 21 Apr 2013 15:22:36 -0700 Subject: [PATCH 21/60] Changed false colorization to use point in frustum for now, since that works --- interface/src/VoxelSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 93f9f414b3..005bd089a8 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -465,7 +465,7 @@ bool VoxelSystem::falseColorizeInViewOperation(VoxelNode* node, bool down, void* voxelBox.x, voxelBox.y, voxelBox.z); // If the voxel is outside of the view frustum, then false color it red - if (ViewFrustum::OUTSIDE == viewFrustum->boxInFrustum(voxelBox)) { + if (ViewFrustum::OUTSIDE == viewFrustum->pointInFrustum(voxelBox.corner)) { // Out of view voxels are colored RED unsigned char newR = 255; unsigned char newG = 0; From e93ece0f52eb06b2df3c57bd63adeacab0150692 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sun, 21 Apr 2013 19:45:54 -0700 Subject: [PATCH 22/60] Added support for NO_FALSE_COLOR define. - changed VoxelNode to have implementation option for NO_FALSE_COLOR Need some help from Stephen and/or Leo on how to make cmake support building the voxels library in NO_FALSE_COLOR mode for the server but keep false color support in the client --- libraries/voxels/src/VoxelNode.cpp | 8 +++++++- libraries/voxels/src/VoxelNode.h | 13 ++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/libraries/voxels/src/VoxelNode.cpp b/libraries/voxels/src/VoxelNode.cpp index 7cae90f744..4aef3a0fe8 100644 --- a/libraries/voxels/src/VoxelNode.cpp +++ b/libraries/voxels/src/VoxelNode.cpp @@ -19,7 +19,9 @@ VoxelNode::VoxelNode() { octalCode = NULL; +#ifdef HAS_FALSE_COLOR _falseColored = false; // assume true color +#endif // default pointers to child nodes to NULL for (int i = 0; i < 8; i++) { @@ -83,6 +85,9 @@ void VoxelNode::setColorFromAverageOfChildren() { setColor(newColor); } +// Note: !NO_FALSE_COLOR implementations of setFalseColor(), setFalseColored(), and setColor() here. +// the actual NO_FALSE_COLOR version are inline in the VoxelNode.h +#ifndef NO_FALSE_COLOR // !NO_FALSE_COLOR means, does have false color void VoxelNode::setFalseColor(colorPart red, colorPart green, colorPart blue) { _falseColored=true; _currentColor[0] = red; @@ -91,7 +96,7 @@ void VoxelNode::setFalseColor(colorPart red, colorPart green, colorPart blue) { _currentColor[3] = 1; // XXXBHG - False colors are always considered set } -void VoxelNode::setFalseColored(bool isFalseColored) { +void VoxelNode::setFalseColored(bool isFalseColored) { // if we were false colored, and are no longer false colored, then swap back if (_falseColored && !isFalseColored) { memcpy(&_currentColor,&_trueColor,sizeof(nodeColor)); @@ -107,6 +112,7 @@ void VoxelNode::setColor(const nodeColor& color) { memcpy(&_currentColor,&color,sizeof(nodeColor)); } } +#endif // will detect if children are leaves AND the same color // and in that case will delete the children and make this node diff --git a/libraries/voxels/src/VoxelNode.h b/libraries/voxels/src/VoxelNode.h index 42b4331440..cf644a1fd1 100644 --- a/libraries/voxels/src/VoxelNode.h +++ b/libraries/voxels/src/VoxelNode.h @@ -17,8 +17,10 @@ typedef unsigned char nodeColor[4]; class VoxelNode { private: nodeColor _trueColor; +#ifndef NO_FALSE_COLOR // !NO_FALSE_COLOR means, does have false color nodeColor _currentColor; bool _falseColored; +#endif public: VoxelNode(); ~VoxelNode(); @@ -32,13 +34,22 @@ public: VoxelNode *children[8]; bool isColored() const { return (_trueColor[3]==1); }; + +#ifndef NO_FALSE_COLOR // !NO_FALSE_COLOR means, does have false color void setFalseColor(colorPart red, colorPart green, colorPart blue); void setFalseColored(bool isFalseColored); bool getFalseColored() { return _falseColored; }; - void setColor(const nodeColor& color); const nodeColor& getTrueColor() const { return _trueColor; }; const nodeColor& getColor() const { return _currentColor; }; +#else + void setFalseColor(colorPart red, colorPart green, colorPart blue) { /* no op */ }; + void setFalseColored(bool isFalseColored) { /* no op */ }; + bool getFalseColored() { return false; }; + void setColor(const nodeColor& color) { memcpy(_trueColor,color,sizeof(nodeColor)); }; + const nodeColor& getTrueColor() const { return _trueColor; }; + const nodeColor& getColor() const { return _trueColor; }; +#endif void getAABox(AABox& box) const; }; From 358efb472ddcd2131eaf06f84e0bd5b3d7a6a8bf Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sun, 21 Apr 2013 22:46:13 -0700 Subject: [PATCH 23/60] Clean up AABox to coding standard, made several methods const - Cleaned up AABox to be consistent with the coding standard - converted some methods to const and fixed up callers --- interface/src/VoxelSystem.cpp | 8 +-- libraries/voxels/src/AABox.cpp | 87 +++++++++++----------------- libraries/voxels/src/AABox.h | 39 ++++++++----- libraries/voxels/src/ViewFrustum.cpp | 15 ++--- libraries/voxels/src/ViewFrustum.h | 6 +- libraries/voxels/src/VoxelNode.cpp | 10 +++- 6 files changed, 82 insertions(+), 83 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 005bd089a8..b2bcc701e0 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -460,12 +460,12 @@ bool VoxelSystem::falseColorizeInViewOperation(VoxelNode* node, bool down, void* voxelBox.scale(TREE_SCALE); - printf("voxelBox corner=(%f,%f,%f) x=%f y=%f z=%f\n", - voxelBox.corner.x, voxelBox.corner.y, voxelBox.corner.z, - voxelBox.x, voxelBox.y, voxelBox.z); + printf("voxelBox corner=(%f,%f,%f) x=%f\n", + voxelBox.getCorner().x, voxelBox.getCorner().y, voxelBox.getCorner().z, + voxelBox.getSize().x); // If the voxel is outside of the view frustum, then false color it red - if (ViewFrustum::OUTSIDE == viewFrustum->pointInFrustum(voxelBox.corner)) { + if (ViewFrustum::OUTSIDE == viewFrustum->pointInFrustum(voxelBox.getCorner())) { // Out of view voxels are colored RED unsigned char newR = 255; unsigned char newG = 0; diff --git a/libraries/voxels/src/AABox.cpp b/libraries/voxels/src/AABox.cpp index 4c2f18f863..0187bae853 100755 --- a/libraries/voxels/src/AABox.cpp +++ b/libraries/voxels/src/AABox.cpp @@ -1,85 +1,68 @@ -/* ------------------------------------------------------ - - Axis Aligned Boxes - Lighthouse3D - - -----------------------------------------------------*/ +// +// AABox.h - Axis Aligned Boxes +// hifi +// +// Added by Brad Hefta-Gaub on 04/11/13. +// Originally from lighthouse3d. Modified to utilize glm::vec3 and clean up to our coding standards +// +// Simple axis aligned box class. +// #include "AABox.h" -AABox::AABox(const glm::vec3& corner, float x, float y, float z) { - setBox(corner,x,y,z); -} - -AABox::AABox(void) { - corner.x = 0; corner.y = 0; corner.z = 0; - x = 1.0f; - y = 1.0f; - z = 1.0f; -} - - -AABox::~AABox() { - // nothing to do -} - - void AABox::scale(float scale) { - corner = corner*scale; - x *= scale; - y *= scale; - z *= scale; + _corner = _corner*scale; + _size = _size*scale; } -void AABox::setBox(const glm::vec3& corner, float x, float y, float z) { - this->corner = corner; - if (x < 0.0) { - x = -x; - this->corner.x -= x; +void AABox::setBox(const glm::vec3& corner, const glm::vec3& size) { + _corner = corner; + _size = size; + + // In the event that the caller gave us negative sizes, fix things up to be reasonable + if (_size.x < 0.0) { + _size.x = -size.x; + _corner.x -= _size.x; } - if (y < 0.0) { - y = -y; - this->corner.y -= y; + if (_size.y < 0.0) { + _size.y = -size.y; + _corner.y -= _size.y; } - if (z < 0.0) { - z = -z; - this->corner.z -= z; + if (_size.z < 0.0) { + _size.z = -size.z; + _corner.z -= _size.z; } - this->x = x; - this->y = y; - this->z = z; } - - -glm::vec3 AABox::getVertexP(const glm::vec3 &normal) { - glm::vec3 res = corner; +glm::vec3 AABox::getVertexP(const glm::vec3 &normal) const { + glm::vec3 res = _corner; if (normal.x > 0) - res.x += x; + res.x += _size.x; if (normal.y > 0) - res.y += y; + res.y += _size.y; if (normal.z > 0) - res.z += z; + res.z += _size.z; return(res); } -glm::vec3 AABox::getVertexN(const glm::vec3 &normal) { - glm::vec3 res = corner; +glm::vec3 AABox::getVertexN(const glm::vec3 &normal) const { + glm::vec3 res = _corner; if (normal.x < 0) - res.x += x; + res.x += _size.x; if (normal.y < 0) - res.y += y; + res.y += _size.y; if (normal.z < 0) - res.z += z; + res.z += _size.z; return(res); } diff --git a/libraries/voxels/src/AABox.h b/libraries/voxels/src/AABox.h index a00cda24c8..0a69b8608d 100755 --- a/libraries/voxels/src/AABox.h +++ b/libraries/voxels/src/AABox.h @@ -1,9 +1,12 @@ -/* ------------------------------------------------------ - - Axis Aligned Boxes - Lighthouse3D - - -----------------------------------------------------*/ - +// +// AABox.h - Axis Aligned Boxes +// hifi +// +// Added by Brad Hefta-Gaub on 04/11/13. +// Originally from lighthouse3d. Modified to utilize glm::vec3 and clean up to our coding standards +// +// Simple axis aligned box class. +// #ifndef _AABOX_ #define _AABOX_ @@ -15,20 +18,26 @@ class AABox public: - glm::vec3 corner; - float x,y,z; + AABox(const glm::vec3& corner, float x, float y, float z) : _corner(corner), _size(x,y,z) { }; + AABox(const glm::vec3& corner, const glm::vec3& size) : _corner(corner), _size(size) { }; + AABox() : _corner(0,0,0), _size(0,0,0) { } + ~AABox() { } - AABox(const glm::vec3 &corner, float x, float y, float z); - AABox(void); - ~AABox(); - - void setBox(const glm::vec3& corner, float x, float y, float z); + void setBox(const glm::vec3& corner, float x, float y, float z) { setBox(corner,glm::vec3(x,y,z)); }; + void setBox(const glm::vec3& corner, const glm::vec3& size); // for use in frustum computations - glm::vec3 getVertexP(const glm::vec3& normal); - glm::vec3 getVertexN(const glm::vec3& normal); + glm::vec3 getVertexP(const glm::vec3& normal) const; + glm::vec3 getVertexN(const glm::vec3& normal) const; void scale(float scale); + + const glm::vec3& getCorner() const { return _corner; }; + const glm::vec3& getSize() const { return _size; }; + +private: + glm::vec3 _corner; + glm::vec3 _size; }; diff --git a/libraries/voxels/src/ViewFrustum.cpp b/libraries/voxels/src/ViewFrustum.cpp index 53371d5268..9fdeafa449 100644 --- a/libraries/voxels/src/ViewFrustum.cpp +++ b/libraries/voxels/src/ViewFrustum.cpp @@ -158,17 +158,17 @@ const char* ViewFrustum::debugPlaneName (int plane) const { } -int ViewFrustum::pointInFrustum(glm::vec3 &p) { +int ViewFrustum::pointInFrustum(const glm::vec3& point) { int result = INSIDE; for(int i=0; i < 6; i++) { - if (_planes[i].distance(p) < 0) { + if (_planes[i].distance(point) < 0) { return OUTSIDE; } } return(result); } -int ViewFrustum::sphereInFrustum(glm::vec3 ¢er, float radius) { +int ViewFrustum::sphereInFrustum(const glm::vec3& center, float radius) { int result = INSIDE; float distance; for(int i=0; i < 6; i++) { @@ -182,9 +182,10 @@ int ViewFrustum::sphereInFrustum(glm::vec3 ¢er, float radius) { } -int ViewFrustum::boxInFrustum(AABox &b) { +int ViewFrustum::boxInFrustum(const AABox& box) { - printf("ViewFrustum::boxInFrustum() box.corner=%f,%f,%f x=%f\n",b.corner.x,b.corner.y,b.corner.z,b.x); + printf("ViewFrustum::boxInFrustum() box.corner=%f,%f,%f x=%f\n", + box.getCorner().x,box.getCorner().y,box.getCorner().z,box.getSize().x); int result = INSIDE; for(int i=0; i < 6; i++) { @@ -195,10 +196,10 @@ int ViewFrustum::boxInFrustum(AABox &b) { ); glm::vec3 normal = _planes[i].getNormal(); - glm::vec3 boxVertexP = b.getVertexP(normal); + glm::vec3 boxVertexP = box.getVertexP(normal); float planeToBoxVertexPDistance = _planes[i].distance(boxVertexP); - glm::vec3 boxVertexN = b.getVertexN(normal); + glm::vec3 boxVertexN = box.getVertexN(normal); float planeToBoxVertexNDistance = _planes[i].distance(boxVertexN); diff --git a/libraries/voxels/src/ViewFrustum.h b/libraries/voxels/src/ViewFrustum.h index 5746f21cb8..6114953099 100644 --- a/libraries/voxels/src/ViewFrustum.h +++ b/libraries/voxels/src/ViewFrustum.h @@ -94,9 +94,9 @@ public: enum {OUTSIDE, INTERSECT, INSIDE}; - int pointInFrustum(glm::vec3 &p); - int sphereInFrustum(glm::vec3 ¢er, float radius); - int boxInFrustum(AABox &b); + int pointInFrustum(const glm::vec3& point); + int sphereInFrustum(const glm::vec3& center, float radius); + int boxInFrustum(const AABox& box); }; diff --git a/libraries/voxels/src/VoxelNode.cpp b/libraries/voxels/src/VoxelNode.cpp index 4aef3a0fe8..9fab2c1092 100644 --- a/libraries/voxels/src/VoxelNode.cpp +++ b/libraries/voxels/src/VoxelNode.cpp @@ -41,12 +41,18 @@ VoxelNode::~VoxelNode() { } void VoxelNode::getAABox(AABox& box) const { + + glm::vec3 corner; + glm::vec3 size; + // copy corner into box - copyFirstVertexForCode(octalCode,(float*)&box.corner); + copyFirstVertexForCode(octalCode,(float*)&corner); // this tells you the "size" of the voxel float voxelScale = 1 / powf(2, *octalCode); - box.x = box.y = box.z = voxelScale; + size = glm::vec3(voxelScale,voxelScale,voxelScale); + + box.setBox(corner,size); } void VoxelNode::addChildAtIndex(int childIndex) { From 400ecf6b86c2b096c93bbea9dd093fdf5ca05011 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sun, 21 Apr 2013 22:57:01 -0700 Subject: [PATCH 24/60] Convert over to standard glm functions for length, normalize, cross, and dot product --- libraries/voxels/src/Plane.cpp | 42 ++++++---------------------------- 1 file changed, 7 insertions(+), 35 deletions(-) diff --git a/libraries/voxels/src/Plane.cpp b/libraries/voxels/src/Plane.cpp index 10d1e2fb6b..a5dc9a93bf 100755 --- a/libraries/voxels/src/Plane.cpp +++ b/libraries/voxels/src/Plane.cpp @@ -16,34 +16,6 @@ using voxels_lib::printLog; // These are some useful utilities that vec3 is missing -float length(const glm::vec3& v) { - return((float)sqrt(v.x * v.x + v.y * v.y + v.z * v.z)); -} - -void normalize(glm::vec3& v) { - float len; - len = length(v); - if (len) { - v.x /= len;; - v.y /= len; - v.z /= len; - } -} - -// cross product -glm::vec3 crossProduct(const glm::vec3& lhs, const glm::vec3& rhs) { - glm::vec3 result; - result.x = lhs.y * rhs.z - lhs.z * rhs.y; - result.y = lhs.z * rhs.x - lhs.x * rhs.z; - result.z = lhs.x * rhs.y - lhs.y * rhs.x; - return result; -} - - -float innerProduct(const glm::vec3& v1,const glm::vec3& v2) { - return (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z); -} - void printVec3(const char* name, const glm::vec3& v) { printf("%s x=%f y=%f z=%f\n", name, v.x, v.y, v.z); } @@ -55,23 +27,23 @@ void Plane::set3Points(const glm::vec3 &v1, const glm::vec3 &v2, const glm::vec3 linev1v3 = v3 - v1; // this will be perpendicular to both lines - _normal = crossProduct(linev1v2,linev1v3); - normalize(_normal); + _normal = glm::cross(linev1v2,linev1v3); + glm::normalize(_normal); // this is a point on the plane _point = v2; // the D coefficient from the form Ax+By+Cz=D - _dCoefficient = -(innerProduct(_normal,_point)); + _dCoefficient = -(glm::dot(_normal,_point)); } void Plane::setNormalAndPoint(const glm::vec3 &normal, const glm::vec3 &point) { _point = point; _normal = normal; - normalize(_normal); + glm::normalize(_normal); // the D coefficient from the form Ax+By+Cz=D - _dCoefficient = -(innerProduct(_normal,_point)); + _dCoefficient = -(glm::dot(_normal,_point)); } void Plane::setCoefficients(float a, float b, float c, float d) { @@ -79,7 +51,7 @@ void Plane::setCoefficients(float a, float b, float c, float d) { _normal = glm::vec3(a,b,c); //compute the lenght of the vector - float l = length(_normal); + float l = glm::length(_normal); // normalize the vector _normal = glm::vec3(a/l,b/l,c/l); @@ -89,7 +61,7 @@ void Plane::setCoefficients(float a, float b, float c, float d) { } float Plane::distance(const glm::vec3 &point) const { - return (_dCoefficient + innerProduct(_normal,point)); + return (_dCoefficient + glm::dot(_normal,point)); } void Plane::print() const { From 2e402c3b17e60bbe8c8a030557fef4c957790b8e Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 22 Apr 2013 10:29:14 -0700 Subject: [PATCH 25/60] added - and then removed - some orientation-related tests --- interface/src/Head.cpp | 62 +++++++++++++++++++++++++++--------------- interface/src/Head.h | 4 ++- interface/src/main.cpp | 2 -- 3 files changed, 43 insertions(+), 25 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 821ff2e111..50ebeed4ae 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -47,7 +47,8 @@ unsigned int iris_texture_height = 256; Head::Head(bool isMine) { - _orientation.setToIdentity(); + _orientation.setToIdentity(); + _velocity = glm::vec3( 0.0, 0.0, 0.0 ); _thrust = glm::vec3( 0.0, 0.0, 0.0 ); _rotation = glm::quat( 0.0f, 0.0f, 0.0f, 0.0f ); @@ -163,8 +164,7 @@ Head::Head(const Head &otherAvatar) { _movedHandOffset = otherAvatar._movedHandOffset; _usingBodySprings = otherAvatar._usingBodySprings; _springForce = otherAvatar._springForce; - _springVelocityDecay = otherAvatar._springVelocityDecay; - + _springVelocityDecay = otherAvatar._springVelocityDecay; _orientation.set( otherAvatar._orientation ); //for (int o=0;ogetLinkedData() == NULL) { newAgent->setLinkedData(new Head(false)); From 38f8769ff648a09650a280d0cc48cdfbe76a06cf Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 22 Apr 2013 11:39:38 -0700 Subject: [PATCH 26/60] stub setup for eve --- CMakeLists.txt | 1 + eve/CMakeLists.txt | 13 +++++++++++++ eve/src/main.cpp | 13 +++++++++++++ 3 files changed, 27 insertions(+) create mode 100644 eve/CMakeLists.txt create mode 100644 eve/src/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 526ba77653..3923f543fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,7 @@ project(hifi) add_subdirectory(avatar-mixer) add_subdirectory(audio-mixer) add_subdirectory(domain-server) +add_subdirectory(eve) add_subdirectory(interface) add_subdirectory(injector) add_subdirectory(space-server) diff --git a/eve/CMakeLists.txt b/eve/CMakeLists.txt new file mode 100644 index 0000000000..b62368f6d3 --- /dev/null +++ b/eve/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 2.8) + +set(ROOT_DIR ..) +set(MACRO_DIR ${ROOT_DIR}/cmake/macros) + +set(TARGET_NAME eve) + +include(${MACRO_DIR}/SetupHifiProject.cmake) +setup_hifi_project(${TARGET_NAME}) + +# link the shared hifi library +include(${MACRO_DIR}/LinkHifiLibrary.cmake) +link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) \ No newline at end of file diff --git a/eve/src/main.cpp b/eve/src/main.cpp new file mode 100644 index 0000000000..05159dd9c0 --- /dev/null +++ b/eve/src/main.cpp @@ -0,0 +1,13 @@ +// +// main.cpp +// eve +// +// Created by Stephen Birarda on 4/22/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +int main(int argc, char* argv[]) { + +} + + From c68ec079eba32ed779d1feb436c828a88f959983 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 22 Apr 2013 11:54:24 -0700 Subject: [PATCH 27/60] rename AGENT_TYPE_INTERFACE to AGENT_TYPE_AVATAR, more stubbing for eve --- eve/src/main.cpp | 48 ++++++++++++++++++++++++++++++- interface/src/Head.cpp | 2 +- interface/src/main.cpp | 2 +- libraries/shared/src/Agent.cpp | 2 +- libraries/shared/src/AgentTypes.h | 2 +- voxel-server/src/main.cpp | 8 +++--- 6 files changed, 55 insertions(+), 9 deletions(-) diff --git a/eve/src/main.cpp b/eve/src/main.cpp index 05159dd9c0..0533ffe7ea 100644 --- a/eve/src/main.cpp +++ b/eve/src/main.cpp @@ -6,8 +6,54 @@ // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // -int main(int argc, char* argv[]) { +#include +#include +#include +const int EVE_AGENT_LIST_PORT = 55441; + +bool stopReceiveAgentDataThread; + +void *receiveAgentData(void *args) +{ + sockaddr senderAddress; + ssize_t bytesReceived; + unsigned char incomingPacket[MAX_PACKET_SIZE]; + + while (!::stopReceiveAgentDataThread) { + if (AgentList::getInstance()->getAgentSocket().receive(&senderAddress, incomingPacket, &bytesReceived)) { + + // we're going to ignore any data that isn't the agent list from the domain server + // ex: the avatar mixer will be sending us the position of other agents + switch (incomingPacket[0]) { + case PACKET_HEADER_DOMAIN: + AgentList::getInstance()->processAgentData(&senderAddress, incomingPacket, bytesReceived); + break; + } + } + } + + pthread_exit(0); + return NULL; +} + +int main(int argc, char* argv[]) { + // create an AgentList instance to handle communication with other agents + AgentList *agentList = AgentList::createInstance(AGENT_TYPE_AVATAR, EVE_AGENT_LIST_PORT); + + // start telling the domain server that we are alive + agentList->startDomainServerCheckInThread(); + + // start the agent list thread that will kill off agents when they stop talking + agentList->startSilentAgentRemovalThread(); + + // start the ping thread that hole punches to create an active connection to other agents + agentList->startPingUnknownAgentsThread(); + + // stop the agent list's threads + agentList->stopDomainServerCheckInThread(); + agentList->stopPingUnknownAgentsThread(); + agentList->stopSilentAgentRemovalThread(); } diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 50ebeed4ae..abba74eb5f 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -331,7 +331,7 @@ void Head::simulate(float deltaTime) { for(std::vector::iterator agent = agentList->getAgents().begin(); agent != agentList->getAgents().end(); agent++) { - if (( agent->getLinkedData() != NULL && ( agent->getType() == AGENT_TYPE_INTERFACE ) )) { + if (( agent->getLinkedData() != NULL && ( agent->getType() == AGENT_TYPE_AVATAR ) )) { Head *otherAvatar = (Head *)agent->getLinkedData(); // when this is working, I will grab the position here... diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 488f9f29b1..aad8a9be74 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -1630,7 +1630,7 @@ int main(int argc, const char * argv[]) return EXIT_SUCCESS; } - AgentList::createInstance(AGENT_TYPE_INTERFACE); + AgentList::createInstance(AGENT_TYPE_AVATAR); gettimeofday(&applicationStartupTime, NULL); const char* domainIP = getCmdOption(argc, argv, "--domain"); diff --git a/libraries/shared/src/Agent.cpp b/libraries/shared/src/Agent.cpp index d05afe5e26..819e4c185f 100644 --- a/libraries/shared/src/Agent.cpp +++ b/libraries/shared/src/Agent.cpp @@ -132,7 +132,7 @@ const char* Agent::getTypeName() const { case AGENT_TYPE_VOXEL: name = AGENT_TYPE_NAME_VOXEL; break; - case AGENT_TYPE_INTERFACE: + case AGENT_TYPE_AVATAR: name = AGENT_TYPE_NAME_INTERFACE; break; case AGENT_TYPE_AUDIO_MIXER: diff --git a/libraries/shared/src/AgentTypes.h b/libraries/shared/src/AgentTypes.h index a5d79efac8..c43af79446 100644 --- a/libraries/shared/src/AgentTypes.h +++ b/libraries/shared/src/AgentTypes.h @@ -20,7 +20,7 @@ // Agent Type Codes const char AGENT_TYPE_DOMAIN = 'D'; const char AGENT_TYPE_VOXEL = 'V'; -const char AGENT_TYPE_INTERFACE = 'I'; // could also be injector??? +const char AGENT_TYPE_AVATAR = 'I'; // could also be injector??? const char AGENT_TYPE_AUDIO_MIXER = 'M'; const char AGENT_TYPE_AVATAR_MIXER = 'W'; diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 8f6bab7dc7..942fbb63b9 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -345,7 +345,7 @@ int main(int argc, const char * argv[]) // Now send this to the connected agents so they know to delete printf("rebroadcasting delete voxel message to connected agents... agentList.broadcastToAgents()\n"); - agentList->broadcastToAgents(packetData,receivedBytes, &AGENT_TYPE_INTERFACE, 1); + agentList->broadcastToAgents(packetData,receivedBytes, &AGENT_TYPE_AVATAR, 1); } if (packetData[0] == PACKET_HEADER_Z_COMMAND) { @@ -373,14 +373,14 @@ int main(int argc, const char * argv[]) // Now send this to the connected agents so they can also process these messages printf("rebroadcasting Z message to connected agents... agentList.broadcastToAgents()\n"); - agentList->broadcastToAgents(packetData,receivedBytes, &AGENT_TYPE_INTERFACE, 1); + agentList->broadcastToAgents(packetData,receivedBytes, &AGENT_TYPE_AVATAR, 1); } - // If we got a PACKET_HEADER_HEAD_DATA, then we're talking to an AGENT_TYPE_INTERFACE, and we + // If we got a PACKET_HEADER_HEAD_DATA, then we're talking to an AGENT_TYPE_AVATAR, and we // need to make sure we have it in our agentList. if (packetData[0] == PACKET_HEADER_HEAD_DATA) { if (agentList->addOrUpdateAgent(&agentPublicAddress, &agentPublicAddress, - AGENT_TYPE_INTERFACE, + AGENT_TYPE_AVATAR, agentList->getLastAgentId())) { agentList->increaseAgentId(); } From a558597b6a3f490891ebae986baf7ea0427e299b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 22 Apr 2013 13:10:21 -0700 Subject: [PATCH 28/60] complete an initial version of eve that sits at 0,0,0 --- eve/CMakeLists.txt | 11 ++++- eve/src/main.cpp | 72 +++++++++++++++++++++++++++--- interface/CMakeLists.txt | 1 - libraries/shared/src/AgentList.cpp | 3 +- voxel-server/CMakeLists.txt | 6 +-- 5 files changed, 76 insertions(+), 17 deletions(-) diff --git a/eve/CMakeLists.txt b/eve/CMakeLists.txt index b62368f6d3..cb38529b2d 100644 --- a/eve/CMakeLists.txt +++ b/eve/CMakeLists.txt @@ -3,11 +3,18 @@ cmake_minimum_required(VERSION 2.8) set(ROOT_DIR ..) set(MACRO_DIR ${ROOT_DIR}/cmake/macros) +# setup for find modules +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/modules/") + set(TARGET_NAME eve) include(${MACRO_DIR}/SetupHifiProject.cmake) setup_hifi_project(${TARGET_NAME}) -# link the shared hifi library +include(${MACRO_DIR}/IncludeGLM.cmake) +include_glm(${TARGET_NAME} ${ROOT_DIR}) + +# link the required hifi libraries include(${MACRO_DIR}/LinkHifiLibrary.cmake) -link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) \ No newline at end of file +link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) +link_hifi_library(avatars ${TARGET_NAME} ${ROOT_DIR}) \ No newline at end of file diff --git a/eve/src/main.cpp b/eve/src/main.cpp index 0533ffe7ea..1078f48fdc 100644 --- a/eve/src/main.cpp +++ b/eve/src/main.cpp @@ -6,11 +6,16 @@ // Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // +#include + +#include #include -#include #include +#include +#include const int EVE_AGENT_LIST_PORT = 55441; +const float DATA_SEND_INTERVAL_MSECS = 10; bool stopReceiveAgentDataThread; @@ -20,14 +25,26 @@ void *receiveAgentData(void *args) ssize_t bytesReceived; unsigned char incomingPacket[MAX_PACKET_SIZE]; + AgentList *agentList = AgentList::getInstance(); + Agent *avatarMixer = NULL; + while (!::stopReceiveAgentDataThread) { - if (AgentList::getInstance()->getAgentSocket().receive(&senderAddress, incomingPacket, &bytesReceived)) { - - // we're going to ignore any data that isn't the agent list from the domain server - // ex: the avatar mixer will be sending us the position of other agents + if (agentList->getAgentSocket().receive(&senderAddress, incomingPacket, &bytesReceived)) { switch (incomingPacket[0]) { - case PACKET_HEADER_DOMAIN: - AgentList::getInstance()->processAgentData(&senderAddress, incomingPacket, bytesReceived); + case PACKET_HEADER_BULK_AVATAR_DATA: + // this is the positional data for other agents + // eve doesn't care about this for now, so let's just update the receive time for the + // avatar mixer - this makes sure it won't be killed during silent agent removal + avatarMixer = agentList->soloAgentOfType(AGENT_TYPE_AVATAR_MIXER); + + if (avatarMixer != NULL) { + avatarMixer->setLastRecvTimeUsecs(usecTimestampNow()); + } + + break; + default: + // have the agentList handle list of agents from DS, replies from other agents, etc. + agentList->processAgentData(&senderAddress, incomingPacket, bytesReceived); break; } } @@ -50,6 +67,47 @@ int main(int argc, char* argv[]) { // start the ping thread that hole punches to create an active connection to other agents agentList->startPingUnknownAgentsThread(); + pthread_t receiveAgentDataThread; + pthread_create(&receiveAgentDataThread, NULL, receiveAgentData, NULL); + + // create an AvatarData object, "eve" + AvatarData eve = AvatarData(); + + unsigned char broadcastPacket[MAX_PACKET_SIZE]; + broadcastPacket[0] = PACKET_HEADER_HEAD_DATA; + + int numBytesToSend = 0; + + timeval thisSend; + double numMicrosecondsSleep = 0; + + while (true) { + // update the thisSend timeval to the current time + gettimeofday(&thisSend, NULL); + + // find the current avatar mixer + Agent *avatarMixer = agentList->soloAgentOfType(AGENT_TYPE_AVATAR_MIXER); + + // make sure we actually have an avatar mixer with an active socket + if (avatarMixer != NULL && avatarMixer->getActiveSocket() != NULL) { + // use the getBroadcastData method in the AvatarData class to populate the broadcastPacket buffer + numBytesToSend = eve.getBroadcastData((broadcastPacket + 1)); + + + // use the UDPSocket instance attached to our agent list to send avatar data to mixer + agentList->getAgentSocket().send(avatarMixer->getActiveSocket(), broadcastPacket, numBytesToSend); + } + + // sleep for the correct amount of time to have data send be consistently timed + if ((numMicrosecondsSleep = (DATA_SEND_INTERVAL_MSECS * 1000) - (usecTimestampNow() - usecTimestamp(&thisSend))) > 0) { + usleep(numMicrosecondsSleep); + } + } + + // stop the receive agent data thread + stopReceiveAgentDataThread = true; + pthread_join(receiveAgentDataThread, NULL); + // stop the agent list's threads agentList->stopDomainServerCheckInThread(); agentList->stopPingUnknownAgentsThread(); diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index de9b31c9df..e4e8dc1614 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -8,7 +8,6 @@ project(${TARGET_NAME}) # setup for find modules set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/modules/") -set(GLM_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external) set(LODEPNG_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/LodePNG) set(PORTAUDIO_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external/portaudio) diff --git a/libraries/shared/src/AgentList.cpp b/libraries/shared/src/AgentList.cpp index 5316eee79c..b89c9aa70c 100644 --- a/libraries/shared/src/AgentList.cpp +++ b/libraries/shared/src/AgentList.cpp @@ -228,7 +228,6 @@ bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, if (agent == agents.end()) { // we didn't have this agent, so add them - Agent newAgent = Agent(publicSocket, localSocket, agentType, agentId); if (socketMatch(publicSocket, localSocket)) { @@ -281,7 +280,7 @@ void AgentList::broadcastToAgents(unsigned char *broadcastData, size_t dataBytes void AgentList::handlePingReply(sockaddr *agentAddress) { for(std::vector::iterator agent = agents.begin(); agent != agents.end(); agent++) { // check both the public and local addresses for each agent to see if we find a match - // prioritize the private address so that we prune erroneous local matches + // prioritize the private address so that we prune erroneous local matches if (socketMatch(agent->getPublicSocket(), agentAddress)) { agent->activatePublicSocket(); break; diff --git a/voxel-server/CMakeLists.txt b/voxel-server/CMakeLists.txt index 99b72be9cb..88aad84af6 100644 --- a/voxel-server/CMakeLists.txt +++ b/voxel-server/CMakeLists.txt @@ -7,7 +7,6 @@ set(MACRO_DIR ${ROOT_DIR}/cmake/macros) # setup for find modules set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/modules/") -set(GLM_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external) # set up the external glm library include(${MACRO_DIR}/IncludeGLM.cmake) @@ -22,7 +21,4 @@ include(${MACRO_DIR}/LinkHifiLibrary.cmake) link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) # link in the hifi voxels library -link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR}) - -# find required libraries -find_package(GLM REQUIRED) +link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR}) \ No newline at end of file From 736eb335a963184013451429ea70fe8a7a791dc1 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Mon, 22 Apr 2013 13:12:17 -0700 Subject: [PATCH 29/60] Added stats at upper right for servers and avatars separately. --- interface/src/main.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 8712700efc..a47936ffd3 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -983,11 +983,18 @@ void display(void) menu.render(WIDTH,HEIGHT); } - // Draw number of nearby people always + // Stats at upper right of screen about who domain server is telling us about glPointSize(1.0f); char agents[100]; - sprintf(agents, "Agents: %ld\n", AgentList::getInstance()->getAgents().size()); - drawtext(WIDTH-100,20, 0.10, 0, 1.0, 0, agents, 1, 0, 0); + + int totalAgents = AgentList::getInstance()->getAgents().size(); + int totalAvatars = 0, totalServers = 0; + for (int i = 0; i < totalAgents; i++) { + if (AgentList::getInstance()->getAgents()[i].getType() == AGENT_TYPE_INTERFACE) totalAvatars++; + else totalServers++; + } + sprintf(agents, "Servers: %d, Avatars: %d\n", totalServers, totalAvatars); + drawtext(WIDTH-150,20, 0.10, 0, 1.0, 0, agents, 1, 0, 0); if (::paintOn) { From b7d6ce9747871715c8f91fc04dc131fdaf6d3b14 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 22 Apr 2013 13:15:46 -0700 Subject: [PATCH 30/60] fixed avatar hand position by making avatars simulate all the time,and also fixing logic of _isMine --- interface/src/Head.cpp | 133 ++++++++++++++++++++++------------------- interface/src/Head.h | 11 ++-- interface/src/main.cpp | 20 ++++--- 3 files changed, 87 insertions(+), 77 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 50ebeed4ae..24d04b2c7b 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -57,13 +57,14 @@ Head::Head(bool isMine) { _bodyPitch = 0.0; _bodyRoll = 0.0; _bodyYawDelta = 0.0; - _triggeringAction = false; + _mousePressed = false; _mode = AVATAR_MODE_STANDING; _isMine = isMine; _maxArmLength = 0.0; //_transmitterTimer = 0; _transmitterHz = 0.0; _transmitterPackets = 0; + _numOtherAvatarsInView = 0; initializeSkeleton(); @@ -114,7 +115,8 @@ Head::Head(bool isMine) { _head.noise = 0; _movedHandOffset = glm::vec3( 0.0, 0.0, 0.0 ); - _usingBodySprings = false; +_usingBodySprings = true; +//_usingBodySprings = false; _springForce = 6.0f; _springVelocityDecay = 16.0f; _renderYaw = 0.0; @@ -133,11 +135,11 @@ Head::Head(bool isMine) { //-------------------------------------------------- // test... just slam them into random positions... //-------------------------------------------------- - _DEBUG_otherAvatarListPosition[ 0 ] = glm::vec3( 0.0f, 0.3f, 2.0f ); - _DEBUG_otherAvatarListPosition[ 1 ] = glm::vec3( 4.0f, 0.3f, 2.0f ); - _DEBUG_otherAvatarListPosition[ 2 ] = glm::vec3( 2.0f, 0.3f, 2.0f ); - _DEBUG_otherAvatarListPosition[ 3 ] = glm::vec3( 1.0f, 0.3f, -4.0f ); - _DEBUG_otherAvatarListPosition[ 4 ] = glm::vec3( -2.0f, 0.3f, -2.0f ); + _otherAvatarHandPosition[ 0 ] = glm::vec3( 0.0f, 0.3f, 2.0f ); + _otherAvatarHandPosition[ 1 ] = glm::vec3( 4.0f, 0.3f, 2.0f ); + _otherAvatarHandPosition[ 2 ] = glm::vec3( 2.0f, 0.3f, 2.0f ); + _otherAvatarHandPosition[ 3 ] = glm::vec3( 1.0f, 0.3f, -4.0f ); + _otherAvatarHandPosition[ 4 ] = glm::vec3( -2.0f, 0.3f, -2.0f ); } Head::Head(const Head &otherAvatar) { @@ -150,7 +152,7 @@ Head::Head(const Head &otherAvatar) { _bodyPitch = otherAvatar._bodyPitch; _bodyRoll = otherAvatar._bodyRoll; _bodyYawDelta = otherAvatar._bodyYawDelta; - _triggeringAction = otherAvatar._triggeringAction; + _mousePressed = otherAvatar._mousePressed; _mode = otherAvatar._mode; _isMine = otherAvatar._isMine; _renderYaw = otherAvatar._renderYaw; @@ -305,8 +307,8 @@ void Head::setLeanSideways(float dist){ _head.leanSideways = dist; } -void Head::setTriggeringAction( bool d ) { - _triggeringAction = d; +void Head::setMousePressed( bool d ) { + _mousePressed = d; } @@ -325,21 +327,38 @@ void Head::simulate(float deltaTime) { _closestOtherAvatar = -1; float closestDistance = 10000.0f; - /* AgentList * agentList = AgentList::getInstance(); + + _numOtherAvatarsInView =0; for(std::vector::iterator agent = agentList->getAgents().begin(); agent != agentList->getAgents().end(); agent++) { if (( agent->getLinkedData() != NULL && ( agent->getType() == AGENT_TYPE_INTERFACE ) )) { Head *otherAvatar = (Head *)agent->getLinkedData(); - - // when this is working, I will grab the position here... - //glm::vec3 otherAvatarPosition = otherAvatar->getBodyPosition(); + + if ( _numOtherAvatarsInView < MAX_OTHER_AVATARS ) { + + //----------------------------------------------------------- + // test other avatar hand position for proximity... + //----------------------------------------------------------- + _otherAvatarHandPosition[ _numOtherAvatarsInView ] = otherAvatar->getBonePosition( AVATAR_BONE_RIGHT_HAND ); + glm::vec3 v( _bone[ AVATAR_BONE_RIGHT_SHOULDER ].position ); + v -= _otherAvatarHandPosition[ _numOtherAvatarsInView ]; + + float distance = glm::length( v ); + if ( distance < _maxArmLength ) { + if ( distance < closestDistance ) { + closestDistance = distance; + _closestOtherAvatar = _numOtherAvatarsInView; + _numOtherAvatarsInView++; + } + } + } } } - */ + /* ///for testing only (prior to having real avs working) for (int o=0; ogetLinkedData() != NULL) { Head *avatar = (Head *)agent->getLinkedData(); //glPushMatrix(); + +//printf( "rendering remote avatar\n" ); + avatar->render(0); //glPopMatrix(); } @@ -1390,7 +1393,6 @@ void key(unsigned char k, int x, int y) { myAvatar.setNoise(0); } - } if (k == 'h') { @@ -1467,13 +1469,12 @@ void idle(void) { // update behaviors for avatar hand movement updateHandController( mouseX, mouseY ); - // when the mouse is being pressed, an 'action' is being - // triggered in the avatar. The action is context-based. + // tell my avatar if the mouse is being pressed... if ( mousePressed == 1 ) { - myAvatar.setTriggeringAction( true ); + myAvatar.setMousePressed( true ); } else { - myAvatar.setTriggeringAction( false ); + myAvatar.setMousePressed( false ); } // walking triggers the handController to stop @@ -1486,7 +1487,6 @@ void idle(void) { // updateAvatar( 1.f/FPS ); - //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++) @@ -1494,11 +1494,13 @@ void idle(void) { if (agent->getLinkedData() != NULL) { Head *avatar = (Head *)agent->getLinkedData(); + +//printf( "simulating remote avatar\n" ); + avatar->simulate(deltaTime); } } - //updateAvatarHand(1.f/FPS); field.simulate (deltaTime); From 7d52af6fd4d846cb2bd64ad40b3a960e0cfadd7e Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Mon, 22 Apr 2013 13:20:12 -0700 Subject: [PATCH 31/60] Fixed per stephen --- interface/src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index a47936ffd3..2285d14bb9 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -990,8 +990,8 @@ void display(void) int totalAgents = AgentList::getInstance()->getAgents().size(); int totalAvatars = 0, totalServers = 0; for (int i = 0; i < totalAgents; i++) { - if (AgentList::getInstance()->getAgents()[i].getType() == AGENT_TYPE_INTERFACE) totalAvatars++; - else totalServers++; + (AgentList::getInstance()->getAgents()[i].getType() == AGENT_TYPE_INTERFACE) + ? totalAvatars++ : totalServers++; } sprintf(agents, "Servers: %d, Avatars: %d\n", totalServers, totalAvatars); drawtext(WIDTH-150,20, 0.10, 0, 1.0, 0, agents, 1, 0, 0); From 3016e5665f4c1982fac84379c44362efed277831 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 22 Apr 2013 13:22:48 -0700 Subject: [PATCH 32/60] move eve away from the origin --- eve/src/main.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/eve/src/main.cpp b/eve/src/main.cpp index 1078f48fdc..a6fb867af2 100644 --- a/eve/src/main.cpp +++ b/eve/src/main.cpp @@ -73,6 +73,9 @@ int main(int argc, char* argv[]) { // create an AvatarData object, "eve" AvatarData eve = AvatarData(); + // move eve away from the origin + eve.setBodyPosition(glm::vec3(3, 0, -3)); + unsigned char broadcastPacket[MAX_PACKET_SIZE]; broadcastPacket[0] = PACKET_HEADER_HEAD_DATA; From f4d5774e693175711049938c8329477b6f3f973e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 22 Apr 2013 13:55:59 -0700 Subject: [PATCH 33/60] change eve's orientation and hand position --- eve/src/main.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/eve/src/main.cpp b/eve/src/main.cpp index a6fb867af2..1478f3d1b2 100644 --- a/eve/src/main.cpp +++ b/eve/src/main.cpp @@ -76,6 +76,14 @@ int main(int argc, char* argv[]) { // move eve away from the origin eve.setBodyPosition(glm::vec3(3, 0, -3)); + // turn her back towards the origin + eve.setBodyYaw(-45); + + // put her hand out so somebody can shake it + eve.setHandPosition(glm::vec3(eve.getBodyPosition()[0] - 0.2, + 0.25, + eve.getBodyPosition()[2] + 0.1)); + unsigned char broadcastPacket[MAX_PACKET_SIZE]; broadcastPacket[0] = PACKET_HEADER_HEAD_DATA; From 60f0e6581db8d3d3a10bda361a5ee0ae85d24c29 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 22 Apr 2013 14:04:36 -0700 Subject: [PATCH 34/60] improved test sphere collision algorithm --- interface/src/Head.cpp | 57 +++++++++++++++++++++--------------------- interface/src/Head.h | 39 +++++++++++++---------------- 2 files changed, 45 insertions(+), 51 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 24d04b2c7b..be8a6680bd 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -115,8 +115,7 @@ Head::Head(bool isMine) { _head.noise = 0; _movedHandOffset = glm::vec3( 0.0, 0.0, 0.0 ); -_usingBodySprings = true; -//_usingBodySprings = false; + _usingBodySprings = true; _springForce = 6.0f; _springVelocityDecay = 16.0f; _renderYaw = 0.0; @@ -168,11 +167,7 @@ Head::Head(const Head &otherAvatar) { _springForce = otherAvatar._springForce; _springVelocityDecay = otherAvatar._springVelocityDecay; _orientation.set( otherAvatar._orientation ); - - //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; - _velocity += collisionForce * 18.0f * deltaTime; + glm::vec3 directionVector = vectorFromJointToBigSphereCenter / distanceToBigSphereCenter; + + float penetration = 1.0 - (distanceToBigSphereCenter / combinedRadius); + glm::vec3 collisionForce = vectorFromJointToBigSphereCenter * penetration; + + _bone[b].springyVelocity += collisionForce * 8.0f * deltaTime; + _velocity += collisionForce * 18.0f * deltaTime; + _bone[b].position = _TEST_bigSpherePosition + directionVector * combinedRadius; } } } @@ -874,7 +872,6 @@ void Head::renderHead(int faceToFace) { glPopMatrix(); } - void Head::startHandMovement() { if (!_usingBodySprings) { @@ -1136,7 +1133,7 @@ glm::vec3 Head::getHeadPosition() { } -glm::vec3 Head::getBonePosition( AvatarBones b ) { +glm::vec3 Head::getBonePosition( AvatarBoneID b ) { return _bone[b].position; } @@ -1246,18 +1243,8 @@ void Head::renderBody() { // Render bone positions as spheres //----------------------------------------- for (int b=0; b Date: Mon, 22 Apr 2013 14:05:16 -0700 Subject: [PATCH 35/60] fix missed reference to AGENT_TYPE_INTERFACE --- 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 749113f490..675a7d8614 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -993,7 +993,7 @@ void display(void) int totalAgents = AgentList::getInstance()->getAgents().size(); int totalAvatars = 0, totalServers = 0; for (int i = 0; i < totalAgents; i++) { - (AgentList::getInstance()->getAgents()[i].getType() == AGENT_TYPE_INTERFACE) + (AgentList::getInstance()->getAgents()[i].getType() == AGENT_TYPE_AVATAR) ? totalAvatars++ : totalServers++; } sprintf(agents, "Servers: %d, Avatars: %d\n", totalServers, totalAvatars); From 9b34427570c0211c17113311bb3d862a99c064d9 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Apr 2013 14:12:08 -0700 Subject: [PATCH 36/60] Added camera data to AvatarData class, and include it in interface --- interface/src/main.cpp | 19 ++++++++++- libraries/avatars/src/AvatarData.cpp | 51 +++++++++++++++++++++++++++- libraries/avatars/src/AvatarData.h | 32 +++++++++++++++++ 3 files changed, 100 insertions(+), 2 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 8712700efc..967b597c81 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -85,6 +85,7 @@ using namespace std; void reshape(int width, int height); // will be defined below +void loadViewFrustum(ViewFrustum& viewFrustum); // will be defined below pthread_t networkReceiveThread; @@ -522,6 +523,22 @@ void updateAvatar(float frametime) myAvatar.setAverageLoudness(averageLoudness); #endif + // Update Avatar with latest camera and view frustum data... + // NOTE: we get this from the view frustum, to make it simpler, since the + // loadViewFrumstum() method will get the correct details from the camera + // We could optimize this to not actually load the viewFrustum, since we don't + // actually need to calculate the view frustum planes to send these details + // to the server. + loadViewFrustum(::viewFrustum); + myAvatar.setCameraPosition(::viewFrustum.getPosition()); + myAvatar.setCameraDirection(::viewFrustum.getDirection()); + myAvatar.setCameraUp(::viewFrustum.getUp()); + myAvatar.setCameraRight(::viewFrustum.getRight()); + myAvatar.setCameraFov(::viewFrustum.getFieldOfView()); + myAvatar.setCameraAspectRatio(::viewFrustum.getAspectRatio()); + myAvatar.setCameraNearClip(::viewFrustum.getNearClip()); + myAvatar.setCameraFarClip(::viewFrustum.getFarClip()); + // Send my stream of head/hand data to the avatar mixer and voxel server unsigned char broadcastString[200]; *broadcastString = PACKET_HEADER_HEAD_DATA; @@ -559,7 +576,7 @@ void updateAvatar(float frametime) } ///////////////////////////////////////////////////////////////////////////////////// -// renderViewFrustum() +// loadViewFrustum() // // Description: this will load the view frustum bounds for EITHER the head // or the "myCamera". diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index f3ec0a31b0..89c8c828bc 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -36,7 +36,15 @@ int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPo AvatarData::AvatarData() : _bodyYaw(-90.0), _bodyPitch(0.0), - _bodyRoll(0.0) { + _bodyRoll(0.0), + _cameraPosition(0,0,0), + _cameraDirection(0,0,0), + _cameraUp(0,0,0), + _cameraRight(0,0,0), + _cameraFov(0.0f), + _cameraAspectRatio(0.0f), + _cameraNearClip(0.0f), + _cameraFarClip(0.0f) { } @@ -64,14 +72,37 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { memcpy(destinationBuffer, &_handPosition, sizeof(float) * 3); destinationBuffer += sizeof(float) * 3; + + // camera details + memcpy(destinationBuffer, &_cameraPosition, sizeof(_cameraPosition)); + destinationBuffer += sizeof(_cameraPosition); + memcpy(destinationBuffer, &_cameraDirection, sizeof(_cameraDirection)); + destinationBuffer += sizeof(_cameraDirection); + memcpy(destinationBuffer, &_cameraRight, sizeof(_cameraRight)); + destinationBuffer += sizeof(_cameraRight); + memcpy(destinationBuffer, &_cameraUp, sizeof(_cameraUp)); + destinationBuffer += sizeof(_cameraUp); + memcpy(destinationBuffer, &_cameraFov, sizeof(_cameraFov)); + destinationBuffer += sizeof(_cameraFov); + memcpy(destinationBuffer, &_cameraAspectRatio, sizeof(_cameraAspectRatio)); + destinationBuffer += sizeof(_cameraAspectRatio); + memcpy(destinationBuffer, &_cameraNearClip, sizeof(_cameraNearClip)); + destinationBuffer += sizeof(_cameraNearClip); + memcpy(destinationBuffer, &_cameraFarClip, sizeof(_cameraFarClip)); + destinationBuffer += sizeof(_cameraFarClip); //printLog("%f, %f, %f\n", _handPosition.x, _handPosition.y, _handPosition.z); + + //printf("AvatarData::getBroadcastData() numBytes=%ld\n",(destinationBuffer - bufferStart)); return destinationBuffer - bufferStart; } // called on the other agents - assigns it to my views of the others void AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { + + //printf("AvatarData::parseData() numBytes=%d\n",numBytes); + // increment to push past the packet header sourceBuffer++; @@ -85,6 +116,24 @@ void AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { memcpy(&_handPosition, sourceBuffer, sizeof(float) * 3); sourceBuffer += sizeof(float) * 3; + // camera details + memcpy(&_cameraPosition, sourceBuffer, sizeof(_cameraPosition)); + sourceBuffer += sizeof(_cameraPosition); + memcpy(&_cameraDirection, sourceBuffer, sizeof(_cameraDirection)); + sourceBuffer += sizeof(_cameraDirection); + memcpy(&_cameraRight, sourceBuffer, sizeof(_cameraRight)); + sourceBuffer += sizeof(_cameraRight); + memcpy(&_cameraUp, sourceBuffer, sizeof(_cameraUp)); + sourceBuffer += sizeof(_cameraUp); + memcpy(&_cameraFov, sourceBuffer, sizeof(_cameraFov)); + sourceBuffer += sizeof(_cameraFov); + memcpy(&_cameraAspectRatio, sourceBuffer, sizeof(_cameraAspectRatio)); + sourceBuffer += sizeof(_cameraAspectRatio); + memcpy(&_cameraNearClip, sourceBuffer, sizeof(_cameraNearClip)); + sourceBuffer += sizeof(_cameraNearClip); + memcpy(&_cameraFarClip, sourceBuffer, sizeof(_cameraFarClip)); + sourceBuffer += sizeof(_cameraFarClip); + //printLog( "_bodyYaw = %f", _bodyYaw ); //printLog("%f, %f, %f\n", _handPosition.x, _handPosition.y, _handPosition.z); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 22186c81a6..df7aa137e5 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -37,6 +37,26 @@ public: float getBodyRoll(); void setBodyRoll(float bodyRoll); + + // getters for camera details + const glm::vec3& getCameraPosition() const { return _cameraPosition; }; + const glm::vec3& getCameraDirection() const { return _cameraDirection; } + const glm::vec3& getCameraUp() const { return _cameraUp; } + const glm::vec3& getCameraRight() const { return _cameraRight; } + float getCameraFov() const { return _cameraFov; } + float getCameraAspectRatio() const { return _cameraAspectRatio; } + float getCameraNearClip() const { return _cameraNearClip; } + float getCameraFarClip() const { return _cameraFarClip; } + + // setters for camera details + void setCameraPosition(const glm::vec3& position) { _cameraPosition = position; }; + void setCameraDirection(const glm::vec3& direction) { _cameraDirection = direction; } + void setCameraUp(const glm::vec3& up) { _cameraUp = up; } + void setCameraRight(const glm::vec3& right) { _cameraRight = right; } + void setCameraFov(float fov) { _cameraFov = fov; } + void setCameraAspectRatio(float aspectRatio) { _cameraAspectRatio = aspectRatio; } + void setCameraNearClip(float nearClip) { _cameraNearClip = nearClip; } + void setCameraFarClip(float farClip) { _cameraFarClip = farClip; } protected: glm::vec3 _bodyPosition; @@ -45,6 +65,18 @@ protected: float _bodyYaw; float _bodyPitch; float _bodyRoll; + + // camera details for the avatar + glm::vec3 _cameraPosition; + + // can we describe this in less space? For example, a Quaternion? or Euler angles? + glm::vec3 _cameraDirection; + glm::vec3 _cameraUp; + glm::vec3 _cameraRight; + float _cameraFov; + float _cameraAspectRatio; + float _cameraNearClip; + float _cameraFarClip; }; #endif /* defined(__hifi__AvatarData__) */ From e1da39e2bb8ad0f5d9aad3c3354e4c9684880622 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Apr 2013 14:13:56 -0700 Subject: [PATCH 37/60] Made several ViewFrustum methods const since they don't modify the class --- libraries/voxels/src/ViewFrustum.cpp | 18 +++++++++++++----- libraries/voxels/src/ViewFrustum.h | 8 ++++---- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/libraries/voxels/src/ViewFrustum.cpp b/libraries/voxels/src/ViewFrustum.cpp index 9fdeafa449..5c9022c27e 100644 --- a/libraries/voxels/src/ViewFrustum.cpp +++ b/libraries/voxels/src/ViewFrustum.cpp @@ -105,7 +105,7 @@ void ViewFrustum::calculate() { } -void ViewFrustum::dump() { +void ViewFrustum::dump() const { printLog("position.x=%f, position.y=%f, position.z=%f\n", _position.x, _position.y, _position.z); printLog("direction.x=%f, direction.y=%f, direction.z=%f\n", _direction.x, _direction.y, _direction.z); @@ -158,17 +158,25 @@ const char* ViewFrustum::debugPlaneName (int plane) const { } -int ViewFrustum::pointInFrustum(const glm::vec3& point) { +int ViewFrustum::pointInFrustum(const glm::vec3& point) const { + + //printf("ViewFrustum::pointInFrustum() point=%f,%f,%f\n",point.x,point.y,point.z); + //dump(); + int result = INSIDE; for(int i=0; i < 6; i++) { - if (_planes[i].distance(point) < 0) { + float distance = _planes[i].distance(point); + + //printf("plane[%d] %s -- distance=%f \n",i,debugPlaneName(i),distance); + + if (distance < 0) { return OUTSIDE; } } return(result); } -int ViewFrustum::sphereInFrustum(const glm::vec3& center, float radius) { +int ViewFrustum::sphereInFrustum(const glm::vec3& center, float radius) const { int result = INSIDE; float distance; for(int i=0; i < 6; i++) { @@ -182,7 +190,7 @@ int ViewFrustum::sphereInFrustum(const glm::vec3& center, float radius) { } -int ViewFrustum::boxInFrustum(const AABox& box) { +int ViewFrustum::boxInFrustum(const AABox& box) const { printf("ViewFrustum::boxInFrustum() box.corner=%f,%f,%f x=%f\n", box.getCorner().x,box.getCorner().y,box.getCorner().z,box.getSize().x); diff --git a/libraries/voxels/src/ViewFrustum.h b/libraries/voxels/src/ViewFrustum.h index 6114953099..9ebfba6e9a 100644 --- a/libraries/voxels/src/ViewFrustum.h +++ b/libraries/voxels/src/ViewFrustum.h @@ -90,13 +90,13 @@ public: ViewFrustum(); - void dump(); + void dump() const; enum {OUTSIDE, INTERSECT, INSIDE}; - int pointInFrustum(const glm::vec3& point); - int sphereInFrustum(const glm::vec3& center, float radius); - int boxInFrustum(const AABox& box); + int pointInFrustum(const glm::vec3& point) const; + int sphereInFrustum(const glm::vec3& center, float radius) const; + int boxInFrustum(const AABox& box) const; }; From 893996675a3d958bd3b0cab35cf6b916b3210257 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Apr 2013 14:15:47 -0700 Subject: [PATCH 38/60] Derive VoxelAgentData from AvatarData to get access to camera details - Changed base class for VoxelAgentData - changed parseData() method to call base class implementation - added avatars library to cmake scripts --- voxel-server/CMakeLists.txt | 3 +++ voxel-server/src/VoxelAgentData.cpp | 9 +++++---- voxel-server/src/VoxelAgentData.h | 3 ++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/voxel-server/CMakeLists.txt b/voxel-server/CMakeLists.txt index 99b72be9cb..e1ce2b6f98 100644 --- a/voxel-server/CMakeLists.txt +++ b/voxel-server/CMakeLists.txt @@ -24,5 +24,8 @@ link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) # link in the hifi voxels library link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR}) +# link in the hifi avatars library +link_hifi_library(avatars ${TARGET_NAME} ${ROOT_DIR}) + # find required libraries find_package(GLM REQUIRED) diff --git a/voxel-server/src/VoxelAgentData.cpp b/voxel-server/src/VoxelAgentData.cpp index 8f9b41e4ca..5860106e34 100644 --- a/voxel-server/src/VoxelAgentData.cpp +++ b/voxel-server/src/VoxelAgentData.cpp @@ -28,9 +28,10 @@ VoxelAgentData* VoxelAgentData::clone() const { } void VoxelAgentData::parseData(unsigned char* sourceBuffer, int numBytes) { - // push past the packet header - sourceBuffer++; + // call base class to parse the data + AvatarData::parseData(sourceBuffer,numBytes); - // pull the position from the interface agent data packet - memcpy(&position, sourceBuffer, sizeof(float) * 3); + // make sure our class knows it's position + memcpy(&position, &_bodyPosition, sizeof(_bodyPosition)); } + diff --git a/voxel-server/src/VoxelAgentData.h b/voxel-server/src/VoxelAgentData.h index 98ec7e9ed7..1a7293a5a1 100644 --- a/voxel-server/src/VoxelAgentData.h +++ b/voxel-server/src/VoxelAgentData.h @@ -11,9 +11,10 @@ #include #include +#include #include "MarkerNode.h" -class VoxelAgentData : public AgentData { +class VoxelAgentData : public AvatarData { public: float position[3]; MarkerNode *rootMarkerNode; From 030f5328f519633d043ddc49edb5ea542002f9b5 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Apr 2013 14:46:25 -0700 Subject: [PATCH 39/60] First cut at View Frustum Culling between client and server --- libraries/voxels/src/VoxelTree.cpp | 123 ++++++++++++++++++++++++----- libraries/voxels/src/VoxelTree.h | 3 + voxel-server/src/main.cpp | 40 ++++++++-- 3 files changed, 140 insertions(+), 26 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index bd197b53cb..e7923e5976 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -17,6 +17,7 @@ #include "PacketHeaders.h" #include "OctalCode.h" #include "VoxelTree.h" +#include "ViewFrustum.h" #include // to load voxels from file using voxels_lib::printLog; @@ -268,6 +269,8 @@ unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer, MarkerNode *currentMarkerNode, float * agentPosition, float thisNodePosition[3], + const ViewFrustum& viewFrustum, + bool viewFrustumCulling, unsigned char * stopOctalCode) { static unsigned char *initialBitstreamPos = bitstreamBuffer; @@ -294,22 +297,38 @@ unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer, unsigned char * childMaskPointer = NULL; float halfUnitForVoxel = powf(0.5, *currentVoxelNode->octalCode) * (0.5 * TREE_SCALE); - - // XXXBHG - Note: It appears as if the X and Z coordinates of Head or Agent are flip-flopped relative to the - // coords of the voxel space. This flip flop causes LOD behavior to be extremely odd. This is my temporary hack - // to fix this behavior. To disable this swap, set swapXandZ to false. - // XXXBHG - 2013/04/11 - adding a note to my branch, I think this code is now broken. - bool swapXandZ=false; - float agentX = swapXandZ ? agentPosition[2] : agentPosition[0]; - float agentZ = swapXandZ ? agentPosition[0] : agentPosition[2]; - - float distanceToVoxelCenter = sqrtf(powf(agentX - thisNodePosition[0] - halfUnitForVoxel, 2) + + float distanceToVoxelCenter = sqrtf(powf(agentPosition[0] - thisNodePosition[0] - halfUnitForVoxel, 2) + powf(agentPosition[1] - thisNodePosition[1] - halfUnitForVoxel, 2) + - powf(agentZ - thisNodePosition[2] - halfUnitForVoxel, 2)); + powf(agentPosition[2] - thisNodePosition[2] - halfUnitForVoxel, 2)); + + // If the voxel is outside of the view frustum, then don't bother sending or recursing + bool voxelInView = true; + + /**** not yet working properly at this level! ************************************************************************** + if (viewFrustumCulling) { + float fullUnitForVoxel = halfUnitForVoxel*2.0f; + AABox voxelBox; + voxelBox.setBox(glm::vec3(thisNodePosition[0],thisNodePosition[1],thisNodePosition[2]), + fullUnitForVoxel,fullUnitForVoxel,fullUnitForVoxel); + + //printf("VoxelTree::loadBitstreamBuffer() voxelBox.corner=(%f,%f,%f) x=%f \n", + // voxelBox.getCorner().x,voxelBox.getCorner().y,voxelBox.getCorner().z, voxelBox.getSize().x); + + voxelInView = (ViewFrustum::OUTSIDE != viewFrustum.pointInFrustum(voxelBox.getCorner())); + } else { + voxelInView = true; + } + **********************************************************************************************************************/ // if the distance to this voxel's center is less than the threshold // distance for its children, we should send the children - if (distanceToVoxelCenter < boundaryDistanceForRenderLevel(*currentVoxelNode->octalCode + 1)) { + bool voxelIsClose = (distanceToVoxelCenter < boundaryDistanceForRenderLevel(*currentVoxelNode->octalCode + 1)); + bool sendVoxel = voxelIsClose && voxelInView; + + //printf("VoxelTree::loadBitstreamBuffer() sendVoxel=%d, voxelIsClose=%d, voxelInView=%d, viewFrustumCulling=%d\n", + // sendVoxel, voxelIsClose, voxelInView, viewFrustumCulling); + + if (sendVoxel) { // write this voxel's data if we're below or at // or at the same level as the stopOctalCode @@ -341,16 +360,78 @@ unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer, for (int i = 0; i < 8; i++) { - // check if the child exists and is not transparent - if (currentVoxelNode->children[i] != NULL - && currentVoxelNode->children[i]->isColored()) { + // Rules for including a child: + // 1) child must exists + if ((currentVoxelNode->children[i] != NULL)) { + // 2) child must have a color... + if (currentVoxelNode->children[i]->isColored()) { - // copy in the childs color to bitstreamBuffer - memcpy(colorPointer, currentVoxelNode->children[i]->getTrueColor(), 3); - colorPointer += 3; + unsigned char* childOctalCode = currentVoxelNode->children[i]->octalCode; + + float childPosition[3]; + copyFirstVertexForCode(childOctalCode,(float*)&childPosition); + childPosition[0] *= TREE_SCALE; // scale it up + childPosition[1] *= TREE_SCALE; // scale it up + childPosition[2] *= TREE_SCALE; // scale it up - // set the colorMask by bitshifting the value of childExists - *bitstreamBuffer += (1 << (7 - i)); + float halfChildVoxel = powf(0.5, *childOctalCode) * (0.5 * TREE_SCALE); + float distanceToChildCenter = sqrtf(powf(agentPosition[0] - childPosition[0] - halfChildVoxel, 2) + + powf(agentPosition[1] - childPosition[1] - halfChildVoxel, 2) + + powf(agentPosition[2] - childPosition[2] - halfChildVoxel, 2)); + + float fullChildVoxel = halfChildVoxel*2.0f; + AABox childBox; + childBox.setBox(glm::vec3(childPosition[0],childPosition[1],childPosition[2]), + fullChildVoxel,fullChildVoxel,fullChildVoxel); + + //printf("VoxelTree::loadBitstreamBuffer() childBox.corner=(%f,%f,%f) x=%f \n", + // childBox.getCorner().x,childBox.getCorner().y,childBox.getCorner().z, childBox.getSize().x); + + // XXXBHG - not sure we want to do this "distance/LOD culling" at this level. + //bool childIsClose = (distanceToChildCenter < boundaryDistanceForRenderLevel(*childOctalCode + 1)); + + bool childIsClose = true; // for now, assume we're close enough + bool childInView = !viewFrustumCulling || + (ViewFrustum::OUTSIDE != viewFrustum.pointInFrustum(childBox.getCorner())); + + /// XXXBHG - debug code, switch this to true, and we'll send everything but include false coloring + // on voxels based on whether or not they match these rules. + bool falseColorInsteadOfCulling = false; + + // removed childIsClose - until we determine if we want to include that + bool sendChild = (childInView) || falseColorInsteadOfCulling; + + //printf("VoxelTree::loadBitstreamBuffer() childIsClose=%d, childInView=%d\n", + // childIsClose, childInView); + + // if we sendAnyway, we'll do false coloring of the voxels based on childIsClose && childInView + if (sendChild) { + + // copy in the childs color to bitstreamBuffer + if (childIsClose && childInView) { + // true color + memcpy(colorPointer, currentVoxelNode->children[i]->getTrueColor(), 3); + } else { + unsigned char red[3] = {255,0,0}; + unsigned char green[3] = {0,255,0}; + unsigned char blue[3] = {0,0,255}; + if (!childIsClose && !childInView) { + // If both too far, and not in view, color them red + memcpy(colorPointer, red, 3); + } else if (!childIsClose) { + // If too far, but in view, color them blue + memcpy(colorPointer, blue, 3); + } else { + // If close, but out of view, color them green + memcpy(colorPointer, green, 3); + } + } + colorPointer += 3; + + // set the colorMask by bitshifting the value of childExists + *bitstreamBuffer += (1 << (7 - i)); + } + } } } @@ -414,6 +495,8 @@ unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer, currentMarkerNode->children[i], agentPosition, childNodePosition, + viewFrustum, + viewFrustumCulling, stopOctalCode); if (bitstreamBuffer - arrBufferBeforeChild > 0) { diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 62ff4e4815..77c00b2e63 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -11,6 +11,7 @@ #include "SimpleMovingAverage.h" +#include "ViewFrustum.h" #include "VoxelNode.h" #include "MarkerNode.h" @@ -52,6 +53,8 @@ public: MarkerNode *currentMarkerNode, float * agentPosition, float thisNodePosition[3], + const ViewFrustum& viewFrustum, + bool viewFrustumCulling, unsigned char * octalCode = NULL); void loadVoxelsFile(const char* fileName, bool wantColorRandomizer); diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 8f6bab7dc7..3e411f2d16 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -48,6 +48,8 @@ const int MAX_VOXEL_TREE_DEPTH_LEVELS = 4; VoxelTree randomTree; bool wantColorRandomizer = false; +bool debugViewFrustum = false; +bool viewFrustumCulling = false; // for now void addSphere(VoxelTree * tree,bool random, bool wantColorRandomizer) { float r = random ? randFloatInRange(0.05,0.1) : 0.25; @@ -165,6 +167,24 @@ void *distributeVoxelsToListeners(void *args) { Agent *thisAgent = (Agent *)&agentList->getAgents()[i]; VoxelAgentData *agentData = (VoxelAgentData *)(thisAgent->getLinkedData()); + ViewFrustum viewFrustum; + // get position and orientation details from the camera + viewFrustum.setPosition(agentData->getCameraPosition()); + viewFrustum.setOrientation(agentData->getCameraDirection(),agentData->getCameraUp(),agentData->getCameraRight()); + + // Also make sure it's got the correct lens details from the camera + viewFrustum.setFieldOfView(agentData->getCameraFov()); + viewFrustum.setAspectRatio(agentData->getCameraAspectRatio()); + viewFrustum.setNearClip(agentData->getCameraNearClip()); + viewFrustum.setFarClip(agentData->getCameraFarClip()); + + viewFrustum.calculate(); + + // debug for fun!! + if (::debugViewFrustum) { + viewFrustum.dump(); + } + // lock this agent's delete mutex so that the delete thread doesn't // kill the agent while we are working with it pthread_mutex_lock(thisAgent->deleteMutex); @@ -181,6 +201,8 @@ void *distributeVoxelsToListeners(void *args) { agentData->rootMarkerNode, agentData->position, treeRoot, + viewFrustum, + ::viewFrustumCulling, stopOctal); agentList->getAgentSocket().send(thisAgent->getActiveSocket(), voxelPacket, voxelPacketEnd - voxelPacket); @@ -249,16 +271,23 @@ int main(int argc, const char * argv[]) agentList->startDomainServerCheckInThread(); srand((unsigned)time(0)); + + const char* DEBUG_VIEW_FRUSTUM="--DebugViewFrustum"; + ::debugViewFrustum = cmdOptionExists(argc, argv, DEBUG_VIEW_FRUSTUM); + printf("debugViewFrustum=%s\n",(::debugViewFrustum?"yes":"no")); + + const char* VIEW_FRUSTUM_CULLING="--ViewFrustumCulling"; + ::viewFrustumCulling = cmdOptionExists(argc, argv, VIEW_FRUSTUM_CULLING); + printf("viewFrustumCulling=%s\n",(::viewFrustumCulling?"yes":"no")); + const char* WANT_COLOR_RANDOMIZER="--WantColorRandomizer"; + ::wantColorRandomizer = cmdOptionExists(argc, argv, WANT_COLOR_RANDOMIZER); + printf("wantColorRandomizer=%s\n",(::wantColorRandomizer?"yes":"no")); + // Check to see if the user passed in a command line option for loading a local // Voxel File. If so, load it now. - const char* WANT_COLOR_RANDOMIZER="--WantColorRandomizer"; const char* INPUT_FILE="-i"; - ::wantColorRandomizer = cmdOptionExists(argc, argv, WANT_COLOR_RANDOMIZER); - - printf("wantColorRandomizer=%s\n",(wantColorRandomizer?"yes":"no")); const char* voxelsFilename = getCmdOption(argc, argv, INPUT_FILE); - if (voxelsFilename) { randomTree.loadVoxelsFile(voxelsFilename,wantColorRandomizer); } @@ -269,7 +298,6 @@ int main(int argc, const char * argv[]) // octal codes to the tree nodes that it is creating randomlyFillVoxelTree(MAX_VOXEL_TREE_DEPTH_LEVELS, randomTree.rootNode); } - const char* ADD_SPHERE="--AddSphere"; const char* ADD_RANDOM_SPHERE="--AddRandomSphere"; From 7c73964836f1ffbba8ee4e40119a7abf78ef3c73 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Apr 2013 15:07:46 -0700 Subject: [PATCH 40/60] code review cleanup --- libraries/avatars/src/AvatarData.cpp | 12 ------------ libraries/voxels/src/VoxelTree.cpp | 8 ++++---- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 89c8c828bc..4189575e67 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -90,19 +90,12 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { destinationBuffer += sizeof(_cameraNearClip); memcpy(destinationBuffer, &_cameraFarClip, sizeof(_cameraFarClip)); destinationBuffer += sizeof(_cameraFarClip); - - //printLog("%f, %f, %f\n", _handPosition.x, _handPosition.y, _handPosition.z); - //printf("AvatarData::getBroadcastData() numBytes=%ld\n",(destinationBuffer - bufferStart)); - return destinationBuffer - bufferStart; } // called on the other agents - assigns it to my views of the others void AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { - - //printf("AvatarData::parseData() numBytes=%d\n",numBytes); - // increment to push past the packet header sourceBuffer++; @@ -133,11 +126,6 @@ void AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { sourceBuffer += sizeof(_cameraNearClip); memcpy(&_cameraFarClip, sourceBuffer, sizeof(_cameraFarClip)); sourceBuffer += sizeof(_cameraFarClip); - - //printLog( "_bodyYaw = %f", _bodyYaw ); - - //printLog("%f, %f, %f\n", _handPosition.x, _handPosition.y, _handPosition.z); - //printLog("%f, %f, %f\n", _bodyPosition.x, _bodyPosition.y, _bodyPosition.z); } glm::vec3 AvatarData::getBodyPosition() { diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index e7923e5976..31d39de3de 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -306,7 +306,7 @@ unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer, /**** not yet working properly at this level! ************************************************************************** if (viewFrustumCulling) { - float fullUnitForVoxel = halfUnitForVoxel*2.0f; + float fullUnitForVoxel = halfUnitForVoxel * 2.0f; AABox voxelBox; voxelBox.setBox(glm::vec3(thisNodePosition[0],thisNodePosition[1],thisNodePosition[2]), fullUnitForVoxel,fullUnitForVoxel,fullUnitForVoxel); @@ -379,10 +379,10 @@ unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer, powf(agentPosition[1] - childPosition[1] - halfChildVoxel, 2) + powf(agentPosition[2] - childPosition[2] - halfChildVoxel, 2)); - float fullChildVoxel = halfChildVoxel*2.0f; + float fullChildVoxel = halfChildVoxel * 2.0f; AABox childBox; - childBox.setBox(glm::vec3(childPosition[0],childPosition[1],childPosition[2]), - fullChildVoxel,fullChildVoxel,fullChildVoxel); + childBox.setBox(glm::vec3(childPosition[0], childPosition[1], childPosition[2]), + fullChildVoxel, fullChildVoxel, fullChildVoxel); //printf("VoxelTree::loadBitstreamBuffer() childBox.corner=(%f,%f,%f) x=%f \n", // childBox.getCorner().x,childBox.getCorner().y,childBox.getCorner().z, childBox.getSize().x); From 7d93f07152e5d5453df9f2a1c8c8d5dff34bfcba Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Apr 2013 15:10:18 -0700 Subject: [PATCH 41/60] code review cleanup --- voxel-server/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/voxel-server/CMakeLists.txt b/voxel-server/CMakeLists.txt index 3f6ac2a5ed..2bdba8f6e3 100644 --- a/voxel-server/CMakeLists.txt +++ b/voxel-server/CMakeLists.txt @@ -26,5 +26,3 @@ link_hifi_library(voxels ${TARGET_NAME} ${ROOT_DIR}) # link in the hifi avatars library link_hifi_library(avatars ${TARGET_NAME} ${ROOT_DIR}) -# find required libraries -find_package(GLM REQUIRED) From 436b43ea8556868519d159a29b938c05489ba850 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Apr 2013 15:11:40 -0700 Subject: [PATCH 42/60] code review cleanup --- voxel-server/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 9496375ca9..bacd253d88 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -170,7 +170,7 @@ void *distributeVoxelsToListeners(void *args) { ViewFrustum viewFrustum; // get position and orientation details from the camera viewFrustum.setPosition(agentData->getCameraPosition()); - viewFrustum.setOrientation(agentData->getCameraDirection(),agentData->getCameraUp(),agentData->getCameraRight()); + viewFrustum.setOrientation(agentData->getCameraDirection(), agentData->getCameraUp(), agentData->getCameraRight()); // Also make sure it's got the correct lens details from the camera viewFrustum.setFieldOfView(agentData->getCameraFov()); From 2f6d2469f472c136ddda839fb1ff9a112c7e07dd Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Apr 2013 15:13:17 -0700 Subject: [PATCH 43/60] code review cleanup --- voxel-server/src/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index bacd253d88..127cd36792 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -274,15 +274,15 @@ int main(int argc, const char * argv[]) const char* DEBUG_VIEW_FRUSTUM="--DebugViewFrustum"; ::debugViewFrustum = cmdOptionExists(argc, argv, DEBUG_VIEW_FRUSTUM); - printf("debugViewFrustum=%s\n",(::debugViewFrustum?"yes":"no")); + printf("debugViewFrustum=%s\n", (::debugViewFrustum ? "yes" : "no")); const char* VIEW_FRUSTUM_CULLING="--ViewFrustumCulling"; ::viewFrustumCulling = cmdOptionExists(argc, argv, VIEW_FRUSTUM_CULLING); - printf("viewFrustumCulling=%s\n",(::viewFrustumCulling?"yes":"no")); + printf("viewFrustumCulling=%s\n", (::viewFrustumCulling ? "yes" : "no")); const char* WANT_COLOR_RANDOMIZER="--WantColorRandomizer"; ::wantColorRandomizer = cmdOptionExists(argc, argv, WANT_COLOR_RANDOMIZER); - printf("wantColorRandomizer=%s\n",(::wantColorRandomizer?"yes":"no")); + printf("wantColorRandomizer=%s\n", (::wantColorRandomizer ? "yes" : "no")); // Check to see if the user passed in a command line option for loading a local // Voxel File. If so, load it now. From cea417027020ae51f7274a2b54e36af06b0c3c45 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Apr 2013 15:14:35 -0700 Subject: [PATCH 44/60] code review cleanup --- voxel-server/src/main.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 127cd36792..808e33a96d 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -272,42 +272,42 @@ int main(int argc, const char * argv[]) srand((unsigned)time(0)); - const char* DEBUG_VIEW_FRUSTUM="--DebugViewFrustum"; + const char* DEBUG_VIEW_FRUSTUM = "--DebugViewFrustum"; ::debugViewFrustum = cmdOptionExists(argc, argv, DEBUG_VIEW_FRUSTUM); printf("debugViewFrustum=%s\n", (::debugViewFrustum ? "yes" : "no")); - const char* VIEW_FRUSTUM_CULLING="--ViewFrustumCulling"; + const char* VIEW_FRUSTUM_CULLING = "--ViewFrustumCulling"; ::viewFrustumCulling = cmdOptionExists(argc, argv, VIEW_FRUSTUM_CULLING); printf("viewFrustumCulling=%s\n", (::viewFrustumCulling ? "yes" : "no")); - const char* WANT_COLOR_RANDOMIZER="--WantColorRandomizer"; + const char* WANT_COLOR_RANDOMIZER = "--WantColorRandomizer"; ::wantColorRandomizer = cmdOptionExists(argc, argv, WANT_COLOR_RANDOMIZER); printf("wantColorRandomizer=%s\n", (::wantColorRandomizer ? "yes" : "no")); // Check to see if the user passed in a command line option for loading a local // Voxel File. If so, load it now. - const char* INPUT_FILE="-i"; + const char* INPUT_FILE = "-i"; const char* voxelsFilename = getCmdOption(argc, argv, INPUT_FILE); if (voxelsFilename) { randomTree.loadVoxelsFile(voxelsFilename,wantColorRandomizer); } - const char* ADD_RANDOM_VOXELS="--AddRandomVoxels"; + const char* ADD_RANDOM_VOXELS = "--AddRandomVoxels"; if (cmdOptionExists(argc, argv, ADD_RANDOM_VOXELS)) { // create an octal code buffer and load it with 0 so that the recursive tree fill can give // octal codes to the tree nodes that it is creating randomlyFillVoxelTree(MAX_VOXEL_TREE_DEPTH_LEVELS, randomTree.rootNode); } - const char* ADD_SPHERE="--AddSphere"; - const char* ADD_RANDOM_SPHERE="--AddRandomSphere"; + const char* ADD_SPHERE = "--AddSphere"; + const char* ADD_RANDOM_SPHERE = "--AddRandomSphere"; if (cmdOptionExists(argc, argv, ADD_SPHERE)) { addSphere(&randomTree,false,wantColorRandomizer); } else if (cmdOptionExists(argc, argv, ADD_RANDOM_SPHERE)) { addSphere(&randomTree,true,wantColorRandomizer); } - const char* NO_ADD_SCENE="--NoAddScene"; + const char* NO_ADD_SCENE = "--NoAddScene"; if (!cmdOptionExists(argc, argv, NO_ADD_SCENE)) { addSphereScene(&randomTree,wantColorRandomizer); } From a79659a5d488963eecf815fed2a698f9d923ed52 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Apr 2013 15:22:41 -0700 Subject: [PATCH 45/60] change VoxelAgentData to not include position, use AvatarData _bodyPosition instead --- libraries/voxels/src/VoxelTree.cpp | 2 +- libraries/voxels/src/VoxelTree.h | 2 +- voxel-server/src/VoxelAgentData.cpp | 11 +---------- voxel-server/src/VoxelAgentData.h | 2 -- voxel-server/src/main.cpp | 2 +- 5 files changed, 4 insertions(+), 15 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 31d39de3de..3e75f76184 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -267,7 +267,7 @@ void VoxelTree::readCodeColorBufferToTree(unsigned char *codeColorBuffer) { unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer, VoxelNode *currentVoxelNode, MarkerNode *currentMarkerNode, - float * agentPosition, + const glm::vec3& agentPosition, float thisNodePosition[3], const ViewFrustum& viewFrustum, bool viewFrustumCulling, diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index 77c00b2e63..60c66925ec 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -51,7 +51,7 @@ public: unsigned char * loadBitstreamBuffer(unsigned char *& bitstreamBuffer, VoxelNode *currentVoxelNode, MarkerNode *currentMarkerNode, - float * agentPosition, + const glm::vec3& agentPosition, float thisNodePosition[3], const ViewFrustum& viewFrustum, bool viewFrustumCulling, diff --git a/voxel-server/src/VoxelAgentData.cpp b/voxel-server/src/VoxelAgentData.cpp index 5860106e34..4476cff056 100644 --- a/voxel-server/src/VoxelAgentData.cpp +++ b/voxel-server/src/VoxelAgentData.cpp @@ -19,19 +19,10 @@ VoxelAgentData::~VoxelAgentData() { } VoxelAgentData::VoxelAgentData(const VoxelAgentData &otherAgentData) { - memcpy(position, otherAgentData.position, sizeof(float) * 3); + memcpy(&_bodyPosition, &otherAgentData._bodyPosition, sizeof(_bodyPosition)); rootMarkerNode = new MarkerNode(); } VoxelAgentData* VoxelAgentData::clone() const { return new VoxelAgentData(*this); } - -void VoxelAgentData::parseData(unsigned char* sourceBuffer, int numBytes) { - // call base class to parse the data - AvatarData::parseData(sourceBuffer,numBytes); - - // make sure our class knows it's position - memcpy(&position, &_bodyPosition, sizeof(_bodyPosition)); -} - diff --git a/voxel-server/src/VoxelAgentData.h b/voxel-server/src/VoxelAgentData.h index 1a7293a5a1..4ca7949b92 100644 --- a/voxel-server/src/VoxelAgentData.h +++ b/voxel-server/src/VoxelAgentData.h @@ -16,14 +16,12 @@ class VoxelAgentData : public AvatarData { public: - float position[3]; MarkerNode *rootMarkerNode; VoxelAgentData(); ~VoxelAgentData(); VoxelAgentData(const VoxelAgentData &otherAgentData); - void parseData(unsigned char* sourceBuffer, int numBytes); VoxelAgentData* clone() const; }; diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index 808e33a96d..d85154abc5 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -199,7 +199,7 @@ void *distributeVoxelsToListeners(void *args) { stopOctal = randomTree.loadBitstreamBuffer(voxelPacketEnd, randomTree.rootNode, agentData->rootMarkerNode, - agentData->position, + agentData->getBodyPosition(), treeRoot, viewFrustum, ::viewFrustumCulling, From ca2840f9057a6a301460888bbed35ca0ac0921db Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 22 Apr 2013 15:39:31 -0700 Subject: [PATCH 46/60] Cleaned up some const values in Head.h, implemented avatar gravity and ground collision, improved test sphere collision, added _usingBodySprings test to getHeadPosition, improved camera settings in main.cpp, cleaned up commented-out code in main.cpp --- interface/src/Head.cpp | 58 +++++++++++++++++++++++------------------- interface/src/Head.h | 7 +++++ interface/src/main.cpp | 33 +++++++++--------------- 3 files changed, 51 insertions(+), 47 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index bf410eae94..f4dcdbee53 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -35,9 +35,7 @@ float browThickness = 0.16; bool usingBigSphereCollisionTest = true; -const float DECAY = 0.1; -const float THRUST_MAG = 10.0; -const float YAW_MAG = 300.0; + char iris_texture_file[] = "resources/images/green_eye.png"; @@ -380,7 +378,19 @@ void Head::simulate(float deltaTime) { //-------------------------------------------------------------- updateBigSphereCollisionTest(deltaTime); } - + + if ( AVATAR_GRAVITY ) { + if ( _bodyPosition.y > _bone[ AVATAR_BONE_RIGHT_FOOT ].radius * 2.0 ) { + _velocity += glm::dvec3( 0.0, -1.0, 0.0 ) * ( 6.0 * deltaTime ); + } + else { + if ( _bodyPosition.y < _bone[ AVATAR_BONE_RIGHT_FOOT ].radius ) { + _bodyPosition.y = _bone[ AVATAR_BONE_RIGHT_FOOT ].radius; + _velocity.y = 0.0; + } + } + } + //------------------------ // update avatar skeleton //------------------------ @@ -460,7 +470,6 @@ void Head::simulate(float deltaTime) { //---------------------------------------------------------- // decay body yaw delta //---------------------------------------------------------- - const float TEST_YAW_DECAY = 5.0; _bodyYawDelta *= (1.0 - TEST_YAW_DECAY * deltaTime); //---------------------------------------------------------- @@ -476,7 +485,6 @@ void Head::simulate(float deltaTime) { //---------------------------------------------------------- // decay velocity //---------------------------------------------------------- - const float LIN_VEL_DECAY = 5.0; _velocity *= ( 1.0 - LIN_VEL_DECAY * deltaTime ); if (!_head.noise) { @@ -585,7 +593,7 @@ void Head::updateBigSphereCollisionTest( float deltaTime ) { { for (int b=0; b #include //looks like we might not need this +const bool AVATAR_GRAVITY = true; +const float DECAY = 0.1; +const float THRUST_MAG = 10.0; +const float YAW_MAG = 300.0; +const float TEST_YAW_DECAY = 5.0; +const float LIN_VEL_DECAY = 5.0; + enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH}; #define FWD 0 diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 749113f490..8d6fa06e8d 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -802,18 +802,16 @@ void display(void) //-------------------------------------------------------- // camera settings //-------------------------------------------------------- - myCamera.setTargetPosition( myAvatar.getBodyPosition() ); - if ( displayHead ) { //----------------------------------------------- // set the camera to looking at my own face //----------------------------------------------- - myCamera.setTargetPosition ( myAvatar.getBodyPosition() ); // XXXBHG - Shouldn't we use Head position here? + myCamera.setTargetPosition ( myAvatar.getHeadPosition() ); myCamera.setYaw ( - myAvatar.getBodyYaw() ); - myCamera.setPitch ( 0.0 ); - myCamera.setRoll ( 0.0 ); - myCamera.setUp ( 0.6 ); - myCamera.setDistance ( 0.3 ); + myCamera.setPitch ( 0.0 ); + myCamera.setRoll ( 0.0 ); + myCamera.setUp ( 0.0 ); + myCamera.setDistance ( 0.2 ); myCamera.setTightness ( 100.0f ); myCamera.update ( 1.f/FPS ); } else { @@ -822,12 +820,12 @@ void display(void) //---------------------------------------------------- myCamera.setTargetPosition ( myAvatar.getBodyPosition() ); myCamera.setYaw ( 180.0 - myAvatar.getBodyYaw() ); - myCamera.setPitch ( 0.0 ); // temporarily, this must be 0.0 or else bad juju - myCamera.setRoll ( 0.0 ); - myCamera.setUp ( 0.45); - myCamera.setDistance ( 1.0 ); - myCamera.setTightness ( 10.0f ); - myCamera.update ( 1.f/FPS ); + 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 ); + myCamera.setTightness ( 8.0f ); + myCamera.update ( 1.f/FPS); } // Note: whichCamera is used to pick between the normal camera myCamera for our @@ -890,14 +888,12 @@ void display(void) float sphereRadius = 0.25f; glColor3f(1,0,0); glPushMatrix(); - //glTranslatef( 0.0f, sphereRadius, 0.0f ); glutSolidSphere( sphereRadius, 15, 15 ); glPopMatrix(); //draw a grid gound plane.... drawGroundPlaneGrid( 5.0f, 9 ); - // Draw cloud of dots if (!displayHead) cloud.render(); @@ -917,12 +913,7 @@ void display(void) agent++) { if (agent->getLinkedData() != NULL) { Head *avatar = (Head *)agent->getLinkedData(); - //glPushMatrix(); - -//printf( "rendering remote avatar\n" ); - avatar->render(0); - //glPopMatrix(); } } @@ -993,7 +984,7 @@ void display(void) int totalAgents = AgentList::getInstance()->getAgents().size(); int totalAvatars = 0, totalServers = 0; for (int i = 0; i < totalAgents; i++) { - (AgentList::getInstance()->getAgents()[i].getType() == AGENT_TYPE_INTERFACE) + (AgentList::getInstance()->getAgents()[i].getType() == AGENT_TYPE_AVATAR) ? totalAvatars++ : totalServers++; } sprintf(agents, "Servers: %d, Avatars: %d\n", totalServers, totalAvatars); From ba4235c175581cfc27776db21bd169753596736a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 22 Apr 2013 16:04:46 -0700 Subject: [PATCH 47/60] don't render agents that are not of type avatar --- 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 675a7d8614..a43a2f0c0f 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -915,7 +915,7 @@ void display(void) for(std::vector::iterator agent = agentList->getAgents().begin(); agent != agentList->getAgents().end(); agent++) { - if (agent->getLinkedData() != NULL) { + if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) { Head *avatar = (Head *)agent->getLinkedData(); //glPushMatrix(); From 2d8997003a692523c0ca94b0de1cd6187ad68bbd Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 22 Apr 2013 16:16:06 -0700 Subject: [PATCH 48/60] include avatar ID on log output --- libraries/shared/src/Agent.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libraries/shared/src/Agent.cpp b/libraries/shared/src/Agent.cpp index 819e4c185f..637a1bc58a 100644 --- a/libraries/shared/src/Agent.cpp +++ b/libraries/shared/src/Agent.cpp @@ -249,9 +249,14 @@ void Agent::printLog(Agent const& agent) { sockaddr_in *agentPublicSocket = (sockaddr_in *) agent.publicSocket; sockaddr_in *agentLocalSocket = (sockaddr_in *) agent.localSocket; - ::printLog("T: %s (%c) PA: %s:%d LA: %s:%d\n", agent.getTypeName(), agent.type, - inet_ntoa(agentPublicSocket->sin_addr), ntohs(agentPublicSocket->sin_port), - inet_ntoa(agentLocalSocket->sin_addr), ntohs(agentLocalSocket->sin_port)); + ::printLog("ID: %d T: %s (%c) PA: %s:%d LA: %s:%d\n", + agent.agentId, + agent.getTypeName(), + agent.type, + inet_ntoa(agentPublicSocket->sin_addr), + ntohs(agentPublicSocket->sin_port), + inet_ntoa(agentLocalSocket->sin_addr), + ntohs(agentLocalSocket->sin_port)); } std::ostream& operator<<(std::ostream& os, const Agent* agent) { From ea5a247f931dde627e05051c1da3125f661892e8 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 22 Apr 2013 16:22:06 -0700 Subject: [PATCH 49/60] view frustum additions means there are now 94 bytes per avatar --- libraries/avatars/src/AvatarData.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index df7aa137e5..819333d558 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -13,7 +13,7 @@ #include -const int BYTES_PER_AVATAR = 30; +const int BYTES_PER_AVATAR = 94; class AvatarData : public AgentData { public: From fb703171f2aa278b41a6e3c242d935a487c7476e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 22 Apr 2013 16:30:45 -0700 Subject: [PATCH 50/60] make other heads the same color and same size --- interface/src/Head.cpp | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 6c4b4a9d35..d75a3012fd 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -718,41 +718,25 @@ void Head::renderHead(int faceToFace) { glPushMatrix(); if (_usingBodySprings) { - glTranslatef - ( - _bone[ AVATAR_BONE_HEAD ].springyPosition.x, - _bone[ AVATAR_BONE_HEAD ].springyPosition.y, - _bone[ AVATAR_BONE_HEAD ].springyPosition.z - ); + glTranslatef(_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 - ); + glTranslatef(_bone[ AVATAR_BONE_HEAD ].position.x, + _bone[ AVATAR_BONE_HEAD ].position.y, + _bone[ AVATAR_BONE_HEAD ].position.z); } - glScalef( 0.03, 0.03, 0.03 ); glRotatef(_head.yaw, 0, 1, 0); glRotatef(_head.pitch, 1, 0, 0); glRotatef(_head.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); + glScalef(2.0, 2.0, 2.0); + glColor3fv(skinColor); - - // Head - if (_isMine) { - glColor3fv(skinColor); - } - else { - glColor3f(0,0,1); // Temp: Other people are BLUE - } glutSolidSphere(1, 30, 30); // Ears From 3dc03f44a13d9d0881c265ae1bce8231cd79da94 Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 22 Apr 2013 16:32:35 -0700 Subject: [PATCH 51/60] improved rendering of avatar --- interface/src/Head.cpp | 122 ++++++++++++++++++++++++----------------- 1 file changed, 71 insertions(+), 51 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index f4dcdbee53..fd054bd6f3 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -649,12 +649,7 @@ void Head::render(int faceToFace) { glutSolidSphere( 1, 20, 20 ); glPopMatrix(); } - - //--------------------------------------------------- - // show avatar orientation - //--------------------------------------------------- - renderOrientationDirections( _bone[ AVATAR_BONE_HEAD ].position, _bone[ AVATAR_BONE_HEAD ].orientation, 0.2f ); - + //--------------------------------------------------- // render body //--------------------------------------------------- @@ -708,6 +703,11 @@ void Head::renderHead(int faceToFace) { glEnable(GL_DEPTH_TEST); glEnable(GL_RESCALE_NORMAL); + //--------------------------------------------------- + // show head orientation + //--------------------------------------------------- + //renderOrientationDirections( _bone[ AVATAR_BONE_HEAD ].position, _bone[ AVATAR_BONE_HEAD ].orientation, 0.2f ); + glPushMatrix(); if (_usingBodySprings) { @@ -900,7 +900,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].radius = 0.0; _bone[b].springBodyTightness = 4.0; _bone[b].orientation.setToIdentity(); } @@ -955,29 +955,54 @@ void Head::initializeSkeleton() { //---------------------------------------------------------- // specify the default pose position //---------------------------------------------------------- - _bone[ AVATAR_BONE_PELVIS_SPINE ].defaultPosePosition = glm::vec3( 0.0, 0.3, 0.0 ); - _bone[ AVATAR_BONE_MID_SPINE ].defaultPosePosition = glm::vec3( 0.0, 0.1, 0.0 ); - _bone[ AVATAR_BONE_CHEST_SPINE ].defaultPosePosition = glm::vec3( 0.0, 0.1, 0.0 ); - _bone[ AVATAR_BONE_NECK ].defaultPosePosition = glm::vec3( 0.0, 0.06, 0.0 ); - _bone[ AVATAR_BONE_HEAD ].defaultPosePosition = glm::vec3( 0.0, 0.06, 0.0 ); - _bone[ AVATAR_BONE_LEFT_CHEST ].defaultPosePosition = glm::vec3( -0.06, 0.06, 0.0 ); - _bone[ AVATAR_BONE_LEFT_SHOULDER ].defaultPosePosition = glm::vec3( -0.03, 0.0, 0.0 ); - _bone[ AVATAR_BONE_LEFT_UPPER_ARM ].defaultPosePosition = glm::vec3( 0.0, -0.12, 0.0 ); - _bone[ AVATAR_BONE_LEFT_FOREARM ].defaultPosePosition = glm::vec3( 0.0, -0.1, 0.0 ); - _bone[ AVATAR_BONE_LEFT_HAND ].defaultPosePosition = glm::vec3( 0.0, -0.05, 0.0 ); - _bone[ AVATAR_BONE_RIGHT_CHEST ].defaultPosePosition = glm::vec3( 0.06, 0.06, 0.0 ); - _bone[ AVATAR_BONE_RIGHT_SHOULDER ].defaultPosePosition = glm::vec3( 0.03, 0.0, 0.0 ); - _bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].defaultPosePosition = glm::vec3( 0.0, -0.12, 0.0 ); - _bone[ AVATAR_BONE_RIGHT_FOREARM ].defaultPosePosition = glm::vec3( 0.0, -0.1, 0.0 ); - _bone[ AVATAR_BONE_RIGHT_HAND ].defaultPosePosition = glm::vec3( 0.0, -0.05, 0.0 ); - _bone[ AVATAR_BONE_LEFT_PELVIS ].defaultPosePosition = glm::vec3( -0.05, 0.0, 0.0 ); - _bone[ AVATAR_BONE_LEFT_THIGH ].defaultPosePosition = glm::vec3( 0.0, -0.15, 0.0 ); - _bone[ AVATAR_BONE_LEFT_SHIN ].defaultPosePosition = glm::vec3( 0.0, -0.15, 0.0 ); - _bone[ AVATAR_BONE_LEFT_FOOT ].defaultPosePosition = glm::vec3( 0.0, 0.0, 0.04 ); - _bone[ AVATAR_BONE_RIGHT_PELVIS ].defaultPosePosition = glm::vec3( 0.05, 0.0, 0.0 ); - _bone[ AVATAR_BONE_RIGHT_THIGH ].defaultPosePosition = glm::vec3( 0.0, -0.15, 0.0 ); - _bone[ AVATAR_BONE_RIGHT_SHIN ].defaultPosePosition = glm::vec3( 0.0, -0.15, 0.0 ); - _bone[ AVATAR_BONE_RIGHT_FOOT ].defaultPosePosition = glm::vec3( 0.0, 0.0, 0.04 ); + _bone[ AVATAR_BONE_PELVIS_SPINE ].defaultPosePosition = glm::vec3( 0.0, 0.3, 0.0 ); + _bone[ AVATAR_BONE_MID_SPINE ].defaultPosePosition = glm::vec3( 0.0, 0.1, 0.0 ); + _bone[ AVATAR_BONE_CHEST_SPINE ].defaultPosePosition = glm::vec3( 0.0, 0.06, 0.0 ); + _bone[ AVATAR_BONE_NECK ].defaultPosePosition = glm::vec3( 0.0, 0.06, 0.0 ); + _bone[ AVATAR_BONE_HEAD ].defaultPosePosition = glm::vec3( 0.0, 0.06, 0.0 ); + _bone[ AVATAR_BONE_LEFT_CHEST ].defaultPosePosition = glm::vec3( -0.06, 0.06, 0.0 ); + _bone[ AVATAR_BONE_LEFT_SHOULDER ].defaultPosePosition = glm::vec3( -0.03, 0.0, 0.0 ); + _bone[ AVATAR_BONE_LEFT_UPPER_ARM ].defaultPosePosition = glm::vec3( 0.0, -0.1, 0.0 ); + _bone[ AVATAR_BONE_LEFT_FOREARM ].defaultPosePosition = glm::vec3( 0.0, -0.1, 0.0 ); + _bone[ AVATAR_BONE_LEFT_HAND ].defaultPosePosition = glm::vec3( 0.0, -0.05, 0.0 ); + _bone[ AVATAR_BONE_RIGHT_CHEST ].defaultPosePosition = glm::vec3( 0.06, 0.06, 0.0 ); + _bone[ AVATAR_BONE_RIGHT_SHOULDER ].defaultPosePosition = glm::vec3( 0.03, 0.0, 0.0 ); + _bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].defaultPosePosition = glm::vec3( 0.0, -0.1, 0.0 ); + _bone[ AVATAR_BONE_RIGHT_FOREARM ].defaultPosePosition = glm::vec3( 0.0, -0.1, 0.0 ); + _bone[ AVATAR_BONE_RIGHT_HAND ].defaultPosePosition = glm::vec3( 0.0, -0.05, 0.0 ); + _bone[ AVATAR_BONE_LEFT_PELVIS ].defaultPosePosition = glm::vec3( -0.05, 0.0, 0.0 ); + _bone[ AVATAR_BONE_LEFT_THIGH ].defaultPosePosition = glm::vec3( 0.0, -0.15, 0.0 ); + _bone[ AVATAR_BONE_LEFT_SHIN ].defaultPosePosition = glm::vec3( 0.0, -0.15, 0.0 ); + _bone[ AVATAR_BONE_LEFT_FOOT ].defaultPosePosition = glm::vec3( 0.0, 0.0, 0.04 ); + _bone[ AVATAR_BONE_RIGHT_PELVIS ].defaultPosePosition = glm::vec3( 0.05, 0.0, 0.0 ); + _bone[ AVATAR_BONE_RIGHT_THIGH ].defaultPosePosition = glm::vec3( 0.0, -0.15, 0.0 ); + _bone[ AVATAR_BONE_RIGHT_SHIN ].defaultPosePosition = glm::vec3( 0.0, -0.15, 0.0 ); + _bone[ AVATAR_BONE_RIGHT_FOOT ].defaultPosePosition = glm::vec3( 0.0, 0.0, 0.04 ); + + + _bone[ AVATAR_BONE_PELVIS_SPINE ].radius = 0.05; + _bone[ AVATAR_BONE_MID_SPINE ].radius = 0.06; + _bone[ AVATAR_BONE_CHEST_SPINE ].radius = 0.03; + _bone[ AVATAR_BONE_NECK ].radius = 0.02; + _bone[ AVATAR_BONE_HEAD ].radius = 0.02; + _bone[ AVATAR_BONE_LEFT_CHEST ].radius = 0.025; + _bone[ AVATAR_BONE_LEFT_SHOULDER ].radius = 0.02; + _bone[ AVATAR_BONE_LEFT_UPPER_ARM ].radius = 0.02; + _bone[ AVATAR_BONE_LEFT_FOREARM ].radius = 0.015; + _bone[ AVATAR_BONE_LEFT_HAND ].radius = 0.01; + _bone[ AVATAR_BONE_RIGHT_CHEST ].radius = 0.025; + _bone[ AVATAR_BONE_RIGHT_SHOULDER ].radius = 0.02; + _bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].radius = 0.02; + _bone[ AVATAR_BONE_RIGHT_FOREARM ].radius = 0.015; + _bone[ AVATAR_BONE_RIGHT_HAND ].radius = 0.01; + _bone[ AVATAR_BONE_LEFT_PELVIS ].radius = 0.02; + _bone[ AVATAR_BONE_LEFT_THIGH ].radius = 0.02; + _bone[ AVATAR_BONE_LEFT_SHIN ].radius = 0.015; + _bone[ AVATAR_BONE_LEFT_FOOT ].radius = 0.02; + _bone[ AVATAR_BONE_RIGHT_PELVIS ].radius = 0.02; + _bone[ AVATAR_BONE_RIGHT_THIGH ].radius = 0.02; + _bone[ AVATAR_BONE_RIGHT_SHIN ].radius = 0.015; + _bone[ AVATAR_BONE_RIGHT_FOOT ].radius = 0.02; //---------------------------------------------------------------------------- // calculate bone length @@ -1125,17 +1150,6 @@ glm::vec3 Head::getHeadPosition() { } return _bone[ AVATAR_BONE_HEAD ].position; - - -/* - return glm::vec3 - ( - _bone[ AVATAR_BONE_HEAD ].position.x, - _bone[ AVATAR_BONE_HEAD ].position.y, - _bone[ AVATAR_BONE_HEAD ].position.z - ); -*/ - } @@ -1251,18 +1265,21 @@ void Head::renderBody() { for (int b=0; b Date: Mon, 22 Apr 2013 17:21:47 -0700 Subject: [PATCH 52/60] switch to boxInFrustum() instead of pointInFrustum() for more accuracy --- interface/src/VoxelSystem.cpp | 2 +- libraries/voxels/src/VoxelTree.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index b2bcc701e0..fb7a11aef2 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -465,7 +465,7 @@ bool VoxelSystem::falseColorizeInViewOperation(VoxelNode* node, bool down, void* voxelBox.getSize().x); // If the voxel is outside of the view frustum, then false color it red - if (ViewFrustum::OUTSIDE == viewFrustum->pointInFrustum(voxelBox.getCorner())) { + if (ViewFrustum::OUTSIDE == viewFrustum->boxInFrustum(voxelBox)) { // Out of view voxels are colored RED unsigned char newR = 255; unsigned char newG = 0; diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 3e75f76184..db69535e14 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -392,7 +392,7 @@ unsigned char * VoxelTree::loadBitstreamBuffer(unsigned char *& bitstreamBuffer, bool childIsClose = true; // for now, assume we're close enough bool childInView = !viewFrustumCulling || - (ViewFrustum::OUTSIDE != viewFrustum.pointInFrustum(childBox.getCorner())); + (ViewFrustum::OUTSIDE != viewFrustum.boxInFrustum(childBox)); /// XXXBHG - debug code, switch this to true, and we'll send everything but include false coloring // on voxels based on whether or not they match these rules. From 06b794563f6fc4170df5fbb654c3f1bde4658c4a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 22 Apr 2013 17:40:27 -0700 Subject: [PATCH 53/60] stop sending avatar agents to other avatars in DS packet --- domain-server/src/main.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 05e1583fca..fceedc6678 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -135,7 +135,11 @@ int main(int argc, const char * argv[]) !agent->matches((sockaddr *)&agentPublicAddress, (sockaddr *)&agentLocalAddress, agentType)) { if (memchr(SOLO_AGENT_TYPES_STRING, agent->getType(), 1) == NULL) { // this is an agent of which there can be multiple, just add them to the packet - currentBufferPos = addAgentToBroadcastPacket(currentBufferPos, &(*agent)); + // don't send avatar agents to other avatars, that will come from avatar mixer + if (agentType != AGENT_TYPE_AVATAR || agent->getType() != AGENT_TYPE_AVATAR) { + currentBufferPos = addAgentToBroadcastPacket(currentBufferPos, &(*agent)); + } + } else { // solo agent, we need to only send newest if (newestSoloAgents[agent->getType()] == NULL || From 602fd94af26b021964872b7b9e8258988bff606f Mon Sep 17 00:00:00 2001 From: Jeffrey Ventrella Date: Mon, 22 Apr 2013 17:41:12 -0700 Subject: [PATCH 54/60] a few cleanups --- interface/src/Head.cpp | 46 ++++++++++-------------------------------- interface/src/main.cpp | 7 +------ 2 files changed, 12 insertions(+), 41 deletions(-) diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index f3b0d4cb65..d1bbf5e65b 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -149,7 +149,7 @@ Head::Head(const Head &otherAvatar) { _bodyPitch = otherAvatar._bodyPitch; _bodyRoll = otherAvatar._bodyRoll; _bodyYawDelta = otherAvatar._bodyYawDelta; - _mousePressed = otherAvatar._mousePressed; + _mousePressed = otherAvatar._mousePressed; _mode = otherAvatar._mode; _isMine = otherAvatar._isMine; _renderYaw = otherAvatar._renderYaw; @@ -892,45 +892,25 @@ void Head::initializeSkeleton() { //---------------------------------------------------------------------------- // parental hierarchy //---------------------------------------------------------------------------- - - //---------------------------------------------------------------------------- - // spine and head - //---------------------------------------------------------------------------- _bone[ AVATAR_BONE_PELVIS_SPINE ].parent = AVATAR_BONE_NULL; _bone[ AVATAR_BONE_MID_SPINE ].parent = AVATAR_BONE_PELVIS_SPINE; _bone[ AVATAR_BONE_CHEST_SPINE ].parent = AVATAR_BONE_MID_SPINE; _bone[ AVATAR_BONE_NECK ].parent = AVATAR_BONE_CHEST_SPINE; _bone[ AVATAR_BONE_HEAD ].parent = AVATAR_BONE_NECK; - - //---------------------------------------------------------------------------- - // left chest and arm - //---------------------------------------------------------------------------- _bone[ AVATAR_BONE_LEFT_CHEST ].parent = AVATAR_BONE_MID_SPINE; _bone[ AVATAR_BONE_LEFT_SHOULDER ].parent = AVATAR_BONE_LEFT_CHEST; _bone[ AVATAR_BONE_LEFT_UPPER_ARM ].parent = AVATAR_BONE_LEFT_SHOULDER; _bone[ AVATAR_BONE_LEFT_FOREARM ].parent = AVATAR_BONE_LEFT_UPPER_ARM; _bone[ AVATAR_BONE_LEFT_HAND ].parent = AVATAR_BONE_LEFT_FOREARM; - - //---------------------------------------------------------------------------- - // right chest and arm - //---------------------------------------------------------------------------- _bone[ AVATAR_BONE_RIGHT_CHEST ].parent = AVATAR_BONE_MID_SPINE; _bone[ AVATAR_BONE_RIGHT_SHOULDER ].parent = AVATAR_BONE_RIGHT_CHEST; _bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].parent = AVATAR_BONE_RIGHT_SHOULDER; _bone[ AVATAR_BONE_RIGHT_FOREARM ].parent = AVATAR_BONE_RIGHT_UPPER_ARM; _bone[ AVATAR_BONE_RIGHT_HAND ].parent = AVATAR_BONE_RIGHT_FOREARM; - - //---------------------------------------------------------------------------- - // left pelvis and leg - //---------------------------------------------------------------------------- _bone[ AVATAR_BONE_LEFT_PELVIS ].parent = AVATAR_BONE_PELVIS_SPINE; _bone[ AVATAR_BONE_LEFT_THIGH ].parent = AVATAR_BONE_LEFT_PELVIS; _bone[ AVATAR_BONE_LEFT_SHIN ].parent = AVATAR_BONE_LEFT_THIGH; _bone[ AVATAR_BONE_LEFT_FOOT ].parent = AVATAR_BONE_LEFT_SHIN; - - //---------------------------------------------------------------------------- - // right pelvis and leg - //---------------------------------------------------------------------------- _bone[ AVATAR_BONE_RIGHT_PELVIS ].parent = AVATAR_BONE_PELVIS_SPINE; _bone[ AVATAR_BONE_RIGHT_THIGH ].parent = AVATAR_BONE_RIGHT_PELVIS; _bone[ AVATAR_BONE_RIGHT_SHIN ].parent = AVATAR_BONE_RIGHT_THIGH; @@ -944,12 +924,12 @@ void Head::initializeSkeleton() { _bone[ AVATAR_BONE_CHEST_SPINE ].defaultPosePosition = glm::vec3( 0.0, 0.06, 0.0 ); _bone[ AVATAR_BONE_NECK ].defaultPosePosition = glm::vec3( 0.0, 0.06, 0.0 ); _bone[ AVATAR_BONE_HEAD ].defaultPosePosition = glm::vec3( 0.0, 0.06, 0.0 ); - _bone[ AVATAR_BONE_LEFT_CHEST ].defaultPosePosition = glm::vec3( -0.06, 0.06, 0.0 ); + _bone[ AVATAR_BONE_LEFT_CHEST ].defaultPosePosition = glm::vec3( -0.05, 0.05, 0.0 ); _bone[ AVATAR_BONE_LEFT_SHOULDER ].defaultPosePosition = glm::vec3( -0.03, 0.0, 0.0 ); _bone[ AVATAR_BONE_LEFT_UPPER_ARM ].defaultPosePosition = glm::vec3( 0.0, -0.1, 0.0 ); _bone[ AVATAR_BONE_LEFT_FOREARM ].defaultPosePosition = glm::vec3( 0.0, -0.1, 0.0 ); _bone[ AVATAR_BONE_LEFT_HAND ].defaultPosePosition = glm::vec3( 0.0, -0.05, 0.0 ); - _bone[ AVATAR_BONE_RIGHT_CHEST ].defaultPosePosition = glm::vec3( 0.06, 0.06, 0.0 ); + _bone[ AVATAR_BONE_RIGHT_CHEST ].defaultPosePosition = glm::vec3( 0.05, 0.05, 0.0 ); _bone[ AVATAR_BONE_RIGHT_SHOULDER ].defaultPosePosition = glm::vec3( 0.03, 0.0, 0.0 ); _bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].defaultPosePosition = glm::vec3( 0.0, -0.1, 0.0 ); _bone[ AVATAR_BONE_RIGHT_FOREARM ].defaultPosePosition = glm::vec3( 0.0, -0.1, 0.0 ); @@ -971,12 +951,12 @@ void Head::initializeSkeleton() { _bone[ AVATAR_BONE_HEAD ].radius = 0.02; _bone[ AVATAR_BONE_LEFT_CHEST ].radius = 0.025; _bone[ AVATAR_BONE_LEFT_SHOULDER ].radius = 0.02; - _bone[ AVATAR_BONE_LEFT_UPPER_ARM ].radius = 0.02; + _bone[ AVATAR_BONE_LEFT_UPPER_ARM ].radius = 0.015; _bone[ AVATAR_BONE_LEFT_FOREARM ].radius = 0.015; _bone[ AVATAR_BONE_LEFT_HAND ].radius = 0.01; _bone[ AVATAR_BONE_RIGHT_CHEST ].radius = 0.025; _bone[ AVATAR_BONE_RIGHT_SHOULDER ].radius = 0.02; - _bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].radius = 0.02; + _bone[ AVATAR_BONE_RIGHT_UPPER_ARM ].radius = 0.015; _bone[ AVATAR_BONE_RIGHT_FOREARM ].radius = 0.015; _bone[ AVATAR_BONE_RIGHT_HAND ].radius = 0.01; _bone[ AVATAR_BONE_LEFT_PELVIS ].radius = 0.02; @@ -1157,16 +1137,12 @@ void Head::updateHandMovement() { if ( _usingBodySprings ) { if ( _closestOtherAvatar != -1 ) { if ( _mousePressed ) { + + + glm::vec3 handToHandVector( _otherAvatarHandPosition[ _closestOtherAvatar ]); + handToHandVector -= _bone[ AVATAR_BONE_RIGHT_HAND ].position; - /* - glm::vec3 handShakePull( DEBUG_otherAvatarListPosition[ closestOtherAvatar ]); - handShakePull -= _bone[ AVATAR_BONE_RIGHT_HAND ].position; - - handShakePull *= 1.0; - - transformedHandMovement += handShakePull; - */ - + //_bone[ AVATAR_BONE_RIGHT_HAND ].springyVelocity -= handPull; _bone[ AVATAR_BONE_RIGHT_HAND ].position = _otherAvatarHandPosition[ _closestOtherAvatar ]; } } @@ -1250,7 +1226,7 @@ void Head::renderBody() { //renderBoneAsBlock( (AvatarBoneID)b); //render bone orientation - //renderOrientationDirections( _bone[b].position, _bone[b].orientation, 0.05f ); + renderOrientationDirections( _bone[b].springyPosition, _bone[b].orientation, _bone[b].radius * 2.0 ); if ( _usingBodySprings ) { glColor3fv( skinColor ); diff --git a/interface/src/main.cpp b/interface/src/main.cpp index c71a94da9a..b3883f6e97 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -1500,7 +1500,7 @@ void idle(void) { // // Sample hardware, update view frustum if needed, Lsend avatar data to mixer/agents // - updateAvatar( 1.f/FPS ); + updateAvatar(deltaTime); //loop through all the other avatars and simulate them. AgentList * agentList = AgentList::getInstance(); @@ -1509,14 +1509,9 @@ void idle(void) { if (agent->getLinkedData() != NULL) { Head *avatar = (Head *)agent->getLinkedData(); - -//printf( "simulating remote avatar\n" ); - avatar->simulate(deltaTime); } } - - //updateAvatarHand(1.f/FPS); field.simulate (deltaTime); myAvatar.simulate(deltaTime); From 9d17dc0387fe7a75303d9341e622876189df4a58 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Apr 2013 17:43:28 -0700 Subject: [PATCH 55/60] make view frustum culling default behavior, removed soem debug printf()s for now --- libraries/voxels/src/ViewFrustum.cpp | 26 ++++++++++++-------------- voxel-server/src/main.cpp | 6 +++--- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/libraries/voxels/src/ViewFrustum.cpp b/libraries/voxels/src/ViewFrustum.cpp index 5c9022c27e..8bdb2d97cb 100644 --- a/libraries/voxels/src/ViewFrustum.cpp +++ b/libraries/voxels/src/ViewFrustum.cpp @@ -192,16 +192,16 @@ int ViewFrustum::sphereInFrustum(const glm::vec3& center, float radius) const { int ViewFrustum::boxInFrustum(const AABox& box) const { - printf("ViewFrustum::boxInFrustum() box.corner=%f,%f,%f x=%f\n", - box.getCorner().x,box.getCorner().y,box.getCorner().z,box.getSize().x); + //printf("ViewFrustum::boxInFrustum() box.corner=%f,%f,%f x=%f\n", + // box.getCorner().x,box.getCorner().y,box.getCorner().z,box.getSize().x); int result = INSIDE; for(int i=0; i < 6; i++) { - printf("plane[%d] -- point(%f,%f,%f) normal(%f,%f,%f) d=%f \n",i, - _planes[i].getPoint().x, _planes[i].getPoint().y, _planes[i].getPoint().z, - _planes[i].getNormal().x, _planes[i].getNormal().y, _planes[i].getNormal().z, - _planes[i].getDCoefficient() - ); + //printf("plane[%d] -- point(%f,%f,%f) normal(%f,%f,%f) d=%f \n",i, + // _planes[i].getPoint().x, _planes[i].getPoint().y, _planes[i].getPoint().z, + // _planes[i].getNormal().x, _planes[i].getNormal().y, _planes[i].getNormal().z, + // _planes[i].getDCoefficient() + //); glm::vec3 normal = _planes[i].getNormal(); glm::vec3 boxVertexP = box.getVertexP(normal); @@ -210,13 +210,11 @@ int ViewFrustum::boxInFrustum(const AABox& box) const { glm::vec3 boxVertexN = box.getVertexN(normal); float planeToBoxVertexNDistance = _planes[i].distance(boxVertexN); - - - printf("plane[%d] normal=(%f,%f,%f) bVertexP=(%f,%f,%f) planeToBoxVertexPDistance=%f boxVertexN=(%f,%f,%f) planeToBoxVertexNDistance=%f\n",i, - normal.x,normal.y,normal.z, - boxVertexP.x,boxVertexP.y,boxVertexP.z,planeToBoxVertexPDistance, - boxVertexN.x,boxVertexN.y,boxVertexN.z,planeToBoxVertexNDistance - ); + //printf("plane[%d] normal=(%f,%f,%f) bVertexP=(%f,%f,%f) planeToBoxVertexPDistance=%f boxVertexN=(%f,%f,%f) planeToBoxVertexNDistance=%f\n",i, + // normal.x,normal.y,normal.z, + // boxVertexP.x,boxVertexP.y,boxVertexP.z,planeToBoxVertexPDistance, + // boxVertexN.x,boxVertexN.y,boxVertexN.z,planeToBoxVertexNDistance + // ); if (planeToBoxVertexPDistance < 0) { return OUTSIDE; diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index d85154abc5..91fa2fd596 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -49,7 +49,7 @@ VoxelTree randomTree; bool wantColorRandomizer = false; bool debugViewFrustum = false; -bool viewFrustumCulling = false; // for now +bool viewFrustumCulling = true; // for now void addSphere(VoxelTree * tree,bool random, bool wantColorRandomizer) { float r = random ? randFloatInRange(0.05,0.1) : 0.25; @@ -276,8 +276,8 @@ int main(int argc, const char * argv[]) ::debugViewFrustum = cmdOptionExists(argc, argv, DEBUG_VIEW_FRUSTUM); printf("debugViewFrustum=%s\n", (::debugViewFrustum ? "yes" : "no")); - const char* VIEW_FRUSTUM_CULLING = "--ViewFrustumCulling"; - ::viewFrustumCulling = cmdOptionExists(argc, argv, VIEW_FRUSTUM_CULLING); + const char* NO_VIEW_FRUSTUM_CULLING = "--NoViewFrustumCulling"; + ::viewFrustumCulling = !cmdOptionExists(argc, argv, NO_VIEW_FRUSTUM_CULLING); printf("viewFrustumCulling=%s\n", (::viewFrustumCulling ? "yes" : "no")); const char* WANT_COLOR_RANDOMIZER = "--WantColorRandomizer"; From d895665d5f6071df25b775587049c5de48af1c23 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 22 Apr 2013 17:55:48 -0700 Subject: [PATCH 56/60] create missing agents sent from the avatar mixer --- libraries/shared/src/Agent.cpp | 32 ++++++++++++++++++++++-------- libraries/shared/src/AgentList.cpp | 24 +++++++++++++++------- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/libraries/shared/src/Agent.cpp b/libraries/shared/src/Agent.cpp index 637a1bc58a..26290e1c1a 100644 --- a/libraries/shared/src/Agent.cpp +++ b/libraries/shared/src/Agent.cpp @@ -23,11 +23,19 @@ using shared_lib::printLog; Agent::Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agentType, uint16_t thisAgentId) { - publicSocket = new sockaddr; - memcpy(publicSocket, agentPublicSocket, sizeof(sockaddr)); + if (agentPublicSocket != NULL) { + publicSocket = new sockaddr; + memcpy(publicSocket, agentPublicSocket, sizeof(sockaddr)); + } else { + publicSocket = NULL; + } - localSocket = new sockaddr; - memcpy(localSocket, agentLocalSocket, sizeof(sockaddr)); + if (agentLocalSocket != NULL) { + localSocket = new sockaddr; + memcpy(localSocket, agentLocalSocket, sizeof(sockaddr)); + } else { + localSocket = NULL; + } type = agentType; agentId = thisAgentId; @@ -44,11 +52,19 @@ Agent::Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agent } Agent::Agent(const Agent &otherAgent) { - publicSocket = new sockaddr; - memcpy(publicSocket, otherAgent.publicSocket, sizeof(sockaddr)); + if (otherAgent.publicSocket != NULL) { + publicSocket = new sockaddr; + memcpy(publicSocket, otherAgent.publicSocket, sizeof(sockaddr)); + } else { + publicSocket = NULL; + } - localSocket = new sockaddr; - memcpy(localSocket, otherAgent.localSocket, sizeof(sockaddr)); + if (otherAgent.localSocket != NULL) { + localSocket = new sockaddr; + memcpy(localSocket, otherAgent.localSocket, sizeof(sockaddr)); + } else { + localSocket = NULL; + } agentId = otherAgent.agentId; diff --git a/libraries/shared/src/AgentList.cpp b/libraries/shared/src/AgentList.cpp index b89c9aa70c..c1c7ee1f63 100644 --- a/libraries/shared/src/AgentList.cpp +++ b/libraries/shared/src/AgentList.cpp @@ -130,11 +130,16 @@ void AgentList::processBulkAgentData(sockaddr *senderAddress, unsigned char *pac int matchingAgentIndex = indexOfMatchingAgent(agentID); - if (matchingAgentIndex >= 0) { + if (matchingAgentIndex < 0) { + // we're missing this agent, we need to add it to the list + addOrUpdateAgent(NULL, NULL, AGENT_TYPE_AVATAR, agentID); - updateAgentWithData(&agents[matchingAgentIndex], packetHolder, numBytesPerAgent + 1); + // theoretically if we can lock the vector we could assume this is size - 1 + matchingAgentIndex = indexOfMatchingAgent(agentID); } + updateAgentWithData(&agents[matchingAgentIndex], packetHolder, numBytesPerAgent + 1); + currentPosition += numBytesPerAgent; } } @@ -219,11 +224,15 @@ int AgentList::updateList(unsigned char *packetData, size_t dataBytes) { bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, char agentType, uint16_t agentId) { std::vector::iterator agent; - for (agent = agents.begin(); agent != agents.end(); agent++) { - if (agent->matches(publicSocket, localSocket, agentType)) { - // we already have this agent, stop checking - break; + if (publicSocket != NULL) { + for (agent = agents.begin(); agent != agents.end(); agent++) { + if (agent->matches(publicSocket, localSocket, agentType)) { + // we already have this agent, stop checking + break; + } } + } else { + agent = agents.end(); } if (agent == agents.end()) { @@ -316,7 +325,8 @@ void *pingUnknownAgents(void *args) { for(std::vector::iterator agent = agentList->getAgents().begin(); agent != agentList->getAgents().end(); agent++) { - if (agent->getActiveSocket() == NULL) { + if (agent->getActiveSocket() == NULL + && (agent->getPublicSocket() != NULL && agent->getLocalSocket() != NULL)) { // ping both of the sockets for the agent so we can figure out // which socket we can use agentList->getAgentSocket().send(agent->getPublicSocket(), &PACKET_HEADER_PING, 1); From 4956370d525cdc3e7b8b1af5ef1fa3ea1f47c477 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 22 Apr 2013 18:05:27 -0700 Subject: [PATCH 57/60] have parseData return the number of bytes consumed --- interface/src/VoxelSystem.cpp | 3 ++- interface/src/VoxelSystem.h | 2 +- interface/src/main.cpp | 3 +-- libraries/avatars/src/AvatarData.cpp | 6 ++++- libraries/avatars/src/AvatarData.h | 4 +--- libraries/shared/src/AgentData.h | 2 +- libraries/shared/src/AgentList.cpp | 22 ++++++++++--------- libraries/shared/src/AgentList.h | 6 ++--- libraries/shared/src/AudioRingBuffer.cpp | 6 +++-- libraries/shared/src/AudioRingBuffer.h | 2 +- libraries/shared/src/UDPSocket.cpp | 28 ++++++++++++++---------- 11 files changed, 47 insertions(+), 37 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index fb7a11aef2..c9e6b3186f 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -114,7 +114,7 @@ float VoxelSystem::getVoxelsBytesReadPerSecondAverage() { } -void VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { +int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { unsigned char command = *sourceBuffer; unsigned char *voxelData = sourceBuffer + 1; @@ -154,6 +154,7 @@ void VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { } setupNewVoxelsForDrawing(); + return numBytes; } void VoxelSystem::setupNewVoxelsForDrawing() { diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index e133b4c039..4c309a92ea 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -26,7 +26,7 @@ public: VoxelSystem(); ~VoxelSystem(); - void parseData(unsigned char* sourceBuffer, int numBytes); + int parseData(unsigned char* sourceBuffer, int numBytes); VoxelSystem* clone() const; void init(); diff --git a/interface/src/main.cpp b/interface/src/main.cpp index b3883f6e97..1c075a62d9 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -1456,8 +1456,7 @@ void *networkReceive(void *args) case PACKET_HEADER_BULK_AVATAR_DATA: AgentList::getInstance()->processBulkAgentData(&senderAddress, incomingPacket, - bytesReceived, - BYTES_PER_AVATAR); + bytesReceived); break; default: AgentList::getInstance()->processAgentData(&senderAddress, incomingPacket, bytesReceived); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 4189575e67..d36894a793 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -95,7 +95,9 @@ 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) { +int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { + unsigned char* startPosition = sourceBuffer; + // increment to push past the packet header sourceBuffer++; @@ -126,6 +128,8 @@ void AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { sourceBuffer += sizeof(_cameraNearClip); memcpy(&_cameraFarClip, sourceBuffer, sizeof(_cameraFarClip)); sourceBuffer += sizeof(_cameraFarClip); + + return sourceBuffer - startPosition; } glm::vec3 AvatarData::getBodyPosition() { diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 819333d558..ea735c62fe 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -13,8 +13,6 @@ #include -const int BYTES_PER_AVATAR = 94; - class AvatarData : public AgentData { public: AvatarData(); @@ -27,7 +25,7 @@ public: void setHandPosition(glm::vec3 handPosition); int getBroadcastData(unsigned char* destinationBuffer); - void parseData(unsigned char* sourceBuffer, int numBytes); + int parseData(unsigned char* sourceBuffer, int numBytes); float getBodyYaw(); void setBodyYaw(float bodyYaw); diff --git a/libraries/shared/src/AgentData.h b/libraries/shared/src/AgentData.h index 640798b52b..f8bef16b41 100644 --- a/libraries/shared/src/AgentData.h +++ b/libraries/shared/src/AgentData.h @@ -12,7 +12,7 @@ class AgentData { public: virtual ~AgentData() = 0; - virtual void parseData(unsigned char* sourceBuffer, int numBytes) = 0; + virtual int parseData(unsigned char* sourceBuffer, int numBytes) = 0; virtual AgentData* clone() const = 0; }; diff --git a/libraries/shared/src/AgentList.cpp b/libraries/shared/src/AgentList.cpp index c1c7ee1f63..77a726bc56 100644 --- a/libraries/shared/src/AgentList.cpp +++ b/libraries/shared/src/AgentList.cpp @@ -106,7 +106,7 @@ void AgentList::processAgentData(sockaddr *senderAddress, unsigned char *packetD } } -void AgentList::processBulkAgentData(sockaddr *senderAddress, unsigned char *packetData, int numTotalBytes, int numBytesPerAgent) { +void AgentList::processBulkAgentData(sockaddr *senderAddress, unsigned char *packetData, int numTotalBytes) { // find the avatar mixer in our agent list and update the lastRecvTime from it int bulkSendAgentIndex = indexOfMatchingAgent(senderAddress); @@ -118,7 +118,7 @@ void AgentList::processBulkAgentData(sockaddr *senderAddress, unsigned char *pac unsigned char *startPosition = packetData; unsigned char *currentPosition = startPosition + 1; - unsigned char packetHolder[numBytesPerAgent + 1]; + unsigned char packetHolder[numTotalBytes]; packetHolder[0] = PACKET_HEADER_HEAD_DATA; @@ -126,7 +126,7 @@ void AgentList::processBulkAgentData(sockaddr *senderAddress, unsigned char *pac while ((currentPosition - startPosition) < numTotalBytes) { currentPosition += unpackAgentId(currentPosition, &agentID); - memcpy(packetHolder + 1, currentPosition, numBytesPerAgent); + memcpy(packetHolder + 1, currentPosition, numTotalBytes - (currentPosition - startPosition)); int matchingAgentIndex = indexOfMatchingAgent(agentID); @@ -138,22 +138,24 @@ void AgentList::processBulkAgentData(sockaddr *senderAddress, unsigned char *pac matchingAgentIndex = indexOfMatchingAgent(agentID); } - updateAgentWithData(&agents[matchingAgentIndex], packetHolder, numBytesPerAgent + 1); - - currentPosition += numBytesPerAgent; + currentPosition += updateAgentWithData(&agents[matchingAgentIndex], + packetHolder, + numTotalBytes - (currentPosition - startPosition)); } } -void AgentList::updateAgentWithData(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes) { +int AgentList::updateAgentWithData(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes) { // find the agent by the sockaddr int agentIndex = indexOfMatchingAgent(senderAddress); if (agentIndex != -1) { - updateAgentWithData(&agents[agentIndex], packetData, dataBytes); + return updateAgentWithData(&agents[agentIndex], packetData, dataBytes); + } else { + return 0; } } -void AgentList::updateAgentWithData(Agent *agent, unsigned char *packetData, int dataBytes) { +int AgentList::updateAgentWithData(Agent *agent, unsigned char *packetData, int dataBytes) { agent->setLastRecvTimeUsecs(usecTimestampNow()); agent->recordBytesReceived(dataBytes); @@ -163,7 +165,7 @@ void AgentList::updateAgentWithData(Agent *agent, unsigned char *packetData, int } } - agent->getLinkedData()->parseData(packetData, dataBytes); + return agent->getLinkedData()->parseData(packetData, dataBytes); } int AgentList::indexOfMatchingAgent(sockaddr *senderAddress) { diff --git a/libraries/shared/src/AgentList.h b/libraries/shared/src/AgentList.h index adc66333f9..f62d527116 100644 --- a/libraries/shared/src/AgentList.h +++ b/libraries/shared/src/AgentList.h @@ -50,10 +50,10 @@ public: bool addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, char agentType, uint16_t agentId); void processAgentData(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes); - void processBulkAgentData(sockaddr *senderAddress, unsigned char *packetData, int numTotalBytes, int numBytesPerAgent); + void processBulkAgentData(sockaddr *senderAddress, unsigned char *packetData, int numTotalBytes); - void updateAgentWithData(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes); - void updateAgentWithData(Agent *agent, unsigned char *packetData, int dataBytes); + int updateAgentWithData(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes); + int updateAgentWithData(Agent *agent, unsigned char *packetData, int dataBytes); void broadcastToAgents(unsigned char *broadcastData, size_t dataBytes, const char* agentTypes, int numAgentTypes); char getOwnerType(); diff --git a/libraries/shared/src/AudioRingBuffer.cpp b/libraries/shared/src/AudioRingBuffer.cpp index 2197d03706..5180e238cb 100644 --- a/libraries/shared/src/AudioRingBuffer.cpp +++ b/libraries/shared/src/AudioRingBuffer.cpp @@ -105,7 +105,7 @@ void AudioRingBuffer::setBearing(float newBearing) { bearing = newBearing; } -void AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { +int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { if (numBytes > (bufferLengthSamples * sizeof(int16_t))) { unsigned char *dataPtr = sourceBuffer + 1; @@ -140,7 +140,9 @@ void AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { if (endOfLastWrite >= buffer + ringBufferLengthSamples) { endOfLastWrite = buffer; - } + } + + return numBytes; } short AudioRingBuffer::diffLastWriteNextOutput() diff --git a/libraries/shared/src/AudioRingBuffer.h b/libraries/shared/src/AudioRingBuffer.h index a87331f330..48620aa133 100644 --- a/libraries/shared/src/AudioRingBuffer.h +++ b/libraries/shared/src/AudioRingBuffer.h @@ -18,7 +18,7 @@ class AudioRingBuffer : public AgentData { ~AudioRingBuffer(); AudioRingBuffer(const AudioRingBuffer &otherRingBuffer); - void parseData(unsigned char* sourceBuffer, int numBytes); + int parseData(unsigned char* sourceBuffer, int numBytes); AudioRingBuffer* clone() const; int16_t* getNextOutput(); diff --git a/libraries/shared/src/UDPSocket.cpp b/libraries/shared/src/UDPSocket.cpp index 42da682d7b..000f0e3d7d 100644 --- a/libraries/shared/src/UDPSocket.cpp +++ b/libraries/shared/src/UDPSocket.cpp @@ -28,20 +28,24 @@ using shared_lib::printLog; sockaddr_in destSockaddr, senderAddress; bool socketMatch(sockaddr *first, sockaddr *second) { - // utility function that indicates if two sockets are equivalent - - // currently only compares two IPv4 addresses - // expandable to IPv6 by adding else if for AF_INET6 - - if (first->sa_family != second->sa_family) { - // not the same family, can't be equal - return false; - } else if (first->sa_family == AF_INET) { - sockaddr_in *firstIn = (sockaddr_in *) first; - sockaddr_in *secondIn = (sockaddr_in *) second; + if (first != NULL && second != NULL) { + // utility function that indicates if two sockets are equivalent - return firstIn->sin_addr.s_addr == secondIn->sin_addr.s_addr + // currently only compares two IPv4 addresses + // expandable to IPv6 by adding else if for AF_INET6 + + if (first->sa_family != second->sa_family) { + // not the same family, can't be equal + return false; + } else if (first->sa_family == AF_INET) { + sockaddr_in *firstIn = (sockaddr_in *) first; + sockaddr_in *secondIn = (sockaddr_in *) second; + + return firstIn->sin_addr.s_addr == secondIn->sin_addr.s_addr && firstIn->sin_port == secondIn->sin_port; + } else { + return false; + } } else { return false; } From b291b5d1f65c699657d81615254436526feb800b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 22 Apr 2013 18:07:58 -0700 Subject: [PATCH 58/60] fixed bug in initialization of false color (actually true color) --- libraries/voxels/src/VoxelNode.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libraries/voxels/src/VoxelNode.cpp b/libraries/voxels/src/VoxelNode.cpp index 9fab2c1092..4278d8d75e 100644 --- a/libraries/voxels/src/VoxelNode.cpp +++ b/libraries/voxels/src/VoxelNode.cpp @@ -58,6 +58,12 @@ void VoxelNode::getAABox(AABox& box) const { void VoxelNode::addChildAtIndex(int childIndex) { children[childIndex] = new VoxelNode(); + // XXXBHG - When the node is constructed, it should be cleanly set up as + // true colored, but for some reason, not so much. I've added a a basecamp + // to-do to research this. But for now we'll use belt and suspenders and set + // it to not-false-colored here! + children[childIndex]->setFalseColored(false); + // give this child its octal code children[childIndex]->octalCode = childOctalCode(octalCode, childIndex); } From 8201b963d13c462fb031c9a1275b12ea936fd398 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 22 Apr 2013 18:36:13 -0700 Subject: [PATCH 59/60] fix crash for NULL agent sockets --- libraries/shared/src/Agent.cpp | 32 +++++++++++++++++------------- libraries/shared/src/Agent.h | 1 - libraries/shared/src/AgentList.cpp | 9 ++++++--- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/libraries/shared/src/Agent.cpp b/libraries/shared/src/Agent.cpp index 26290e1c1a..bb49783210 100644 --- a/libraries/shared/src/Agent.cpp +++ b/libraries/shared/src/Agent.cpp @@ -264,23 +264,27 @@ void Agent::printLog(Agent const& agent) { sockaddr_in *agentPublicSocket = (sockaddr_in *) agent.publicSocket; sockaddr_in *agentLocalSocket = (sockaddr_in *) agent.localSocket; + + const char* publicAddressString = (agentPublicSocket == NULL) + ? "Unknown" + : inet_ntoa(agentPublicSocket->sin_addr); + unsigned short publicAddressPort = (agentPublicSocket == NULL) + ? 0 + : ntohs(agentPublicSocket->sin_port); + + const char* localAddressString = (agentLocalSocket == NULL) + ? "Unknown" + : inet_ntoa(agentLocalSocket->sin_addr); + unsigned short localAddressPort = (agentLocalSocket == NULL) + ? 0 + : ntohs(agentPublicSocket->sin_port); ::printLog("ID: %d T: %s (%c) PA: %s:%d LA: %s:%d\n", agent.agentId, agent.getTypeName(), agent.type, - inet_ntoa(agentPublicSocket->sin_addr), - ntohs(agentPublicSocket->sin_port), - inet_ntoa(agentLocalSocket->sin_addr), - ntohs(agentLocalSocket->sin_port)); -} - -std::ostream& operator<<(std::ostream& os, const Agent* agent) { - sockaddr_in *agentPublicSocket = (sockaddr_in *)agent->publicSocket; - sockaddr_in *agentLocalSocket = (sockaddr_in *)agent->localSocket; - - os << "T: " << agent->getTypeName() << " (" << agent->type << ") PA: " << inet_ntoa(agentPublicSocket->sin_addr) << - ":" << ntohs(agentPublicSocket->sin_port) << " LA: " << inet_ntoa(agentLocalSocket->sin_addr) << - ":" << ntohs(agentLocalSocket->sin_port); - return os; + publicAddressString, + publicAddressPort, + localAddressString, + localAddressPort); } \ No newline at end of file diff --git a/libraries/shared/src/Agent.h b/libraries/shared/src/Agent.h index 14942defcb..b1d2347c21 100644 --- a/libraries/shared/src/Agent.h +++ b/libraries/shared/src/Agent.h @@ -63,7 +63,6 @@ public: float getAveragePacketsPerSecond(); static void printLog(Agent const&); - friend std::ostream& operator<<(std::ostream& os, const Agent* agent); private: void swap(Agent &first, Agent &second); diff --git a/libraries/shared/src/AgentList.cpp b/libraries/shared/src/AgentList.cpp index 77a726bc56..5744c0780a 100644 --- a/libraries/shared/src/AgentList.cpp +++ b/libraries/shared/src/AgentList.cpp @@ -157,14 +157,17 @@ int AgentList::updateAgentWithData(sockaddr *senderAddress, unsigned char *packe int AgentList::updateAgentWithData(Agent *agent, unsigned char *packetData, int dataBytes) { agent->setLastRecvTimeUsecs(usecTimestampNow()); - agent->recordBytesReceived(dataBytes); + + if (agent->getActiveSocket() != NULL) { + agent->recordBytesReceived(dataBytes); + } if (agent->getLinkedData() == NULL) { if (linkedDataCreateCallback != NULL) { linkedDataCreateCallback(agent); } } - + return agent->getLinkedData()->parseData(packetData, dataBytes); } @@ -180,7 +183,7 @@ int AgentList::indexOfMatchingAgent(sockaddr *senderAddress) { int AgentList::indexOfMatchingAgent(uint16_t agentID) { for(std::vector::iterator agent = agents.begin(); agent != agents.end(); agent++) { - if (agent->getActiveSocket() != NULL && agent->getAgentId() == agentID) { + if (agent->getAgentId() == agentID) { return agent - agents.begin(); } } From 79d547e9d0a512e6cd0dfa4e8e2250d551654597 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 22 Apr 2013 18:41:12 -0700 Subject: [PATCH 60/60] fix return of bytes read to push pointer forwards --- libraries/avatars/src/AvatarData.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index d36894a793..d644937464 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -96,11 +96,12 @@ int AvatarData::getBroadcastData(unsigned char* destinationBuffer) { // called on the other agents - assigns it to my views of the others int AvatarData::parseData(unsigned char* sourceBuffer, int numBytes) { - unsigned char* startPosition = sourceBuffer; - + // increment to push past the packet header sourceBuffer++; + unsigned char* startPosition = sourceBuffer; + memcpy(&_bodyPosition, sourceBuffer, sizeof(float) * 3); sourceBuffer += sizeof(float) * 3;