From 677e2580e17125f55dde74837fdbaf41e76e2197 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Wed, 17 Jul 2013 14:42:20 -0700 Subject: [PATCH 1/3] make send only changed bits work better --- libraries/voxels/src/VoxelTree.cpp | 10 ++++------ libraries/voxels/src/VoxelTree.h | 6 ++++-- voxel-server/src/VoxelNodeData.cpp | 16 ++++++++++++++++ voxel-server/src/VoxelNodeData.h | 7 ++++++- voxel-server/src/main.cpp | 10 ++++------ 5 files changed, 34 insertions(+), 15 deletions(-) diff --git a/libraries/voxels/src/VoxelTree.cpp b/libraries/voxels/src/VoxelTree.cpp index 91a31a6cd1..203ed7e908 100644 --- a/libraries/voxels/src/VoxelTree.cpp +++ b/libraries/voxels/src/VoxelTree.cpp @@ -1114,14 +1114,12 @@ int VoxelTree::encodeTreeBitstreamRecursion(VoxelNode* node, unsigned char* outp return bytesAtThisLevel; } - /** Not ready for production - coming soon. - // If we're not in delta sending mode, but the voxel hasn't changed, then we can also bail early... - if (!params.deltaViewFrustum && !node->hasChangedSince(params.lastViewFrustumSent - CHANGE_FUDGE)) { - printf("not delta sending, and the node hasn't changed, bail early... lastSent=%lld getLastChanged=%lld\n", - params.lastViewFrustumSent, node->getLastChanged()); + // If we're not in delta sending mode, and we weren't asked to do a force send, and the voxel hasn't changed, + // then we can also bail early and save bits + if (!params.forceSendScene && !params.deltaViewFrustum && + !node->hasChangedSince(params.lastViewFrustumSent - CHANGE_FUDGE)) { return bytesAtThisLevel; } - **/ // If the user also asked for occlusion culling, check if this node is occluded, but only if it's not a leaf. // leaf occlusion is handled down below when we check child nodes diff --git a/libraries/voxels/src/VoxelTree.h b/libraries/voxels/src/VoxelTree.h index bab66c5097..e5db6526e9 100644 --- a/libraries/voxels/src/VoxelTree.h +++ b/libraries/voxels/src/VoxelTree.h @@ -51,7 +51,7 @@ public: long childWasInViewDiscarded; int boundaryLevelAdjust; uint64_t lastViewFrustumSent; - + bool forceSendScene; CoverageMap* map; EncodeBitstreamParams( @@ -65,7 +65,8 @@ public: bool wantOcclusionCulling= NO_OCCLUSION_CULLING, CoverageMap* map = IGNORE_COVERAGE_MAP, int boundaryLevelAdjust = NO_BOUNDARY_ADJUST, - uint64_t lastViewFrustumSent = IGNORE_LAST_SENT) : + uint64_t lastViewFrustumSent = IGNORE_LAST_SENT, + bool forceSendScene = true) : maxEncodeLevel (maxEncodeLevel), maxLevelReached (0), viewFrustum (viewFrustum), @@ -78,6 +79,7 @@ public: childWasInViewDiscarded (0), boundaryLevelAdjust (boundaryLevelAdjust), lastViewFrustumSent (lastViewFrustumSent), + forceSendScene (forceSendScene), map (map) {} }; diff --git a/voxel-server/src/VoxelNodeData.cpp b/voxel-server/src/VoxelNodeData.cpp index f3d87948aa..c4b8ee8b79 100644 --- a/voxel-server/src/VoxelNodeData.cpp +++ b/voxel-server/src/VoxelNodeData.cpp @@ -20,6 +20,7 @@ VoxelNodeData::VoxelNodeData(Node* owningNode) : _maxLevelReachedInLastSearch(1), _lastTimeBagEmpty(0), _viewFrustumChanging(false), + _viewFrustumJustStoppedChanging(true), _currentPacketIsColor(true) { _voxelPacket = new unsigned char[MAX_VOXEL_PACKET_SIZE]; @@ -69,10 +70,25 @@ bool VoxelNodeData::updateCurrentViewFrustum() { _currentViewFrustum.calculate(); currentViewFrustumChanged = true; } + + // When we first detect that the view stopped changing, we record this. + // but we don't change it back to false until we've completely sent this + // scene. + if (_viewFrustumChanging && !currentViewFrustumChanged) { + _viewFrustumJustStoppedChanging = true; + } _viewFrustumChanging = currentViewFrustumChanged; return currentViewFrustumChanged; } +void VoxelNodeData::setViewSent(bool viewSent) { + _viewSent = viewSent; + if (viewSent) { + _viewFrustumJustStoppedChanging = false; + } +} + + void VoxelNodeData::updateLastKnownViewFrustum() { bool frustumChanges = !_lastKnownViewFrustum.matches(_currentViewFrustum); diff --git a/voxel-server/src/VoxelNodeData.h b/voxel-server/src/VoxelNodeData.h index 0f96a07c3d..96b61db963 100644 --- a/voxel-server/src/VoxelNodeData.h +++ b/voxel-server/src/VoxelNodeData.h @@ -48,7 +48,11 @@ public: void updateLastKnownViewFrustum(); bool getViewSent() const { return _viewSent; }; - void setViewSent(bool viewSent) { _viewSent = viewSent; } + void setViewSent(bool viewSent); + + bool getViewFrustumChanging() const { return _viewFrustumChanging; }; + bool getViewFrustumJustStoppedChanging() const { return _viewFrustumJustStoppedChanging; }; + uint64_t getLastTimeBagEmpty() const { return _lastTimeBagEmpty; }; void setLastTimeBagEmpty(uint64_t lastTimeBagEmpty) { _lastTimeBagEmpty = lastTimeBagEmpty; }; @@ -69,6 +73,7 @@ private: ViewFrustum _lastKnownViewFrustum; uint64_t _lastTimeBagEmpty; bool _viewFrustumChanging; + bool _viewFrustumJustStoppedChanging; bool _currentPacketIsColor; }; diff --git a/voxel-server/src/main.cpp b/voxel-server/src/main.cpp index f171d9b168..5b1ad57861 100644 --- a/voxel-server/src/main.cpp +++ b/voxel-server/src/main.cpp @@ -205,6 +205,7 @@ void deepestLevelVoxelDistributor(NodeList* nodeList, } } + // This is the start of "resending" the scene. nodeData->nodeBag.insert(serverTree.rootNode); } @@ -242,15 +243,12 @@ void deepestLevelVoxelDistributor(NodeList* nodeList, EncodeBitstreamParams params(INT_MAX, &nodeData->getCurrentViewFrustum(), wantColor, WANT_EXISTS_BITS, DONT_CHOP, wantDelta, lastViewFrustum, wantOcclusionCulling, coverageMap, boundaryLevelAdjust, - nodeData->getLastTimeBagEmpty()); - + nodeData->getLastTimeBagEmpty(), + nodeData->getViewFrustumJustStoppedChanging()); + bytesWritten = serverTree.encodeTreeBitstream(subTree, &tempOutputBuffer[0], MAX_VOXEL_PACKET_SIZE - 1, nodeData->nodeBag, params); - if (::debugVoxelSending && wantDelta) { - printf("encodeTreeBitstream() childWasInViewDiscarded=%ld\n", params.childWasInViewDiscarded); - } - if (nodeData->getAvailable() >= bytesWritten) { nodeData->writeToPacket(&tempOutputBuffer[0], bytesWritten); } else { From 4272f4da5721487e1c9863bd6e1edf62555706b2 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 17 Jul 2013 14:57:29 -0700 Subject: [PATCH 2/3] Tiny sliding with gravity removed --- interface/src/Avatar.cpp | 15 ++++++++------- interface/src/Avatar.h | 5 ++++- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index e92394af22..950108a65d 100755 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -98,6 +98,7 @@ Avatar::Avatar(Node* owningNode) : _elapsedTimeMoving(0.0f), _elapsedTimeStopped(0.0f), _elapsedTimeSinceCollision(0.0f), + _lastCollisionPosition(0, 0, 0), _speedBrakes(false), _isThrustOn(false), _voxels(this) @@ -541,11 +542,12 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { // For gravity, always move the avatar by the amount driven by gravity, so that the collision // routines will detect it and collide every frame when pulled by gravity to a surface // - - _velocity += _scale * _gravity * (GRAVITY_EARTH * deltaTime); - _position += _scale * _gravity * (GRAVITY_EARTH * deltaTime) * deltaTime; + const float MIN_DISTANCE_AFTER_COLLISION_FOR_GRAVITY = 0.01f; + if (glm::length(_position - _lastCollisionPosition) > MIN_DISTANCE_AFTER_COLLISION_FOR_GRAVITY) { + _velocity += _scale * _gravity * (GRAVITY_EARTH * deltaTime); + _position += _scale * _gravity * (GRAVITY_EARTH * deltaTime) * deltaTime; + } } - updateCollisionWithEnvironment(deltaTime); updateCollisionWithVoxels(deltaTime); updateAvatarCollisions(deltaTime); @@ -890,11 +892,9 @@ void Avatar::updateCollisionWithEnvironment(float deltaTime) { if (velocityTowardCollision > VISIBLE_GROUND_COLLISION_VELOCITY) { Application::getInstance()->setGroundPlaneImpact(1.0f); } + _lastCollisionPosition = _position; updateCollisionSound(penetration, deltaTime, ENVIRONMENT_COLLISION_FREQUENCY); - applyHardCollision(penetration, ENVIRONMENT_SURFACE_ELASTICITY, ENVIRONMENT_SURFACE_DAMPING); - - } } @@ -908,6 +908,7 @@ void Avatar::updateCollisionWithVoxels(float deltaTime) { if (Application::getInstance()->getVoxels()->findCapsulePenetration( _position - glm::vec3(0.0f, _pelvisFloatingHeight - radius, 0.0f), _position + glm::vec3(0.0f, _height - _pelvisFloatingHeight - radius, 0.0f), radius, penetration)) { + _lastCollisionPosition = _position; updateCollisionSound(penetration, deltaTime, VOXEL_COLLISION_FREQUENCY); applyHardCollision(penetration, VOXEL_ELASTICITY, VOXEL_DAMPING); } diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 61207a2d8b..75e0ab2f9b 100755 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -118,7 +118,8 @@ public: const glm::vec3& amplifyAngle, float yawFromTouch, float pitchFromTouch); - void addBodyYaw(float y) {_bodyYaw += y;}; + void addBodyYaw(float bodyYaw) {_bodyYaw += bodyYaw;}; + void addBodyYawDelta(float bodyYawDelta) {_bodyYawDelta += bodyYawDelta;} void render(bool lookingInMirror, bool renderAvatarBalls); //setters @@ -155,6 +156,7 @@ public: float getElapsedTimeStopped () const { return _elapsedTimeStopped;} float getElapsedTimeMoving () const { return _elapsedTimeMoving;} float getElapsedTimeSinceCollision() const { return _elapsedTimeSinceCollision;} + const glm::vec3& getLastCollisionPosition () const { return _lastCollisionPosition;} float getAbsoluteHeadYaw () const; float getAbsoluteHeadPitch () const; Head& getHead () {return _head; } @@ -245,6 +247,7 @@ private: float _elapsedTimeMoving; // Timers to drive camera transitions when moving float _elapsedTimeStopped; float _elapsedTimeSinceCollision; + glm::vec3 _lastCollisionPosition; bool _speedBrakes; bool _isThrustOn; From 52d8ece38abdd30f3a3f40ee1f5547d512f90b5e Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 17 Jul 2013 15:03:56 -0700 Subject: [PATCH 3/3] remove old pre-movement of avatar in gravity --- interface/src/Avatar.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index 950108a65d..c723bb3b8d 100755 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -542,10 +542,9 @@ void Avatar::simulate(float deltaTime, Transmitter* transmitter) { // For gravity, always move the avatar by the amount driven by gravity, so that the collision // routines will detect it and collide every frame when pulled by gravity to a surface // - const float MIN_DISTANCE_AFTER_COLLISION_FOR_GRAVITY = 0.01f; + const float MIN_DISTANCE_AFTER_COLLISION_FOR_GRAVITY = 0.02f; if (glm::length(_position - _lastCollisionPosition) > MIN_DISTANCE_AFTER_COLLISION_FOR_GRAVITY) { _velocity += _scale * _gravity * (GRAVITY_EARTH * deltaTime); - _position += _scale * _gravity * (GRAVITY_EARTH * deltaTime) * deltaTime; } } updateCollisionWithEnvironment(deltaTime);