diff options
author | leviathan <leviathan@lindenlab.com> | 2024-09-13 10:47:24 -0700 |
---|---|---|
committer | leviathan <leviathan@lindenlab.com> | 2024-09-13 10:47:24 -0700 |
commit | da87e8bd370ea079576f8b412a4ddb80c0715bd1 (patch) | |
tree | bdc9e145b111a4e73c773c667315ea14bd1ca5f0 | |
parent | 74205607b7e106f3b7566ef4a4b9c2fcdfa2f83e (diff) |
send AgentUpdate ASAP when control bits change
-rw-r--r-- | indra/newview/llagent.cpp | 54 | ||||
-rw-r--r-- | indra/newview/llagent.h | 4 | ||||
-rw-r--r-- | indra/newview/llagentcamera.cpp | 4 | ||||
-rw-r--r-- | indra/newview/llappviewer.cpp | 38 | ||||
-rw-r--r-- | indra/newview/llappviewer.h | 6 | ||||
-rw-r--r-- | indra/newview/llviewermessage.cpp | 333 |
6 files changed, 171 insertions, 268 deletions
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 7c37cc1c00..c8b0adbaf8 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -439,8 +439,6 @@ LLAgent::LLAgent() : mIsDoNotDisturb(false), mControlFlags(0x00000000), - mbFlagsDirty(false), - mbFlagsNeedReset(false), mAutoPilot(false), mAutoPilotFlyOnStop(false), @@ -936,8 +934,6 @@ void LLAgent::setFlying(bool fly, bool fail_sound) // Update Movement Controls according to Fly mode LLFloaterMove::setFlyingMode(fly); - - mbFlagsDirty = true; } @@ -1068,7 +1064,6 @@ void LLAgent::setRegion(LLViewerRegion *regionp) { regionp->setCapabilitiesReceivedCallback(LLAgent::capabilityReceivedCallback); } - } else { @@ -1556,7 +1551,6 @@ U32 LLAgent::getControlFlags() void LLAgent::setControlFlags(U32 mask) { mControlFlags |= mask; - mbFlagsDirty = true; } @@ -1565,28 +1559,7 @@ void LLAgent::setControlFlags(U32 mask) //----------------------------------------------------------------------------- void LLAgent::clearControlFlags(U32 mask) { - U32 old_flags = mControlFlags; mControlFlags &= ~mask; - if (old_flags != mControlFlags) - { - mbFlagsDirty = true; - } -} - -//----------------------------------------------------------------------------- -// controlFlagsDirty() -//----------------------------------------------------------------------------- -bool LLAgent::controlFlagsDirty() const -{ - return mbFlagsDirty; -} - -//----------------------------------------------------------------------------- -// enableControlFlagReset() -//----------------------------------------------------------------------------- -void LLAgent::enableControlFlagReset() -{ - mbFlagsNeedReset = true; } //----------------------------------------------------------------------------- @@ -1594,14 +1567,9 @@ void LLAgent::enableControlFlagReset() //----------------------------------------------------------------------------- void LLAgent::resetControlFlags() { - if (mbFlagsNeedReset) - { - mbFlagsNeedReset = false; - mbFlagsDirty = false; - // reset all of the ephemeral flags - // some flags are managed elsewhere - mControlFlags &= AGENT_CONTROL_AWAY | AGENT_CONTROL_FLY | AGENT_CONTROL_MOUSELOOK; - } + // reset all of the ephemeral flags + // some flags are managed elsewhere + mControlFlags &= AGENT_CONTROL_AWAY | AGENT_CONTROL_FLY | AGENT_CONTROL_MOUSELOOK; } //----------------------------------------------------------------------------- @@ -2085,11 +2053,19 @@ void LLAgent::propagate(const F32 dt) } // handle rotation based on keyboard levels - const F32 YAW_RATE = 90.f * DEG_TO_RAD; // radians per second - yaw(YAW_RATE * gAgentCamera.getYawKey() * dt); + constexpr F32 YAW_RATE = 90.f * DEG_TO_RAD; // radians per second + F32 angle = YAW_RATE * gAgentCamera.getYawKey() * dt; + if (fabs(angle) > 0.0f) + { + yaw(angle); + } - const F32 PITCH_RATE = 90.f * DEG_TO_RAD; // radians per second - pitch(PITCH_RATE * gAgentCamera.getPitchKey() * dt); + constexpr F32 PITCH_RATE = 90.f * DEG_TO_RAD; // radians per second + angle = PITCH_RATE * gAgentCamera.getPitchKey() * dt; + if (fabs(angle) > 0.0f) + { + pitch(angle); + } // handle auto-land behavior if (isAgentAvatarValid()) diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 7c7f7aa91d..afc34f747f 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -482,21 +482,17 @@ public: void setControlFlags(U32 mask); // Performs bitwise mControlFlags |= mask void clearControlFlags(U32 mask); // Performs bitwise mControlFlags &= ~mask bool controlFlagsDirty() const; - void enableControlFlagReset(); void resetControlFlags(); bool anyControlGrabbed() const; // True iff a script has taken over a control bool isControlGrabbed(S32 control_index) const; // Send message to simulator to force grabbed controls to be // released, in case of a poorly written script. void forceReleaseControls(); - void setFlagsDirty() { mbFlagsDirty = true; } private: S32 mControlsTakenCount[TOTAL_CONTROLS]; S32 mControlsTakenPassedOnCount[TOTAL_CONTROLS]; U32 mControlFlags; // Replacement for the mFooKey's - bool mbFlagsDirty; - bool mbFlagsNeedReset; // ! HACK ! For preventing incorrect flags sent when crossing region boundaries //-------------------------------------------------------------------- // Animations diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index e7531f963b..81e79a2ed9 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -2204,10 +2204,6 @@ void LLAgentCamera::changeCameraToMouselook(bool animate) mCameraMode = CAMERA_MODE_MOUSELOOK; const U32 old_flags = gAgent.getControlFlags(); gAgent.setControlFlags(AGENT_CONTROL_MOUSELOOK); - if (old_flags != gAgent.getControlFlags()) - { - gAgent.setFlagsDirty(); - } if (animate) { diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 4eb4f5ae20..764e52accb 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -642,8 +642,6 @@ LLAppViewer::LLAppViewer() mQuitRequested(false), mClosingFloaters(false), mLogoutRequestSent(false), - mLastAgentControlFlags(0), - mLastAgentForceUpdate(0), mMainloopTimeout(NULL), mAgentRegionLastAlive(false), mRandomizeFramerate(LLCachedControl<bool>(gSavedSettings,"Randomize Framerate", false)), @@ -4711,30 +4709,13 @@ void LLAppViewer::idle() gAgent.autoPilot(&yaw); } - static LLFrameTimer agent_update_timer; - - // When appropriate, update agent location to the simulator. - F32 agent_update_time = agent_update_timer.getElapsedTimeF32(); - F32 agent_force_update_time = mLastAgentForceUpdate + agent_update_time; - bool timed_out = agent_update_time > (1.0f / (F32)AGENT_UPDATES_PER_SECOND); - bool force_send = - // if there is something to send - (gAgent.controlFlagsDirty() && timed_out) - // if something changed - || (mLastAgentControlFlags != gAgent.getControlFlags()) - // keep alive - || (agent_force_update_time > (1.0f / (F32) AGENT_FORCE_UPDATES_PER_SECOND)); - // timing out doesn't warranty that an update will be sent, - // just that it will be checked. - if (force_send || timed_out) - { - LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; - // Send avatar and camera info - mLastAgentControlFlags = gAgent.getControlFlags(); - mLastAgentForceUpdate = force_send ? 0 : agent_force_update_time; - send_agent_update(force_send); - agent_update_timer.reset(); - } + send_agent_update(false); + + // After calling send_agent_update() in the mainloop we always clear + // the agent's ephemeral ControlFlags (whether an AgentUpdate was + // actually sent or not) because these will be recomputed based on + // real-time key/controller input and resubmitted next frame. + gAgent.resetControlFlags(); } ////////////////////////////////////// @@ -5346,11 +5327,6 @@ void LLAppViewer::idleNetwork() } #endif - - - // we want to clear the control after sending out all necessary agent updates - gAgent.resetControlFlags(); - // Decode enqueued messages... S32 remaining_possible_decodes = MESSAGE_MAX_PER_FRAME - total_decoded; diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index 7b456cc542..4ce4259ed8 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -322,8 +322,6 @@ private: bool mQuitRequested; // User wants to quit, may have modified documents open. bool mClosingFloaters; bool mLogoutRequestSent; // Disconnect message sent to simulator, no longer safe to send messages to the sim. - U32 mLastAgentControlFlags; - F32 mLastAgentForceUpdate; struct SettingsFiles* mSettingsLocationList; LLWatchdogTimeout* mMainloopTimeout; @@ -341,10 +339,6 @@ private: bool mIsFirstRun; }; -// consts from viewer.h -const S32 AGENT_UPDATES_PER_SECOND = 125; // Value derived experimentally to avoid Input Delays with latest PBR-Capable Viewers when viewer FPS is highly volatile. -const S32 AGENT_FORCE_UPDATES_PER_SECOND = 1; - // Globals with external linkage. From viewer.h // *NOTE:Mani - These will be removed as the Viewer App Cleanup project continues. // diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 872a9a1581..0861b439eb 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3139,14 +3139,9 @@ void process_crossed_region(LLMessageSystem* msg, void**) } - -// Sends avatar and camera information to simulator. -// Sent roughly once per frame, or 20 times per second, whichever is less often - -const F32 THRESHOLD_HEAD_ROT_QDOT = 0.9997f; // ~= 2.5 degrees -- if its less than this we need to update head_rot -const F32 MAX_HEAD_ROT_QDOT = 0.99999f; // ~= 0.5 degrees -- if its greater than this then no need to update head_rot - // between these values we delay the updates (but no more than one second) - +// sends an AgentUpdate message to the server... or not: +// only when force_send is 'true' OR +// something changed AND the update is not being throttled void send_agent_update(bool force_send, bool send_reliable) { LL_PROFILE_ZONE_SCOPED; @@ -3154,72 +3149,46 @@ void send_agent_update(bool force_send, bool send_reliable) if (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE) { - // We don't care if they want to send an agent update, they're not allowed to until the simulator - // that's the target is ready to receive them (after avatar_init_complete is received) + // We don't care if they want to send an agent update, they're not allowed + // until the target simulator is ready to receive them + // (e.g. after avatar_init_complete is received) return; } - // We have already requested to log out. Don't send agent updates. - if(LLAppViewer::instance()->logoutRequestSent()) + if (LLAppViewer::instance()->logoutRequestSent()) { + // We have already requested to log out. Don't send agent updates. return; } - // no region to send update to - if(gAgent.getRegion() == NULL) + if (gAgent.getRegion() == nullptr || gDisconnected) { + // no region to send update to return; } - const F32 TRANSLATE_THRESHOLD = 0.01f; - - // NOTA BENE: This is (intentionally?) using the small angle sine approximation to test for rotation - // Plus, there is an extra 0.5 in the mix since the perpendicular between last_camera_at and getAtAxis() bisects cam_rot_change - // Thus, we're actually testing against 0.2 degrees - const F32 ROTATION_THRESHOLD = 0.1f * 2.f*F_PI/360.f; // Rotation thresh 0.2 deg, see note above - - const U8 DUP_MSGS = 1; // HACK! number of times to repeat data on motionless agent - - // Store data on last sent update so that if no changes, no send - static LLVector3 last_camera_pos_agent, - last_camera_at, - last_camera_left, - last_camera_up; - - static LLVector3 cam_center_chg, - cam_rot_chg; - - static LLQuaternion last_head_rot; - static U32 last_control_flags = 0; - static U8 last_render_state; - static U8 duplicate_count = 0; - static F32 head_rot_chg = 1.0; - static U8 last_flags; - - LLMessageSystem *msg = gMessageSystem; - LLVector3 camera_pos_agent; // local to avatar's region - U8 render_state; - - LLQuaternion body_rotation = gAgent.getFrameAgent().getQuaternion(); - LLQuaternion head_rotation = gAgent.getHeadRotation(); - - camera_pos_agent = gAgentCamera.getCameraPositionAgent(); + static F64 last_send_time = 0.0; + static U32 last_control_flags = 0; + static U8 last_render_state = 0; + static U8 last_flags = AU_FLAGS_NONE; + static LLQuaternion last_body_rot, + last_head_rot; + static LLVector3 last_camera_pos_agent, + last_camera_at; - render_state = gAgent.getRenderState(); - - U32 control_flag_change = 0; - U8 flag_change = 0; - - cam_center_chg = last_camera_pos_agent - camera_pos_agent; - cam_rot_chg = last_camera_at - LLViewerCamera::getInstance()->getAtAxis(); + // compute sec_since_last_send + constexpr F64 MAX_AGENT_UPDATES_PER_SECOND = 125.0; // Value derived experimentally to avoid Input Delays with latest PBR-Capable Viewers when viewer FPS is highly volatile. + constexpr F64 MIN_AGENT_UPDATES_PER_SECOND = 1.0; // keep-alive rate + constexpr F64 MIN_AGENT_UPDATE_PERIOD = 1.0 / MAX_AGENT_UPDATES_PER_SECOND; + constexpr F64 MAX_AGENT_UPDATE_PERIOD = 1.0 / MIN_AGENT_UPDATES_PER_SECOND; + F64 now = LLFrameTimer::getTotalSeconds(); + F64 sec_since_last_send = now - last_send_time; // If a modifier key is held down, turn off // LBUTTON and ML_LBUTTON so that using the camera (alt-key) doesn't // trigger a control event. U32 control_flags = gAgent.getControlFlags(); - - MASK key_mask = gKeyboard->currentMask(true); - + MASK key_mask = gKeyboard->currentMask(true); if (key_mask & MASK_ALT || key_mask & MASK_CONTROL) { control_flags &= ~( AGENT_CONTROL_LBUTTON_DOWN | @@ -3228,7 +3197,22 @@ void send_agent_update(bool force_send, bool send_reliable) AGENT_CONTROL_ML_LBUTTON_UP ; } - control_flag_change = last_control_flags ^ control_flags; + // any change in control_flags should be sent ASAP, so we fold that into force_send + force_send = force_send || (control_flags != last_control_flags); + + if (! force_send && sec_since_last_send < MIN_AGENT_UPDATE_PERIOD) + { + // throttle less-important AgentUpdates + return; + } + + bool send_update = force_send || sec_since_last_send > MAX_AGENT_UPDATE_PERIOD; + + LLVector3 camera_pos_agent = gAgentCamera.getCameraPositionAgent(); // local to avatar's region + LLVector3 camera_at = LLViewerCamera::getInstance()->getAtAxis(); + LLQuaternion body_rotation = gAgent.getFrameAgent().getQuaternion(); + LLQuaternion head_rotation = gAgent.getHeadRotation(); + U8 render_state = gAgent.getRenderState(); U8 flags = AU_FLAGS_NONE; if (gAgent.isGroupTitleHidden()) @@ -3240,159 +3224,140 @@ void send_agent_update(bool force_send, bool send_reliable) flags |= AU_FLAGS_CLIENT_AUTOPILOT; } - flag_change = last_flags ^ flags; - - head_rot_chg = dot(last_head_rot, head_rotation); - - //static S32 msg_number = 0; // Used for diagnostic log messages - - if (force_send || - (cam_center_chg.magVec() > TRANSLATE_THRESHOLD) || - (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT) || - (last_render_state != render_state) || - (cam_rot_chg.magVec() > ROTATION_THRESHOLD) || - control_flag_change != 0 || - flag_change != 0) + if (!send_update) { - /* Diagnotics to show why we send the AgentUpdate message. Also un-commment the msg_number code above and below this block - msg_number += 1; - if (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT) - { - //LL_INFOS("Messaging") << "head rot " << head_rotation << LL_ENDL; - LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", head_rot_chg " << head_rot_chg << LL_ENDL; - } - if (cam_rot_chg.magVec() > ROTATION_THRESHOLD) - { - LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", cam rot " << cam_rot_chg.magVec() << LL_ENDL; - } - if (cam_center_chg.magVec() > TRANSLATE_THRESHOLD) - { - LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", cam center " << cam_center_chg.magVec() << LL_ENDL; - } -// if (drag_delta_chg.magVec() > TRANSLATE_THRESHOLD) -// { -// LL_INFOS("Messaging") << "drag delta " << drag_delta_chg.magVec() << LL_ENDL; -// } - if (control_flag_change) + // check to see if anything changed + // use a do-while-false to provide easy way to break out as soon as we find something changed + do { - LL_INFOS("Messaging") << "msg " << msg_number << ", frame " << LLFrameTimer::getFrameCount() << ", dcf = " << control_flag_change << LL_ENDL; - } -*/ - - duplicate_count = 0; - } - else - { - duplicate_count++; + // start with the easy evaluations and progress to more complicated - if (head_rot_chg < MAX_HEAD_ROT_QDOT && duplicate_count < AGENT_UPDATES_PER_SECOND) - { - // The head_rotation is sent for updating things like attached guns. - // We only trigger a new update when head_rotation deviates beyond - // some threshold from the last update, however this can break fine - // adjustments when trying to aim an attached gun, so what we do here - // (where we would normally skip sending an update when nothing has changed) - // is gradually reduce the threshold to allow a better update to - // eventually get sent... should update to within 0.5 degrees in less - // than a second. - if (head_rot_chg < THRESHOLD_HEAD_ROT_QDOT + (MAX_HEAD_ROT_QDOT - THRESHOLD_HEAD_ROT_QDOT) * duplicate_count / AGENT_UPDATES_PER_SECOND) + // check render_state + if (last_render_state != render_state) { - duplicate_count = 0; + send_update = true; + break; } - else + + // check flags + if (last_flags != flags) { - return; + send_update = true; + break; } - } - else - { - return; - } - } - if (duplicate_count < DUP_MSGS && !gDisconnected) - { - /* More diagnostics to count AgentUpdate messages - static S32 update_sec = 0; - static S32 update_count = 0; - static S32 max_update_count = 0; - S32 cur_sec = lltrunc( LLTimer::getTotalSeconds() ); - update_count += 1; - if (cur_sec != update_sec) - { - if (update_sec != 0) + // check translation + constexpr F32 TRANSLATE_THRESHOLD = 0.01f; + if ((last_camera_pos_agent - camera_pos_agent).magVec() > TRANSLATE_THRESHOLD) { - update_sec = cur_sec; - //msg_number = 0; - max_update_count = llmax(max_update_count, update_count); - LL_INFOS() << "Sent " << update_count << " AgentUpdate messages per second, max is " << max_update_count << LL_ENDL; + send_update = true; + break; } - update_sec = cur_sec; - update_count = 0; - } - */ - // Build the message - msg->newMessageFast(_PREHASH_AgentUpdate); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - msg->addQuatFast(_PREHASH_BodyRotation, body_rotation); - msg->addQuatFast(_PREHASH_HeadRotation, head_rotation); - msg->addU8Fast(_PREHASH_State, render_state); - msg->addU8Fast(_PREHASH_Flags, flags); - -// if (camera_pos_agent.mV[VY] > 255.f) -// { -// LL_INFOS("Messaging") << "Sending camera center " << camera_pos_agent << LL_ENDL; -// } - - msg->addVector3Fast(_PREHASH_CameraCenter, camera_pos_agent); - msg->addVector3Fast(_PREHASH_CameraAtAxis, LLViewerCamera::getInstance()->getAtAxis()); - msg->addVector3Fast(_PREHASH_CameraLeftAxis, LLViewerCamera::getInstance()->getLeftAxis()); - msg->addVector3Fast(_PREHASH_CameraUpAxis, LLViewerCamera::getInstance()->getUpAxis()); - msg->addF32Fast(_PREHASH_Far, gAgentCamera.mDrawDistance); + // check camera rotation + // Note: we are using the sine small angle approximation trick here + constexpr F32 RADIANS_PER_DEGREE = F_PI / 360.f; + constexpr F32 CAMERA_AT_THRESHOLD = 0.2f * RADIANS_PER_DEGREE; + if ((last_camera_at - camera_at).magVec() > CAMERA_AT_THRESHOLD) + { + send_update = true; + break; + } - msg->addU32Fast(_PREHASH_ControlFlags, control_flags); + // check head rotation + constexpr F64 MIN_HEAD_ROT_QDOT = 0.9997; // ~= 2.5 degrees -- if its less than this we need to update head_rot + constexpr F64 MAX_HEAD_ROT_QDOT = 0.99999; // ~= 0.5 degrees -- if its greater than this then we consider it close enough - if (gDebugClicks) - { - if (control_flags & AGENT_CONTROL_LBUTTON_DOWN) + if (fabs((F64)(dot(last_body_rot, body_rotation))) < MIN_HEAD_ROT_QDOT) { - LL_INFOS("Messaging") << "AgentUpdate left button down" << LL_ENDL; + send_update = true; + break; } - if (control_flags & AGENT_CONTROL_LBUTTON_UP) + F64 head_rot_qdot = fabs((F64)(dot(last_head_rot, head_rotation))); + if (head_rot_qdot > MAX_HEAD_ROT_QDOT) { - LL_INFOS("Messaging") << "AgentUpdate left button up" << LL_ENDL; + // close enough + return; + } + else if (head_rot_qdot < MIN_HEAD_ROT_QDOT) + { + // way off + send_update = true; + break; } - } - gAgent.enableControlFlagReset(); + // Finally, if we get here then head_rot_qdot is somewhere between MIN_ and MAX_HEAD_ROT_QDOT - if (!send_reliable) + // The head_rotation is sent for updating things like attached guns. + // We only trigger a new update when head_rotation deviates beyond + // some threshold from the last update, however this can break fine + // adjustments when trying to aim an attached gun, so what we do here + // (where we would normally skip sending an update when nothing has changed) + // is linearly increase the min threshold until an update is sent. + // Min threshold should update to MAX_HEAD_ROT_QDOT within THRESHOLD_GROWTH_PERIOD. + constexpr F64 THRESHOLD_GROWTH_PERIOD = 0.5; + constexpr F64 threshold_growth_per_sec = (MAX_HEAD_ROT_QDOT - MIN_HEAD_ROT_QDOT) / THRESHOLD_GROWTH_PERIOD; + send_update = head_rot_qdot < MIN_HEAD_ROT_QDOT + sec_since_last_send * threshold_growth_per_sec; + } while (false); + } + + if (!send_update) + { + return; + } + + // Build the message + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_AgentUpdate); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addQuatFast(_PREHASH_BodyRotation, body_rotation); + msg->addQuatFast(_PREHASH_HeadRotation, head_rotation); + msg->addU8Fast(_PREHASH_State, render_state); + msg->addU8Fast(_PREHASH_Flags, flags); + + msg->addVector3Fast(_PREHASH_CameraCenter, camera_pos_agent); + msg->addVector3Fast(_PREHASH_CameraAtAxis, camera_at); + msg->addVector3Fast(_PREHASH_CameraLeftAxis, LLViewerCamera::getInstance()->getLeftAxis()); + msg->addVector3Fast(_PREHASH_CameraUpAxis, LLViewerCamera::getInstance()->getUpAxis()); + msg->addF32Fast(_PREHASH_Far, gAgentCamera.mDrawDistance); + + msg->addU32Fast(_PREHASH_ControlFlags, control_flags); + + if (gDebugClicks) + { + if (control_flags & AGENT_CONTROL_LBUTTON_DOWN) { - gAgent.sendMessage(); + LL_INFOS("Messaging") << "AgentUpdate left button down" << LL_ENDL; } - else + + if (control_flags & AGENT_CONTROL_LBUTTON_UP) { - gAgent.sendReliableMessage(); + LL_INFOS("Messaging") << "AgentUpdate left button up" << LL_ENDL; } + } -// LL_DEBUGS("Messaging") << "agent " << avatar_pos_agent << " cam " << camera_pos_agent << LL_ENDL; - - // Copy the old data - last_head_rot = head_rotation; - last_render_state = render_state; - last_camera_pos_agent = camera_pos_agent; - last_camera_at = LLViewerCamera::getInstance()->getAtAxis(); - last_camera_left = LLViewerCamera::getInstance()->getLeftAxis(); - last_camera_up = LLViewerCamera::getInstance()->getUpAxis(); - last_control_flags = control_flags; - last_flags = flags; + if (send_reliable) + { + gAgent.sendReliableMessage(); + } + else + { + gAgent.sendMessage(); } -} + // remember last update data + last_send_time = now; + last_control_flags = control_flags; + last_render_state = render_state; + last_flags = flags; + last_body_rot = body_rotation; + last_head_rot = head_rotation; + last_camera_pos_agent = camera_pos_agent; + last_camera_at = camera_at; +} // sounds can arrive before objects, store them for a short time // Note: this is a workaround for MAINT-4743, real fix would be to make |