summaryrefslogtreecommitdiff
path: root/indra/newview/llagentcamera.cpp
diff options
context:
space:
mode:
authorleviathan <leviathan@lindenlab.com>2026-05-07 22:52:05 -0700
committerleviathan <leviathan@lindenlab.com>2026-10-16 13:14:36 -0700
commit5f9fc17e90f3d5a219c52dc3cecf449275174ffc (patch)
tree7ae3505efd8b1010a56d9ff921ed1d84122b69cd /indra/newview/llagentcamera.cpp
parentfa75a7bd0f909c8b19d6217c5c15b4431d439c8b (diff)
overhaul game-control config and UI
Diffstat (limited to 'indra/newview/llagentcamera.cpp')
-rw-r--r--indra/newview/llagentcamera.cpp101
1 files changed, 93 insertions, 8 deletions
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 0fe5f622e3..ef269be0be 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -185,7 +185,9 @@ LLAgentCamera::LLAgentCamera() :
mPanLeftKey(0.f),
mPanRightKey(0.f),
mPanInKey(0.f),
- mPanOutKey(0.f)
+ mPanOutKey(0.f),
+ mRollLeftKey(0.f),
+ mRollRightKey(0.f)
{
mFollowCam.setMaxCameraDistantFromSubject( MAX_CAMERA_DISTANCE_FROM_AGENT );
@@ -195,6 +197,7 @@ LLAgentCamera::LLAgentCamera() :
resetPanDiff();
resetOrbitDiff();
+ resetCameraRoll();
}
// Requires gSavedSettings to be initialized.
@@ -331,7 +334,8 @@ void LLAgentCamera::resetView(bool reset_camera, bool change_camera)
//Camera Tool is needed for Free Camera Control Mode
if (!LLFloaterCamera::inFreeCameraMode())
{
- LLFloaterReg::hideInstance("build");
+ if (LLFloaterReg::instanceVisible("build"))
+ LLFloaterReg::hideInstance("build");
// Switch back to basic toolset
LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
@@ -355,6 +359,8 @@ void LLAgentCamera::resetView(bool reset_camera, bool change_camera)
setFocusOnAvatar(true, ANIMATE);
mCameraFOVZoomFactor = 0.f;
+
+ resetCameraRoll();
}
resetPanDiff();
resetOrbitDiff();
@@ -905,6 +911,19 @@ void LLAgentCamera::cameraOrbitOver(const F32 angle)
}
}
+//-----------------------------------------------------------------------------
+// cameraRollOver()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::cameraRollOver(const F32 angle)
+{
+ mRollAngle += fmod(angle, F_TWO_PI);
+}
+
+void LLAgentCamera::resetCameraRoll()
+{
+ mRollAngle = 0.f;
+}
+
void LLAgentCamera::resetCameraOrbit()
{
LLVector3 camera_offset_unit(mCameraFocusOffsetTarget);
@@ -918,6 +937,7 @@ void LLAgentCamera::resetCameraOrbit()
cameraZoomIn(1.f);
resetOrbitDiff();
+ resetCameraRoll();
}
void LLAgentCamera::resetOrbitDiff()
@@ -1282,6 +1302,7 @@ void LLAgentCamera::updateCamera()
const F32 ORBIT_OVER_RATE = 90.f * DEG_TO_RAD; // radians per second
const F32 ORBIT_AROUND_RATE = 90.f * DEG_TO_RAD; // radians per second
const F32 PAN_RATE = 5.f; // meters per second
+ const F32 ROLL_RATE = 45.f * DEG_TO_RAD; // radians per second
if (gAgentCamera.getOrbitUpKey() || gAgentCamera.getOrbitDownKey())
{
@@ -1323,6 +1344,12 @@ void LLAgentCamera::updateCamera()
cameraPanUp(input_rate * PAN_RATE / gFPSClamped );
}
+ if (getRollLeftKey() || getRollRightKey())
+ {
+ F32 input_rate = getRollRightKey() - getRollLeftKey();
+ cameraRollOver(input_rate * ROLL_RATE / gFPSClamped);
+ }
+
// Clear camera keyboard keys.
gAgentCamera.clearOrbitKeys();
gAgentCamera.clearPanKeys();
@@ -1552,6 +1579,7 @@ void LLAgentCamera::updateCamera()
LLVector3 chest_scale = chest_joint->getScale();
// shorten avatar skeleton to avoid foot interpenetration
+#if 0 // This screws up mouselook attachments
if (!gAgentAvatarp->mInAir)
{
LLVector3 chest_offset = LLVector3(0.f, 0.f, chest_joint->getPosition().mV[VZ]) * torso_joint->getWorldRotation();
@@ -1565,9 +1593,37 @@ void LLAgentCamera::updateCamera()
chest_joint->setScale(LLVector3(1.f, 1.f, scale_factor));
diff.mV[VZ] = 0.f;
}
+#endif
+ static LLCachedControl<bool> useRealisticMouselook(gSavedSettings, "AlchemyRealisticMouselook", false);
+ if (useRealisticMouselook)
+ {
+ auto frame_agent = gAgent.getFrameAgent();
+ LLQuaternion agent_rot(frame_agent.getQuaternion());
+ auto avatarp_parent = (LLViewerObject*)gAgentAvatarp->getParent();
+ if(avatarp_parent)
+ {
+ auto avatarp_root = (LLViewerObject*)gAgentAvatarp->getRoot();
+ if(avatarp_root)
+ {
+ auto decoupled = avatarp_root->flagCameraDecoupled();
+ if(decoupled)
+ {
+ agent_rot *= avatarp_parent->getRenderRotation();
+ }
- // SL-315
- gAgentAvatarp->mPelvisp->setPosition(gAgentAvatarp->mPelvisp->getPosition() + diff);
+ }
+ }
+
+ LLViewerCamera::getInstance()->updateCameraLocation(head_pos,
+ mCameraUpVector,
+ gAgentAvatarp->mHeadp->getWorldPosition() +
+ LLVector3(1.0, 0.0, 0.0) * agent_rot);
+ }
+ else
+ {
+ // SL-315
+ gAgentAvatarp->mPelvisp->setPosition(gAgentAvatarp->mPelvisp->getPosition() + diff);
+ }
gAgentAvatarp->mRoot->updateWorldMatrixChildren();
@@ -1594,6 +1650,18 @@ void LLAgentCamera::updateCamera()
torso_joint->setScale(torso_scale);
chest_joint->setScale(chest_scale);
}
+
+ // We have do this at the very end to make sure it takes all previous calculations into
+ // account and then applies our roll on top of it, besides it wouldn't even work otherwise.
+ LLQuaternion rot_quat = LLViewerCamera::instance().getQuaternion();
+ LLMatrix3 rot_mat(mRollAngle, 0.f, 0.f);
+ rot_quat = LLQuaternion(rot_mat)*rot_quat;
+
+ LLMatrix3 mat(rot_quat);
+
+ LLViewerCamera::instance().mXAxis = LLVector3(mat.mMatrix[0]);
+ LLViewerCamera::instance().mYAxis = LLVector3(mat.mMatrix[1]);
+ LLViewerCamera::instance().mZAxis = LLVector3(mat.mMatrix[2]);
}
void LLAgentCamera::updateLastCamera()
@@ -1697,7 +1765,6 @@ LLVector3d LLAgentCamera::calcFocusPositionTargetGlobal()
LLVector3d LLAgentCamera::calcThirdPersonFocusOffset()
{
// ...offset from avatar
- LLVector3d focus_offset;
LLQuaternion agent_rot = gAgent.getFrameAgent().getQuaternion();
if (isAgentAvatarValid() && gAgentAvatarp->getParent())
{
@@ -2124,6 +2191,22 @@ void LLAgentCamera::handleScrollWheel(S32 clicks)
}
else if (mFocusOnAvatar && (mCameraMode == CAMERA_MODE_THIRD_PERSON))
{
+ MASK mask = gKeyboard->currentMask(true);
+ if (mask & MASK_SHIFT)
+ {
+ LLVector3d offset = gSavedSettings.getVector3d("FocusOffsetRearView");
+ offset.mdV[VZ] += 0.1f * (F32)clicks;
+ gSavedSettings.setVector3d("FocusOffsetRearView", offset);
+ return;
+ }
+ else if (mask & MASK_CONTROL)
+ {
+ LLVector3 offset = gSavedSettings.getVector3("CameraOffsetRearView");
+ offset.mV[VZ] += 0.1f * (F32)clicks;
+ gSavedSettings.setVector3("CameraOffsetRearView", offset);
+ return;
+ }
+
F32 camera_offset_initial_mag = getCameraOffsetInitial().magVec();
F32 current_zoom_fraction = mTargetCameraDistance / (camera_offset_initial_mag * gSavedSettings.getF32("CameraOffsetScale"));
@@ -2216,7 +2299,6 @@ void LLAgentCamera::changeCameraToMouselook(bool animate)
updateLastCamera();
mCameraMode = CAMERA_MODE_MOUSELOOK;
- const U32 old_flags = gAgent.getControlFlags();
gAgent.setControlFlags(AGENT_CONTROL_MOUSELOOK);
if (animate)
@@ -2471,6 +2553,7 @@ void LLAgentCamera::switchCameraPreset(ECameraPreset preset)
resetPanDiff();
resetOrbitDiff();
+ resetCameraRoll();
gSavedSettings.setU32("CameraPresetType", mCameraPreset);
}
@@ -2675,9 +2758,9 @@ void LLAgentCamera::setCameraPosAndFocusGlobal(const LLVector3d& camera_pos, con
if (mCameraAnimating)
{
- const F64 ANIM_METERS_PER_SECOND = 10.0;
+ const F64 ANIM_METERS_PER_SECOND = 25.0;
const F64 MIN_ANIM_SECONDS = 0.5;
- const F64 MAX_ANIM_SECONDS = 10.0;
+ const F64 MAX_ANIM_SECONDS = 1.0;
F64 anim_duration = llmax( MIN_ANIM_SECONDS, sqrt(focus_delta_squared) / ANIM_METERS_PER_SECOND );
anim_duration = llmin( anim_duration, MAX_ANIM_SECONDS );
setAnimationDuration( (F32)anim_duration );
@@ -2950,6 +3033,8 @@ void LLAgentCamera::clearOrbitKeys()
mOrbitDownKey = 0.f;
mOrbitInKey = 0.f;
mOrbitOutKey = 0.f;
+ mRollLeftKey = 0.f;
+ mRollRightKey = 0.f;
}
void LLAgentCamera::clearPanKeys()