summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llmessage/llpartdata.cpp5
-rw-r--r--indra/newview/app_settings/settings.xml13
-rw-r--r--indra/newview/cube.dae103
-rw-r--r--indra/newview/llappviewer.cpp4
-rw-r--r--indra/newview/llfloaterhoverheight.cpp13
-rw-r--r--indra/newview/llfloaterland.cpp6
-rw-r--r--indra/newview/llfloaterland.h1
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloatermap.cpp148
-rw-r--r--indra/newview/llfloatermap.h1
-rw-r--r--indra/newview/llfloatermodelpreview.cpp26
-rw-r--r--indra/newview/llfloatermodelpreview.h1
-rw-r--r--indra/newview/llfloaterregioninfo.cpp6
-rwxr-xr-x[-rw-r--r--]indra/newview/llfloaterworldmap.cpp87
-rw-r--r--indra/newview/llfloaterworldmap.h7
-rw-r--r--indra/newview/llmodelpreview.cpp23
-rw-r--r--indra/newview/llmodelpreview.h15
-rwxr-xr-x[-rw-r--r--]indra/newview/llnetmap.cpp603
-rw-r--r--indra/newview/llnetmap.h54
-rw-r--r--indra/newview/llviewerparcelmgr.cpp2
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerparceloverlay.cpp64
-rw-r--r--indra/newview/llviewerparceloverlay.h3
-rwxr-xr-x[-rw-r--r--]indra/newview/llviewerregion.cpp9
-rw-r--r--indra/newview/llviewerregion.h2
-rwxr-xr-x[-rw-r--r--]indra/newview/llworldmapview.cpp268
-rw-r--r--indra/newview/llworldmapview.h40
-rw-r--r--indra/newview/skins/default/colors.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_map.xml78
-rw-r--r--indra/newview/skins/default/xui/en/floater_model_preview.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_world_map.xml3
-rw-r--r--indra/newview/skins/default/xui/en/menu_mini_map.xml120
-rw-r--r--indra/newview/skins/default/xui/en/panel_avatar_list_item.xml1
-rwxr-xr-xindra/newview/viewer_manifest.py3
32 files changed, 1168 insertions, 546 deletions
diff --git a/indra/llmessage/llpartdata.cpp b/indra/llmessage/llpartdata.cpp
index 53aa35c0f9..6664eb02dc 100644
--- a/indra/llmessage/llpartdata.cpp
+++ b/indra/llmessage/llpartdata.cpp
@@ -311,8 +311,9 @@ BOOL LLPartSysData::unpack(LLDataPacker &dp)
std::ostream& operator<<(std::ostream& s, const LLPartSysData &data)
{
s << "Flags: " << std::hex << data.mFlags;
- s << " Pattern: " << std::hex << (U32) data.mPattern << "\n";
- s << "Age: [" << data.mStartAge << ", " << data.mMaxAge << "]\n";
+ s << "Pattern: " << std::hex << (U32) data.mPattern << "\n";
+ s << "Source Age: [" << data.mStartAge << ", " << data.mMaxAge << "]\n";
+ s << "Particle Age: " << data.mPartData.mMaxAge << "\n";
s << "Angle: [" << data.mInnerAngle << ", " << data.mOuterAngle << "]\n";
s << "Burst Rate: " << data.mBurstRate << "\n";
s << "Burst Radius: " << data.mBurstRadius << "\n";
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index b3be9d302e..41bccc941e 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -6808,7 +6808,18 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>128.0</real>
+ <real>64.0</real>
+ </map>
+ <key>MiniMapShowPropertyLines</key>
+ <map>
+ <key>Comment</key>
+ <string>Whether or not to show parcel borders on the MiniMap.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <real>1</real>
</map>
<key>MouseSensitivity</key>
<map>
diff --git a/indra/newview/cube.dae b/indra/newview/cube.dae
new file mode 100644
index 0000000000..085b2c7309
--- /dev/null
+++ b/indra/newview/cube.dae
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
+ <asset>
+ <contributor>
+ modified from https://gist.github.com/wtsnz/bfa11c40e04594b260255b5dc7956f26
+ </contributor>
+ <created>2018-10-25T16:29:03Z</created>
+ <modified>2022-02-18T00:00:00Z</modified>
+ <unit meter="1.000000"/>
+ <up_axis>Y_UP</up_axis>
+ </asset>
+
+ <library_materials>
+ <material id="Blue" name="Blue">
+ <instance_effect url="#effect_Blue"/>
+ </material>
+ </library_materials>
+
+
+ <library_effects>
+ <effect id="effect_Blue">
+ <profile_COMMON>
+ <technique sid="common">
+ <phong>
+ <ambient>
+ <color>0 0 0 1</color>
+ </ambient>
+ <diffuse>
+ <color>0.137255 0.403922 0.870588 1</color>
+ </diffuse>
+ <specular>
+ <color>0.5 0.5 0.5 1</color>
+ </specular>
+ <shininess>
+ <float>16</float>
+ </shininess>
+ <transparent opaque="A_ONE">
+ <color>0 0 0 1</color>
+ </transparent>
+ <transparency>
+ <float>1</float>
+ </transparency>
+ <index_of_refraction>
+ <float>1</float>
+ </index_of_refraction>
+ </phong>
+ </technique>
+ </profile_COMMON>
+ </effect>
+ </library_effects>
+
+
+ <library_geometries>
+ <geometry id="F1" name="default_physics_shape">
+ <mesh>
+
+ <source id="cube-vertex-positions">
+ <float_array id="ID2-array" count="72">-0.5 0.5 0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 -0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 -0.5 0.5 -0.5 0.5 -0.5 -0.5 0.5 -0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 </float_array>
+ <technique_common>
+ <accessor source="#ID2-array" count="24" stride="3">
+ <param name="X" type="float"/>
+ <param name="Y" type="float"/>
+ <param name="Z" type="float"/>
+ </accessor>
+ </technique_common>
+ </source>
+
+ <vertices id="cube-vertices">
+ <input semantic="POSITION" source="#cube-vertex-positions"/>
+ </vertices>
+
+ <triangles count="12" material="geometryElement5">
+ <input semantic="VERTEX" offset="0" source="#cube-vertices"/>
+ <p>0 1 2 0 2 3 4 5 6 4 6 7 8 9 10 8 10 11 12 13 14 12 14 15 16 17 18 16 18 19 20 21 22 20 22 23 </p>
+ </triangles>
+
+ </mesh>
+ </geometry>
+ </library_geometries>
+ <library_visual_scenes>
+
+
+ <visual_scene id="reportScene">
+ <!-- No Spaces allowed in Name -->
+ <node id="F1" name="Face1">
+ <instance_geometry url="#F1">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="geometryElement5" target="#Blue"/>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ </node>
+ </visual_scene>
+ </library_visual_scenes>
+
+
+ <scene>
+ <instance_visual_scene url="#reportScene"/>
+ </scene>
+
+
+</COLLADA>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 0c4874ef11..c898dd5179 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -589,7 +589,7 @@ static void settings_to_globals()
gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc");
gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates");
- LLWorldMapView::sMapScale = gSavedSettings.getF32("MapScale");
+ LLWorldMapView::setScaleSetting(gSavedSettings.getF32("MapScale"));
#if LL_DARWIN
gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI");
@@ -3404,7 +3404,7 @@ void LLAppViewer::cleanupSavedSettings()
}
}
- gSavedSettings.setF32("MapScale", LLWorldMapView::sMapScale );
+ gSavedSettings.setF32("MapScale", LLWorldMapView::getScaleSetting());
// Some things are cached in LLAgent.
if (gAgent.isInitialized())
diff --git a/indra/newview/llfloaterhoverheight.cpp b/indra/newview/llfloaterhoverheight.cpp
index 42c5e40761..a00fc4aa84 100644
--- a/indra/newview/llfloaterhoverheight.cpp
+++ b/indra/newview/llfloaterhoverheight.cpp
@@ -100,11 +100,14 @@ void LLFloaterHoverHeight::onClose(bool app_quitting)
// static
void LLFloaterHoverHeight::onSliderMoved(LLUICtrl* ctrl, void* userData)
{
- LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
- F32 value = sldrCtrl->getValueF32();
- LLVector3 offset(0.0, 0.0, llclamp(value,MIN_HOVER_Z,MAX_HOVER_Z));
- LL_INFOS("Avatar") << "setting hover from slider moved" << offset[2] << LL_ENDL;
- gAgentAvatarp->setHoverOffset(offset, false);
+ if (isAgentAvatarValid())
+ {
+ LLSliderCtrl* sldrCtrl = static_cast<LLSliderCtrl*>(ctrl);
+ F32 value = sldrCtrl->getValueF32();
+ LLVector3 offset(0.0, 0.0, llclamp(value, MIN_HOVER_Z, MAX_HOVER_Z));
+ LL_INFOS("Avatar") << "setting hover from slider moved" << offset[2] << LL_ENDL;
+ gAgentAvatarp->setHoverOffset(offset, false);
+ }
}
// Do send-to-the-server work when slider drag completes, or new
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 04133f2710..ff2384e382 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -3054,7 +3054,8 @@ BOOL LLPanelLandCovenant::postBuild()
{
mLastRegionID = LLUUID::null;
mNextUpdateTime = 0;
-
+ mTextEstateOwner = getChild<LLTextBox>("estate_owner_text");
+ mTextEstateOwner->setIsFriendCallback(LLAvatarActions::isFriend);
return TRUE;
}
@@ -3162,8 +3163,7 @@ void LLPanelLandCovenant::updateEstateOwnerName(const std::string& name)
LLPanelLandCovenant* self = LLFloaterLand::getCurrentPanelLandCovenant();
if (self)
{
- LLTextBox* editor = self->getChild<LLTextBox>("estate_owner_text");
- if (editor) editor->setText(name);
+ self->mTextEstateOwner->setText(name);
}
}
diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h
index 5d9b411f04..684950d88b 100644
--- a/indra/newview/llfloaterland.h
+++ b/indra/newview/llfloaterland.h
@@ -413,6 +413,7 @@ protected:
private:
LLUUID mLastRegionID;
F64 mNextUpdateTime; //seconds since client start
+ LLTextBox* mTextEstateOwner;
};
#endif
diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp
index fc2da772f3..fd1af7ccc0 100644..100755
--- a/indra/newview/llfloatermap.cpp
+++ b/indra/newview/llfloatermap.cpp
@@ -51,7 +51,7 @@
// The minor cardinal direction labels are hidden if their height is more
// than this proportion of the map.
-const F32 MAP_MINOR_DIR_THRESHOLD = 0.07f;
+const F32 MAP_MINOR_DIR_THRESHOLD = 0.035f;
//
// Member functions
@@ -77,35 +77,44 @@ LLFloaterMap::~LLFloaterMap()
BOOL LLFloaterMap::postBuild()
{
- mMap = getChild<LLNetMap>("Net Map");
- if (gSavedSettings.getBOOL("DoubleClickTeleport"))
- {
- mMap->setToolTipMsg(getString("AltToolTipMsg"));
- }
- else if (gSavedSettings.getBOOL("DoubleClickShowWorldMap"))
- {
- mMap->setToolTipMsg(getString("ToolTipMsg"));
- }
- sendChildToBack(mMap);
-
- mTextBoxNorth = getChild<LLTextBox> ("floater_map_north");
- mTextBoxEast = getChild<LLTextBox> ("floater_map_east");
- mTextBoxWest = getChild<LLTextBox> ("floater_map_west");
- mTextBoxSouth = getChild<LLTextBox> ("floater_map_south");
- mTextBoxSouthEast = getChild<LLTextBox> ("floater_map_southeast");
- mTextBoxNorthEast = getChild<LLTextBox> ("floater_map_northeast");
- mTextBoxSouthWest = getChild<LLTextBox> ("floater_map_southwest");
- mTextBoxNorthWest = getChild<LLTextBox> ("floater_map_northwest");
-
- updateMinorDirections();
-
- // Get the drag handle all the way in back
- sendChildToBack(getDragHandle());
-
- // keep onscreen
- gFloaterView->adjustToFitScreen(this, FALSE);
-
- return TRUE;
+ mMap = getChild<LLNetMap>("Net Map");
+ mMap->setToolTipMsg(getString("ToolTipMsg"));
+ mMap->setParcelNameMsg(getString("ParcelNameMsg"));
+ mMap->setParcelSalePriceMsg(getString("ParcelSalePriceMsg"));
+ mMap->setParcelSaleAreaMsg(getString("ParcelSaleAreaMsg"));
+ mMap->setParcelOwnerMsg(getString("ParcelOwnerMsg"));
+ mMap->setRegionNameMsg(getString("RegionNameMsg"));
+ mMap->setToolTipHintMsg(getString("ToolTipHintMsg"));
+ mMap->setAltToolTipHintMsg(getString("AltToolTipHintMsg"));
+ sendChildToBack(mMap);
+
+ mTextBoxNorth = getChild<LLTextBox>("floater_map_north");
+ mTextBoxEast = getChild<LLTextBox>("floater_map_east");
+ mTextBoxWest = getChild<LLTextBox>("floater_map_west");
+ mTextBoxSouth = getChild<LLTextBox>("floater_map_south");
+ mTextBoxSouthEast = getChild<LLTextBox>("floater_map_southeast");
+ mTextBoxNorthEast = getChild<LLTextBox>("floater_map_northeast");
+ mTextBoxSouthWest = getChild<LLTextBox>("floater_map_southwest");
+ mTextBoxNorthWest = getChild<LLTextBox>("floater_map_northwest");
+
+ mTextBoxNorth->reshapeToFitText();
+ mTextBoxEast->reshapeToFitText();
+ mTextBoxWest->reshapeToFitText();
+ mTextBoxSouth->reshapeToFitText();
+ mTextBoxSouthEast->reshapeToFitText();
+ mTextBoxNorthEast->reshapeToFitText();
+ mTextBoxSouthWest->reshapeToFitText();
+ mTextBoxNorthWest->reshapeToFitText();
+
+ updateMinorDirections();
+
+ // Get the drag handle all the way in back
+ sendChildToBack(getDragHandle());
+
+ // keep onscreen
+ gFloaterView->adjustToFitScreen(this, false);
+
+ return true;
}
BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask)
@@ -138,23 +147,44 @@ BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask)
return TRUE;
}
-void LLFloaterMap::setDirectionPos( LLTextBox* text_box, F32 rotation )
+void LLFloaterMap::setDirectionPos(LLTextBox *text_box, F32 rotation)
{
- // Rotation is in radians.
- // Rotation of 0 means x = 1, y = 0 on the unit circle.
-
- F32 map_half_height = (F32)(getRect().getHeight() / 2) - getHeaderHeight()/2;
- F32 map_half_width = (F32)(getRect().getWidth() / 2) ;
- F32 text_half_height = (F32)(text_box->getRect().getHeight() / 2);
- F32 text_half_width = (F32)(text_box->getRect().getWidth() / 2);
- F32 radius = llmin( map_half_height - text_half_height, map_half_width - text_half_width );
-
- // Inset by a little to account for position display.
- radius -= 8.f;
-
- text_box->setOrigin(
- ll_round(map_half_width - text_half_width + radius * cos( rotation )),
- ll_round(map_half_height - text_half_height + radius * sin( rotation )) );
+ // Rotation is in radians.
+ // Rotation of 0 means x = 1, y = 0 on the unit circle.
+
+ F32 map_half_height = (F32) (getRect().getHeight() / 2) - (getHeaderHeight() / 2);
+ F32 map_half_width = (F32) (getRect().getWidth() / 2);
+ F32 text_half_height = (F32) (text_box->getRect().getHeight() / 2);
+ F32 text_half_width = (F32) (text_box->getRect().getWidth() / 2);
+ F32 extra_padding = (F32) (mTextBoxNorth->getRect().getWidth() / 2);
+ F32 pos_half_height = map_half_height - text_half_height - extra_padding;
+ F32 pos_half_width = map_half_width - text_half_width - extra_padding;
+
+ F32 corner_angle = atan2(pos_half_height, pos_half_width);
+ F32 rotation_mirrored_into_top = abs(fmodf(rotation, F_PI));
+ if (rotation < 0)
+ {
+ rotation_mirrored_into_top = F_PI - rotation_mirrored_into_top;
+ }
+ F32 rotation_mirrored_into_top_right = (F_PI_BY_TWO - abs(rotation_mirrored_into_top - F_PI_BY_TWO));
+ bool at_left_right_edge = rotation_mirrored_into_top_right < corner_angle;
+
+ F32 part_x = cos(rotation);
+ F32 part_y = sin(rotation);
+ F32 y;
+ F32 x;
+ if (at_left_right_edge)
+ {
+ x = std::copysign(pos_half_width, part_x);
+ y = x * part_y / part_x;
+ }
+ else
+ {
+ y = std::copysign(pos_half_height, part_y);
+ x = y * part_x / part_y;
+ }
+
+ text_box->setOrigin(ll_round(map_half_width + x - text_half_width), ll_round(map_half_height + y - text_half_height));
}
void LLFloaterMap::updateMinorDirections()
@@ -218,32 +248,6 @@ void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent)
updateMinorDirections();
}
-void LLFloaterMap::handleZoom(const LLSD& userdata)
-{
- std::string level = userdata.asString();
-
- F32 scale = 0.0f;
- if (level == std::string("default"))
- {
- LLControlVariable *pvar = gSavedSettings.getControl("MiniMapScale");
- if(pvar)
- {
- pvar->resetToDefault();
- scale = gSavedSettings.getF32("MiniMapScale");
- }
- }
- else if (level == std::string("close"))
- scale = LLNetMap::MAP_SCALE_MAX;
- else if (level == std::string("medium"))
- scale = LLNetMap::MAP_SCALE_MID;
- else if (level == std::string("far"))
- scale = LLNetMap::MAP_SCALE_MIN;
- if (scale != 0.0f)
- {
- mMap->setScale(scale);
- }
-}
-
LLFloaterMap* LLFloaterMap::getInstance()
{
return LLFloaterReg::getTypedInstance<LLFloaterMap>("mini_map");
diff --git a/indra/newview/llfloatermap.h b/indra/newview/llfloatermap.h
index ff2fb20535..929b1795aa 100644
--- a/indra/newview/llfloatermap.h
+++ b/indra/newview/llfloatermap.h
@@ -48,7 +48,6 @@ public:
/*virtual*/ void draw();
private:
- void handleZoom(const LLSD& userdata);
void setDirectionPos( LLTextBox* text_box, F32 rotation );
void updateMinorDirections();
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 0fefb0d432..d99d95934c 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -476,22 +476,25 @@ void LLFloaterModelPreview::loadHighLodModel()
loadModel(3);
}
-void LLFloaterModelPreview::loadModel(S32 lod)
+void LLFloaterModelPreview::prepareToLoadModel(S32 lod)
{
mModelPreview->mLoading = true;
if (lod == LLModel::LOD_PHYSICS)
{
// loading physics from file
mModelPreview->mPhysicsSearchLOD = lod;
+ mModelPreview->mWarnOfUnmatchedPhyicsMeshes = false;
}
-
+}
+void LLFloaterModelPreview::loadModel(S32 lod)
+{
+ prepareToLoadModel(lod);
(new LLMeshFilePicker(mModelPreview, lod))->getFile();
}
void LLFloaterModelPreview::loadModel(S32 lod, const std::string& file_name, bool force_disable_slm)
{
- mModelPreview->mLoading = true;
-
+ prepareToLoadModel(lod);
mModelPreview->loadModel(file_name, lod, force_disable_slm);
}
@@ -1060,11 +1063,18 @@ void LLFloaterModelPreview::onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata)
}
S32 file_mode = iface->getItemCount() - 1;
- if (which_mode < file_mode)
+ S32 cube_mode = file_mode - 1;
+ if (which_mode < cube_mode)
{
S32 which_lod = num_lods - which_mode;
sInstance->mModelPreview->setPhysicsFromLOD(which_lod);
}
+ else if (which_mode == cube_mode)
+ {
+ std::string path = gDirUtilp->getAppRODataDir();
+ gDirUtilp->append(path, "cube.dae");
+ sInstance->loadModel(LLModel::LOD_PHYSICS, path);
+ }
LLModelPreview *model_preview = sInstance->mModelPreview;
if (model_preview)
@@ -1659,15 +1669,15 @@ LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LL
void LLFloaterModelPreview::setCtrlLoadFromFile(S32 lod)
{
if (lod == LLModel::LOD_PHYSICS)
- {
+ {
LLComboBox* lod_combo = findChild<LLComboBox>("physics_lod_combo");
if (lod_combo)
{
- lod_combo->setCurrentByIndex(5);
+ lod_combo->setCurrentByIndex(lod_combo->getItemCount() - 1);
}
}
else
-{
+ {
LLComboBox* lod_combo = findChild<LLComboBox>("lod_source_" + lod_name[lod]);
if (lod_combo)
{
diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h
index b5dab262a3..614087e36d 100644
--- a/indra/newview/llfloatermodelpreview.h
+++ b/indra/newview/llfloatermodelpreview.h
@@ -223,6 +223,7 @@ private:
void resetUploadOptions();
void clearLogTab();
+ void prepareToLoadModel(S32 lod);
void createSmoothComboBox(LLComboBox* combo_box, float min, float max);
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 19080f05c0..1390f56ea7 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -47,6 +47,7 @@
#include "llagent.h"
#include "llappviewer.h"
+#include "llavataractions.h"
#include "llavatarname.h"
#include "llfloateravatarpicker.h"
#include "llbutton.h"
@@ -1826,7 +1827,7 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region)
setCtrlsEnabled(god || owner || manager);
getChildView("apply_btn")->setEnabled(FALSE);
-
+ getChildView("estate_owner")->setEnabled(TRUE);
getChildView("message_estate_btn")->setEnabled(god || owner || manager);
getChildView("kick_user_from_estate_btn")->setEnabled(god || owner || manager);
@@ -1888,6 +1889,8 @@ BOOL LLPanelEstateInfo::postBuild()
getChild<LLUICtrl>("externally_visible_radio")->setFocus(TRUE);
+ getChild<LLTextBox>("estate_owner")->setIsFriendCallback(LLAvatarActions::isFriend);
+
return LLPanelRegionInfo::postBuild();
}
@@ -2132,6 +2135,7 @@ BOOL LLPanelEstateCovenant::postBuild()
{
mEstateNameText = getChild<LLTextBox>("estate_name_text");
mEstateOwnerText = getChild<LLTextBox>("estate_owner_text");
+ mEstateOwnerText->setIsFriendCallback(LLAvatarActions::isFriend);
mLastModifiedText = getChild<LLTextBox>("covenant_timestamp_text");
mEditor = getChild<LLViewerTextEditor>("covenant_editor");
LLButton* reset_button = getChild<LLButton>("reset_covenant");
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index 2c84cd1f93..fb44449c55 100644..100755
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -81,7 +81,6 @@
//---------------------------------------------------------------------------
// Constants
//---------------------------------------------------------------------------
-static const F32 MAP_ZOOM_TIME = 0.2f;
// Merov: we switched from using the "world size" (which varies depending where the user went) to a fixed
// width of 512 regions max visible at a time. This makes the zoom slider works in a consistent way across
@@ -284,7 +283,7 @@ void* LLFloaterWorldMap::createWorldMapView(void* data)
BOOL LLFloaterWorldMap::postBuild()
{
- mPanel = getChild<LLPanel>("objects_mapview");
+ mMapView = dynamic_cast<LLWorldMapView*>(getChild<LLPanel>("objects_mapview"));
LLComboBox *avatar_combo = getChild<LLComboBox>("friend combo");
avatar_combo->selectFirstItem();
@@ -305,13 +304,11 @@ BOOL LLFloaterWorldMap::postBuild()
landmark_combo->setTextChangedCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) );
mListLandmarkCombo = dynamic_cast<LLCtrlListInterface *>(landmark_combo);
- mCurZoomVal = log(LLWorldMapView::sMapScale/256.f)/log(2.f);
- getChild<LLUICtrl>("zoom slider")->setValue(mCurZoomVal);
+ F32 slider_zoom = mMapView->getZoom();
+ getChild<LLUICtrl>("zoom slider")->setValue(slider_zoom);
setDefaultBtn(NULL);
- mZoomTimer.stop();
-
onChangeMaturity();
return TRUE;
@@ -321,7 +318,7 @@ BOOL LLFloaterWorldMap::postBuild()
LLFloaterWorldMap::~LLFloaterWorldMap()
{
// All cleaned up by LLView destructor
- mPanel = NULL;
+ mMapView = NULL;
// Inventory deletes all observers on shutdown
mInventory = NULL;
@@ -359,17 +356,15 @@ void LLFloaterWorldMap::onOpen(const LLSD& key)
mIsClosing = FALSE;
- LLWorldMapView* map_panel;
- map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel;
- map_panel->clearLastClick();
+ mMapView->clearLastClick();
{
// reset pan on show, so it centers on you again
if (!center_on_target)
{
- LLWorldMapView::setPan(0, 0, TRUE);
+ mMapView->setPan(0, 0, true);
}
- map_panel->updateVisibleBlocks();
+ mMapView->updateVisibleBlocks();
// Reload items as they may have changed
LLWorldMap::getInstance()->reloadItems();
@@ -417,18 +412,21 @@ BOOL LLFloaterWorldMap::handleHover(S32 x, S32 y, MASK mask)
BOOL LLFloaterWorldMap::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
- if (!isMinimized() && isFrontmost())
- {
- if(mPanel->pointInView(x, y))
- {
- F32 slider_value = (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal();
- slider_value += ((F32)clicks * -0.3333f);
- getChild<LLUICtrl>("zoom slider")->setValue(LLSD(slider_value));
- return TRUE;
- }
- }
-
- return LLFloater::handleScrollWheel(x, y, clicks);
+ if (!isMinimized() && isFrontmost())
+ {
+ S32 map_x = x - mMapView->getRect().mLeft;
+ S32 map_y = y - mMapView->getRect().mBottom;
+ if (mMapView->pointInView(map_x, map_y))
+ {
+ F32 old_slider_zoom = (F32) getChild<LLUICtrl>("zoom slider")->getValue().asReal();
+ F32 slider_zoom = old_slider_zoom + ((F32) clicks * -0.3333f);
+ getChild<LLUICtrl>("zoom slider")->setValue(LLSD(slider_zoom));
+ mMapView->zoomWithPivot(slider_zoom, map_x, map_y);
+ return true;
+ }
+ }
+
+ return LLFloater::handleScrollWheel(x, y, clicks);
}
@@ -507,26 +505,13 @@ void LLFloaterWorldMap::draw()
setMouseOpaque(TRUE);
getDragHandle()->setMouseOpaque(TRUE);
-
- //RN: snaps to zoom value because interpolation caused jitter in the text rendering
- if (!mZoomTimer.getStarted() && mCurZoomVal != (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal())
- {
- mZoomTimer.start();
- }
- F32 interp = mZoomTimer.getElapsedTimeF32() / MAP_ZOOM_TIME;
- if (interp > 1.f)
- {
- interp = 1.f;
- mZoomTimer.stop();
- }
- mCurZoomVal = lerp(mCurZoomVal, (F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal(), interp);
- F32 map_scale = 256.f*pow(2.f, mCurZoomVal);
- LLWorldMapView::setScale( map_scale );
+
+ mMapView->zoom((F32)getChild<LLUICtrl>("zoom slider")->getValue().asReal());
// Enable/disable checkboxes depending on the zoom level
// If above threshold level (i.e. low res) -> Disable all checkboxes
// If under threshold level (i.e. high res) -> Enable all checkboxes
- bool enable = LLWorldMapView::showRegionInfo();
+ bool enable = mMapView->showRegionInfo();
getChildView("people_chk")->setEnabled(enable);
getChildView("infohub_chk")->setEnabled(enable);
getChildView("telehub_chk")->setEnabled(enable);
@@ -1025,9 +1010,7 @@ void LLFloaterWorldMap::adjustZoomSliderBounds()
S32 world_height_regions = MAX_VISIBLE_REGIONS;
// Find how much space we have to display the world
- LLWorldMapView* map_panel;
- map_panel = (LLWorldMapView*)mPanel;
- LLRect view_rect = map_panel->getRect();
+ LLRect view_rect = mMapView->getRect();
// View size in pixels
S32 view_width = view_rect.getWidth();
@@ -1295,9 +1278,9 @@ void LLFloaterWorldMap::onShowTargetBtn()
void LLFloaterWorldMap::onShowAgentBtn()
{
- LLWorldMapView::setPan( 0, 0, FALSE); // FALSE == animate
- // Set flag so user's location will be displayed if not tracking anything else
- mSetToUserPosition = TRUE;
+ mMapView->setPan(0, 0, false); // false == animate
+ // Set flag so user's location will be displayed if not tracking anything else
+ mSetToUserPosition = true;
}
void LLFloaterWorldMap::onClickTeleportBtn()
@@ -1349,9 +1332,10 @@ void LLFloaterWorldMap::centerOnTarget(BOOL animate)
pos_global.clearVec();
}
- LLWorldMapView::setPan( -llfloor((F32)(pos_global.mdV[VX] * (F64)LLWorldMapView::sMapScale / REGION_WIDTH_METERS)),
- -llfloor((F32)(pos_global.mdV[VY] * (F64)LLWorldMapView::sMapScale / REGION_WIDTH_METERS)),
- !animate);
+ F64 map_scale = (F64)mMapView->getScale();
+ mMapView->setPan(-llfloor((F32)(pos_global.mdV[VX] * map_scale / REGION_WIDTH_METERS)),
+ -llfloor((F32)(pos_global.mdV[VY] * map_scale / REGION_WIDTH_METERS)),
+ !animate);
mWaitingForTracker = FALSE;
}
@@ -1656,9 +1640,8 @@ void LLFloaterWorldMap::onChangeMaturity()
void LLFloaterWorldMap::onFocusLost()
{
- gViewerWindow->showCursor();
- LLWorldMapView* map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel;
- map_panel->mPanning = FALSE;
+ gViewerWindow->showCursor();
+ mMapView->mPanning = false;
}
LLPanelHideBeacon::LLPanelHideBeacon() :
diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h
index 14a9c26fb9..378339d0ad 100644
--- a/indra/newview/llfloaterworldmap.h
+++ b/indra/newview/llfloaterworldmap.h
@@ -44,6 +44,7 @@ class LLInventoryObserver;
class LLItemInfo;
class LLLineEditor;
class LLTabContainer;
+class LLWorldMapView;
class LLFloaterWorldMap : public LLFloater
{
@@ -154,11 +155,7 @@ protected:
void onTeleportFinished();
private:
- LLPanel* mPanel; // Panel displaying the map
-
- // Ties to LLWorldMapView::sMapScale, in pixels per region
- F32 mCurZoomVal;
- LLFrameTimer mZoomTimer;
+ LLWorldMapView* mMapView; // Panel displaying the map
// update display of teleport destination coordinates - pos is in global coordinates
void updateTeleportCoordsDisplay( const LLVector3d& pos );
diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
index fef169cbbc..50f84266f4 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -86,6 +86,7 @@ static const LLColor4 PREVIEW_DEG_FILL_COL(1.f, 0.f, 0.f, 0.5f);
static const F32 PREVIEW_DEG_EDGE_WIDTH(3.f);
static const F32 PREVIEW_DEG_POINT_SIZE(8.f);
static const F32 PREVIEW_ZOOM_LIMIT(10.f);
+static const std::string DEFAULT_PHYSICS_MESH_NAME = "default_physics_shape";
const F32 SKIN_WEIGHT_CAMERA_DISTANCE = 16.f;
@@ -465,6 +466,20 @@ void LLModelPreview::rebuildUploadData()
LLFloaterModelPreview::addStringToLog(out, false);
}
}
+ if (mWarnOfUnmatchedPhyicsMeshes && !lod_model && (i == LLModel::LOD_PHYSICS))
+ {
+ // Despite the various strategies above, if we don't now have a physics model, we're going to end up with decomposition.
+ // That's ok, but might not what they wanted. Use default_physics_shape if found.
+ std::ostringstream out;
+ out << "No physics model specified for " << instance.mLabel;
+ if (mDefaultPhysicsShapeP)
+ {
+ out << " - using: " << DEFAULT_PHYSICS_MESH_NAME;
+ lod_model = mDefaultPhysicsShapeP;
+ }
+ LL_WARNS() << out.str() << LL_ENDL;
+ LLFloaterModelPreview::addStringToLog(out, !mDefaultPhysicsShapeP); // Flash log tab if no default.
+ }
if (lod_model)
{
@@ -1051,6 +1066,13 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
}
else
{
+ if (loaded_lod == LLModel::LOD_PHYSICS)
+ { // Explicitly loading physics. See if there is a default mesh.
+ LLMatrix4 ignored_transform; // Each mesh that uses this will supply their own.
+ mDefaultPhysicsShapeP = nullptr;
+ FindModel(mScene[loaded_lod], DEFAULT_PHYSICS_MESH_NAME + getLodSuffix(loaded_lod), mDefaultPhysicsShapeP, ignored_transform);
+ mWarnOfUnmatchedPhyicsMeshes = true;
+ }
BOOL legacyMatching = gSavedSettings.getBOOL("ImporterLegacyMatching");
if (!legacyMatching)
{
@@ -1121,7 +1143,6 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod)
LL_WARNS() << out.str() << LL_ENDL;
LLFloaterModelPreview::addStringToLog(out, false);
}
-
mModel[loaded_lod][idx]->mLabel = name;
}
}
diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h
index 8e59c71a55..f5f4227049 100644
--- a/indra/newview/llmodelpreview.h
+++ b/indra/newview/llmodelpreview.h
@@ -217,6 +217,21 @@ private:
LLVOAvatar* getPreviewAvatar(void) { return mPreviewAvatar; }
// Count amount of original models, excluding sub-models
static U32 countRootModels(LLModelLoader::model_list models);
+ /// Indicates whether we should warn of high-lod meshes that do not have a corresponding physics mesh.
+ /// Reset when resetting the modelpreview (i.e., when the uploader dialog is created or reset), and when
+ /// about to process a physics file. Set to true immediately after the file is loaded (before rebuildUploadData()).
+ ///
+ /// (The rules for mapping the correspondence of high-lod meshes to physics meshes are complex. When
+ /// lod rendering meshes are used, there is never an unmatched mesh. Nor is there a mismatch when
+ /// the high-lod file and physics file have ony one mesh each. In these cases, this value is moot.
+ /// When there are multiple meshes in each file, they are matched by name or order, and some meshes
+ /// are broken up by limitations into multiple objects, and thus there can be mismatches.)
+ bool mWarnOfUnmatchedPhyicsMeshes{false};
+ /// A mesh to use as the default physics shape in only those cases where the physics shape is not otherwise specified.
+ /// It is set only when the user chooses a physics shape file that contains a mesh with a name that matches DEFAULT_PHYSICS_MESH_NAME.
+ /// It is reset when such a name is not found, and when resetting the modelpreview.
+ /// Not read unless mWarnOfUnmatchedPhyicsMeshes is true.
+ LLModel* mDefaultPhysicsShapeP{};
protected:
friend class LLModelLoader;
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 112da55682..5cae3ce8d6 100644..100755
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -37,6 +37,7 @@
#include "llfocusmgr.h"
#include "lllocalcliprect.h"
#include "llrender.h"
+#include "llresmgr.h"
#include "llui.h"
#include "lltooltip.h"
@@ -47,11 +48,16 @@
#include "llagentcamera.h"
#include "llappviewer.h" // for gDisconnected
#include "llcallingcard.h" // LLAvatarTracker
+#include "llfloaterland.h"
#include "llfloaterworldmap.h"
+#include "llparcel.h"
#include "lltracker.h"
#include "llsurface.h"
+#include "llurlmatch.h"
+#include "llurlregistry.h"
#include "llviewercamera.h"
#include "llviewercontrol.h"
+#include "llviewerparcelmgr.h"
#include "llviewertexture.h"
#include "llviewertexturelist.h"
#include "llviewermenu.h"
@@ -64,7 +70,10 @@
static LLDefaultChildRegistry::Register<LLNetMap> r1("net_map");
const F32 LLNetMap::MAP_SCALE_MIN = 32;
-const F32 LLNetMap::MAP_SCALE_MID = 1024;
+const F32 LLNetMap::MAP_SCALE_FAR = 32;
+const F32 LLNetMap::MAP_SCALE_MEDIUM = 128;
+const F32 LLNetMap::MAP_SCALE_CLOSE = 256;
+const F32 LLNetMap::MAP_SCALE_VERY_CLOSE = 1024;
const F32 LLNetMap::MAP_SCALE_MAX = 4096;
const F32 MAP_SCALE_ZOOM_FACTOR = 1.04f; // Zoom in factor per click of scroll wheel (4%)
@@ -78,13 +87,13 @@ const F64 COARSEUPDATE_MAX_Z = 1020.0f;
LLNetMap::LLNetMap (const Params & p)
: LLUICtrl (p),
mBackgroundColor (p.bg_color()),
- mScale( MAP_SCALE_MID ),
- mPixelsPerMeter( MAP_SCALE_MID / REGION_WIDTH_METERS ),
+ mScale( MAP_SCALE_MEDIUM ),
+ mPixelsPerMeter( MAP_SCALE_MEDIUM / REGION_WIDTH_METERS ),
mObjectMapTPM(0.f),
mObjectMapPixels(0.f),
- mTargetPan(0.f, 0.f),
mCurPan(0.f, 0.f),
mStartPan(0.f, 0.f),
+ mPopupWorldPos(0.f, 0.f, 0.f),
mMouseDown(0, 0),
mPanning(false),
mUpdateNow(false),
@@ -107,13 +116,22 @@ LLNetMap::~LLNetMap()
BOOL LLNetMap::postBuild()
{
- LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-
- registrar.add("Minimap.Zoom", boost::bind(&LLNetMap::handleZoom, this, _2));
- registrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2));
-
- mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
- return TRUE;
+ LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commitRegistrar;
+ LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enableRegistrar;
+
+ enableRegistrar.add("Minimap.Zoom.Check", boost::bind(&LLNetMap::isZoomChecked, this, _2));
+ commitRegistrar.add("Minimap.Zoom.Set", boost::bind(&LLNetMap::setZoom, this, _2));
+ commitRegistrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2));
+ commitRegistrar.add("Minimap.Center.Activate", boost::bind(&LLNetMap::activateCenterMap, this, _2));
+ enableRegistrar.add("Minimap.MapOrientation.Check", boost::bind(&LLNetMap::isMapOrientationChecked, this, _2));
+ commitRegistrar.add("Minimap.MapOrientation.Set", boost::bind(&LLNetMap::setMapOrientation, this, _2));
+ commitRegistrar.add("Minimap.AboutLand", boost::bind(&LLNetMap::popupShowAboutLand, this, _2));
+
+ mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_mini_map.xml", gMenuHolder,
+ LLViewerMenuHolderGL::child_registry_t::instance());
+ mPopupMenu->setItemEnabled("Re-center map", false);
+
+ return true;
}
void LLNetMap::setScale( F32 scale )
@@ -153,18 +171,32 @@ void LLNetMap::draw()
static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white);
//static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white);
static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white);
- static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white);
+ static LLUIColor map_parcel_outline_color = LLUIColorTable::instance().getColor("MapParcelOutlineColor", LLColor4(LLColor3(LLColor4::yellow), 0.5f));
if (mObjectImagep.isNull())
{
createObjectImage();
}
- static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
- if (auto_center)
+ static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
+ bool auto_centering = auto_center && !mPanning;
+ mCentering = mCentering && !mPanning;
+
+ if (auto_centering || mCentering)
{
- mCurPan = lerp(mCurPan, mTargetPan, LLSmoothInterpolation::getInterpolant(0.1f));
+ mCurPan = lerp(mCurPan, LLVector2(0.0f, 0.0f) , LLSmoothInterpolation::getInterpolant(0.1f));
}
+ bool centered = abs(mCurPan.mV[VX]) < 0.5f && abs(mCurPan.mV[VY]) < 0.5f;
+ if (centered)
+ {
+ mCurPan.mV[0] = 0.0f;
+ mCurPan.mV[1] = 0.0f;
+ mCentering = false;
+ }
+
+ bool can_recenter_map = !(centered || mCentering || auto_centering);
+ mPopupMenu->setItemEnabled("Re-center map", can_recenter_map);
+ updateAboutLandPopupButton();
// Prepare a scissor region
F32 rotation = 0;
@@ -211,7 +243,8 @@ void LLNetMap::draw()
}
// figure out where agent is
- S32 region_width = ll_round(LLWorld::getInstance()->getRegionWidthInMeters());
+ const S32 region_width = ll_round(LLWorld::getInstance()->getRegionWidthInMeters());
+ const F32 scale_pixels_per_meter = mScale / region_width;
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
@@ -220,8 +253,8 @@ void LLNetMap::draw()
// Find x and y position relative to camera's center.
LLVector3 origin_agent = regionp->getOriginAgent();
LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent();
- F32 relative_x = (rel_region_pos.mV[0] / region_width) * mScale;
- F32 relative_y = (rel_region_pos.mV[1] / region_width) * mScale;
+ F32 relative_x = rel_region_pos.mV[0] * scale_pixels_per_meter;
+ F32 relative_y = rel_region_pos.mV[1] * scale_pixels_per_meter;
// background region rectangle
F32 bottom = relative_y;
@@ -244,6 +277,7 @@ void LLNetMap::draw()
}
+
// Draw using texture.
gGL.getTexUnit(0)->bind(regionp->getLand().getSTexture());
gGL.begin(LLRender::QUADS);
@@ -305,8 +339,8 @@ void LLNetMap::draw()
LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal);
LLVector3 camera_position = gAgentCamera.getCameraPositionAgent();
map_center_agent -= camera_position;
- map_center_agent.mV[VX] *= mScale/region_width;
- map_center_agent.mV[VY] *= mScale/region_width;
+ map_center_agent.mV[VX] *= scale_pixels_per_meter;
+ map_center_agent.mV[VY] *= scale_pixels_per_meter;
gGL.getTexUnit(0)->bind(mObjectImagep);
F32 image_half_width = 0.5f*mObjectMapPixels;
@@ -322,6 +356,13 @@ void LLNetMap::draw()
gGL.texCoord2f(1.f, 1.f);
gGL.vertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]);
gGL.end();
+
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* regionp = *iter;
+ regionp->renderPropertyLinesOnMinimap(scale_pixels_per_meter, map_parcel_outline_color.get().mV);
+ }
gGL.popMatrix();
@@ -446,41 +487,34 @@ void LLNetMap::draw()
F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect();
F32 far_clip_meters = LLViewerCamera::getInstance()->getFar();
F32 far_clip_pixels = far_clip_meters * meters_to_pixels;
-
- F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 );
- F32 half_width_pixels = half_width_meters * meters_to_pixels;
- F32 ctr_x = (F32)center_sw_left;
- F32 ctr_y = (F32)center_sw_bottom;
-
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- if( rotate_map )
- {
- gGL.color4fv((map_frustum_color()).mV);
-
- gGL.begin( LLRender::TRIANGLES );
- gGL.vertex2f( ctr_x, ctr_y );
- gGL.vertex2f( ctr_x - half_width_pixels, ctr_y + far_clip_pixels );
- gGL.vertex2f( ctr_x + half_width_pixels, ctr_y + far_clip_pixels );
- gGL.end();
- }
- else
- {
- gGL.color4fv((map_frustum_rotating_color()).mV);
-
- // If we don't rotate the map, we have to rotate the frustum.
- gGL.pushMatrix();
- gGL.translatef( ctr_x, ctr_y, 0 );
- gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f);
- gGL.begin( LLRender::TRIANGLES );
- gGL.vertex2f( 0, 0 );
- gGL.vertex2f( -half_width_pixels, far_clip_pixels );
- gGL.vertex2f( half_width_pixels, far_clip_pixels );
- gGL.end();
- gGL.popMatrix();
- }
+ F32 ctr_x = (F32)center_sw_left;
+ F32 ctr_y = (F32)center_sw_bottom;
+
+ const F32 steps_per_circle = 40.0f;
+ const F32 steps_per_radian = steps_per_circle / F_TWO_PI;
+ const F32 arc_start = -(horiz_fov / 2.0f) + F_PI_BY_TWO;
+ const F32 arc_end = (horiz_fov / 2.0f) + F_PI_BY_TWO;
+ const S32 steps = llmax(1, (S32)((horiz_fov * steps_per_radian) + 0.5f));
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ if( rotate_map )
+ {
+ gGL.pushMatrix();
+ gGL.translatef( ctr_x, ctr_y, 0 );
+ gl_washer_segment_2d(far_clip_pixels, 0, arc_start, arc_end, steps, map_frustum_color(), map_frustum_color());
+ gGL.popMatrix();
+ }
+ else
+ {
+ gGL.pushMatrix();
+ gGL.translatef( ctr_x, ctr_y, 0 );
+ // If we don't rotate the map, we have to rotate the frustum.
+ gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f);
+ gl_washer_segment_2d(far_clip_pixels, 0, arc_start, arc_end, steps, map_frustum_color(), map_frustum_color());
+ gGL.popMatrix();
+ }
}
gGL.popMatrix();
@@ -547,6 +581,65 @@ void LLNetMap::drawTracking(const LLVector3d& pos_global, const LLColor4& color,
}
}
+bool LLNetMap::isMouseOnPopupMenu()
+{
+ if (!mPopupMenu->isOpen())
+ {
+ return false;
+ }
+
+ S32 popup_x;
+ S32 popup_y;
+ LLUI::getInstance()->getMousePositionLocal(mPopupMenu, &popup_x, &popup_y);
+ // *NOTE: Tolerance is larger than it needs to be because the context menu is offset from the mouse when the menu is opened from certain
+ // directions. This may be a quirk of LLMenuGL::showPopup. -Cosmic,2022-03-22
+ constexpr S32 tolerance = 10;
+ // Test tolerance from all four corners, as the popup menu can appear from a different direction if there's not enough space.
+ // Assume the size of the popup menu is much larger than the provided tolerance.
+ // In practice, this is a [tolerance]px margin around the popup menu.
+ for (S32 sign_x = -1; sign_x <= 1; sign_x += 2)
+ {
+ for (S32 sign_y = -1; sign_y <= 1; sign_y += 2)
+ {
+ if (mPopupMenu->pointInView(popup_x + (sign_x * tolerance), popup_y + (sign_y * tolerance)))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void LLNetMap::updateAboutLandPopupButton()
+{
+ if (!mPopupMenu->isOpen())
+ {
+ return;
+ }
+
+ LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(mPopupWorldPos);
+ if (!region)
+ {
+ mPopupMenu->setItemEnabled("About Land", false);
+ }
+ else
+ {
+ // Check if the mouse is in the bounds of the popup. If so, it's safe to assume no other hover function will be called, so the hover
+ // parcel can be used to check if location-sensitive tooltip options are available.
+ if (isMouseOnPopupMenu())
+ {
+ LLViewerParcelMgr::getInstance()->setHoverParcel(mPopupWorldPos);
+ LLParcel *hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel();
+ bool valid_parcel = false;
+ if (hover_parcel)
+ {
+ valid_parcel = hover_parcel->getOwnerID().notNull();
+ }
+ mPopupMenu->setItemEnabled("About Land", valid_parcel);
+ }
+ }
+}
+
LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y )
{
x -= ll_round(getRect().getWidth() / 2 + mCurPan.mV[VX]);
@@ -574,66 +667,152 @@ LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y )
BOOL LLNetMap::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
- // note that clicks are reversed from what you'd think: i.e. > 0 means zoom out, < 0 means zoom in
- F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks);
+ // note that clicks are reversed from what you'd think: i.e. > 0 means zoom out, < 0 means zoom in
+ F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks);
F32 old_scale = mScale;
- setScale(new_scale);
+ setScale(new_scale);
- static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
- if (!auto_center)
- {
- // Adjust pan to center the zoom on the mouse pointer
- LLVector2 zoom_offset;
- zoom_offset.mV[VX] = x - getRect().getWidth() / 2;
- zoom_offset.mV[VY] = y - getRect().getHeight() / 2;
- mCurPan -= zoom_offset * mScale / old_scale - zoom_offset;
- }
+ static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true);
+ if (!auto_center)
+ {
+ // Adjust pan to center the zoom on the mouse pointer
+ LLVector2 zoom_offset;
+ zoom_offset.mV[VX] = x - getRect().getWidth() / 2;
+ zoom_offset.mV[VY] = y - getRect().getHeight() / 2;
+ mCurPan -= zoom_offset * mScale / old_scale - zoom_offset;
+ }
- return TRUE;
+ return true;
}
-BOOL LLNetMap::handleToolTip( S32 x, S32 y, MASK mask )
+BOOL LLNetMap::handleToolTip(S32 x, S32 y, MASK mask)
{
- if (gDisconnected)
- {
- return FALSE;
- }
-
- // If the cursor is near an avatar on the minimap, a mini-inspector will be
- // shown for the avatar, instead of the normal map tooltip.
- if (handleToolTipAgent(mClosestAgentToCursor))
- {
- return TRUE;
- }
-
- LLRect sticky_rect;
- std::string region_name;
- LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( viewPosToGlobal( x, y ) );
- if(region)
- {
- // set sticky_rect
- S32 SLOP = 4;
- localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect.mLeft), &(sticky_rect.mBottom));
- sticky_rect.mRight = sticky_rect.mLeft + 2 * SLOP;
- sticky_rect.mTop = sticky_rect.mBottom + 2 * SLOP;
-
- region_name = region->getName();
- if (!region_name.empty())
- {
- region_name += "\n";
- }
- }
-
- LLStringUtil::format_map_t args;
- args["[REGION]"] = region_name;
- std::string msg = mToolTipMsg;
- LLStringUtil::format(msg, args);
- LLToolTipMgr::instance().show(LLToolTip::Params()
- .message(msg)
- .sticky_rect(sticky_rect));
-
- return TRUE;
+ if (gDisconnected)
+ {
+ return false;
+ }
+
+ // If the cursor is near an avatar on the minimap, a mini-inspector will be
+ // shown for the avatar, instead of the normal map tooltip.
+ if (handleToolTipAgent(mClosestAgentToCursor))
+ {
+ return true;
+ }
+
+ // The popup menu uses the hover parcel when it is open and the mouse is on
+ // top of it, with some additional tolerance. Returning early here prevents
+ // fighting over that hover parcel when getting tooltip info in the
+ // tolerance region.
+ if (isMouseOnPopupMenu())
+ {
+ return false;
+ }
+
+ LLRect sticky_rect;
+ S32 SLOP = 4;
+ localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect.mLeft), &(sticky_rect.mBottom));
+ sticky_rect.mRight = sticky_rect.mLeft + 2 * SLOP;
+ sticky_rect.mTop = sticky_rect.mBottom + 2 * SLOP;
+
+ std::string parcel_name_msg;
+ std::string parcel_sale_price_msg;
+ std::string parcel_sale_area_msg;
+ std::string parcel_owner_msg;
+ std::string region_name_msg;
+
+ LLVector3d posGlobal = viewPosToGlobal(x, y);
+ LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(posGlobal);
+ if (region)
+ {
+ std::string region_name = region->getName();
+ if (!region_name.empty())
+ {
+ region_name_msg = mRegionNameMsg;
+ LLStringUtil::format(region_name_msg, {{"[REGION_NAME]", region_name}});
+ }
+
+ // Only show parcel information in the tooltip if property lines are visible. Otherwise, the parcel the tooltip is referring to is
+ // ambiguous.
+ if (gSavedSettings.getBOOL("MiniMapShowPropertyLines"))
+ {
+ LLViewerParcelMgr::getInstance()->setHoverParcel(posGlobal);
+ LLParcel *hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel();
+ if (hover_parcel)
+ {
+ std::string parcel_name = hover_parcel->getName();
+ if (!parcel_name.empty())
+ {
+ parcel_name_msg = mParcelNameMsg;
+ LLStringUtil::format(parcel_name_msg, {{"[PARCEL_NAME]", parcel_name}});
+ }
+
+ const LLUUID parcel_owner = hover_parcel->getOwnerID();
+ std::string parcel_owner_name_url = LLSLURL("agent", parcel_owner, "inspect").getSLURLString();
+ static LLUrlMatch parcel_owner_name_url_match;
+ LLUrlRegistry::getInstance()->findUrl(parcel_owner_name_url, parcel_owner_name_url_match);
+ if (!parcel_owner_name_url_match.empty())
+ {
+ parcel_owner_msg = mParcelOwnerMsg;
+ std::string parcel_owner_name = parcel_owner_name_url_match.getLabel();
+ LLStringUtil::format(parcel_owner_msg, {{"[PARCEL_OWNER]", parcel_owner_name}});
+ }
+
+ if (hover_parcel->getForSale())
+ {
+ const LLUUID auth_buyer_id = hover_parcel->getAuthorizedBuyerID();
+ const LLUUID agent_id = gAgent.getID();
+ bool show_for_sale = auth_buyer_id.isNull() || auth_buyer_id == agent_id || parcel_owner == agent_id;
+ if (show_for_sale)
+ {
+ S32 price = hover_parcel->getSalePrice();
+ S32 area = hover_parcel->getArea();
+ F32 cost_per_sqm = 0.0f;
+ if (area > 0)
+ {
+ cost_per_sqm = F32(price) / area;
+ }
+ std::string formatted_price = LLResMgr::getInstance()->getMonetaryString(price);
+ std::string formatted_cost_per_meter = llformat("%.1f", cost_per_sqm);
+ parcel_sale_price_msg = mParcelSalePriceMsg;
+ LLStringUtil::format(parcel_sale_price_msg,
+ {{"[PRICE]", formatted_price}, {"[PRICE_PER_SQM]", formatted_cost_per_meter}});
+ std::string formatted_area = llformat("%d", area);
+ parcel_sale_area_msg = mParcelSaleAreaMsg;
+ LLStringUtil::format(parcel_sale_area_msg, {{"[AREA]", formatted_area}});
+ }
+ }
+ }
+ }
+ }
+
+ std::string tool_tip_hint_msg;
+ if (gSavedSettings.getBOOL("DoubleClickTeleport"))
+ {
+ tool_tip_hint_msg = mAltToolTipHintMsg;
+ }
+ else if (gSavedSettings.getBOOL("DoubleClickShowWorldMap"))
+ {
+ tool_tip_hint_msg = mToolTipHintMsg;
+ }
+
+ LLStringUtil::format_map_t args;
+ args["[PARCEL_NAME_MSG]"] = parcel_name_msg.empty() ? "" : parcel_name_msg + '\n';
+ args["[PARCEL_SALE_PRICE_MSG]"] = parcel_sale_price_msg.empty() ? "" : parcel_sale_price_msg + '\n';
+ args["[PARCEL_SALE_AREA_MSG]"] = parcel_sale_area_msg.empty() ? "" : parcel_sale_area_msg + '\n';
+ args["[PARCEL_OWNER_MSG]"] = parcel_owner_msg.empty() ? "" : parcel_owner_msg + '\n';
+ args["[REGION_NAME_MSG]"] = region_name_msg.empty() ? "" : region_name_msg + '\n';
+ args["[TOOL_TIP_HINT_MSG]"] = tool_tip_hint_msg.empty() ? "" : tool_tip_hint_msg + '\n';
+
+ std::string msg = mToolTipMsg;
+ LLStringUtil::format(msg, args);
+ if (msg.back() == '\n')
+ {
+ msg.resize(msg.size() - 1);
+ }
+ LLToolTipMgr::instance().show(LLToolTip::Params().message(msg).sticky_rect(sticky_rect));
+
+ return true;
}
BOOL LLNetMap::handleToolTipAgent(const LLUUID& avatar_id)
@@ -806,59 +985,58 @@ void LLNetMap::createObjectImage()
mUpdateNow = true;
}
-BOOL LLNetMap::handleMouseDown( S32 x, S32 y, MASK mask )
+BOOL LLNetMap::handleMouseDown(S32 x, S32 y, MASK mask)
{
- if (!(mask & MASK_SHIFT)) return FALSE;
-
- // Start panning
- gFocusMgr.setMouseCapture(this);
+ // Start panning
+ gFocusMgr.setMouseCapture(this);
- mStartPan = mCurPan;
- mMouseDown.mX = x;
- mMouseDown.mY = y;
- return TRUE;
+ mStartPan = mCurPan;
+ mMouseDown.mX = x;
+ mMouseDown.mY = y;
+ return true;
}
-BOOL LLNetMap::handleMouseUp( S32 x, S32 y, MASK mask )
+BOOL LLNetMap::handleMouseUp(S32 x, S32 y, MASK mask)
{
- if(abs(mMouseDown.mX-x)<3 && abs(mMouseDown.mY-y)<3)
- handleClick(x,y,mask);
-
- if (hasMouseCapture())
- {
- if (mPanning)
- {
- // restore mouse cursor
- S32 local_x, local_y;
- local_x = mMouseDown.mX + llfloor(mCurPan.mV[VX] - mStartPan.mV[VX]);
- local_y = mMouseDown.mY + llfloor(mCurPan.mV[VY] - mStartPan.mV[VY]);
- LLRect clip_rect = getRect();
- clip_rect.stretch(-8);
- clip_rect.clipPointToRect(mMouseDown.mX, mMouseDown.mY, local_x, local_y);
- LLUI::getInstance()->setMousePositionLocal(this, local_x, local_y);
-
- // finish the pan
- mPanning = false;
-
- mMouseDown.set(0, 0);
-
- // auto centre
- mTargetPan.setZero();
- }
- gViewerWindow->showCursor();
- gFocusMgr.setMouseCapture(NULL);
- return TRUE;
- }
- return FALSE;
+ if (abs(mMouseDown.mX - x) < 3 && abs(mMouseDown.mY - y) < 3)
+ {
+ handleClick(x, y, mask);
+ }
+
+ if (hasMouseCapture())
+ {
+ if (mPanning)
+ {
+ // restore mouse cursor
+ S32 local_x, local_y;
+ local_x = mMouseDown.mX + llfloor(mCurPan.mV[VX] - mStartPan.mV[VX]);
+ local_y = mMouseDown.mY + llfloor(mCurPan.mV[VY] - mStartPan.mV[VY]);
+ LLRect clip_rect = getRect();
+ clip_rect.stretch(-8);
+ clip_rect.clipPointToRect(mMouseDown.mX, mMouseDown.mY, local_x, local_y);
+ LLUI::getInstance()->setMousePositionLocal(this, local_x, local_y);
+
+ // finish the pan
+ mPanning = false;
+
+ mMouseDown.set(0, 0);
+ }
+ gViewerWindow->showCursor();
+ gFocusMgr.setMouseCapture(NULL);
+ return true;
+ }
+
+ return false;
}
BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
if (mPopupMenu)
{
+ mPopupWorldPos = viewPosToGlobal(x, y);
mPopupMenu->buildDrawLabels();
mPopupMenu->updateParent(LLMenuGL::sMenuContainer);
- mPopupMenu->setItemEnabled("Stop Tracking", LLTracker::isTracking(0));
+ mPopupMenu->setItemEnabled("Stop tracking", LLTracker::isTracking(0));
LLMenuGL::showPopup(this, mPopupMenu, x, y);
}
return TRUE;
@@ -906,6 +1084,27 @@ BOOL LLNetMap::handleDoubleClick(S32 x, S32 y, MASK mask)
return TRUE;
}
+F32 LLNetMap::getScaleForName(std::string scale_name)
+{
+ if (scale_name == "very close")
+ {
+ return LLNetMap::MAP_SCALE_VERY_CLOSE;
+ }
+ else if (scale_name == "close")
+ {
+ return LLNetMap::MAP_SCALE_CLOSE;
+ }
+ else if (scale_name == "medium")
+ {
+ return LLNetMap::MAP_SCALE_MEDIUM;
+ }
+ else if (scale_name == "far")
+ {
+ return LLNetMap::MAP_SCALE_FAR;
+ }
+ return 0.0f;
+}
+
// static
bool LLNetMap::outsideSlop( S32 x, S32 y, S32 start_x, S32 start_y, S32 slop )
{
@@ -923,7 +1122,7 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask )
{
if (!mPanning)
{
- // just started panning, so hide cursor
+ // Just started panning. Hide cursor.
mPanning = true;
gViewerWindow->hideCursor();
}
@@ -933,61 +1132,89 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask )
// Set pan to value at start of drag + offset
mCurPan += delta;
- mTargetPan = mCurPan;
gViewerWindow->moveCursorToCenter();
}
-
- // Doesn't really matter, cursor should be hidden
- gViewerWindow->setCursor( UI_CURSOR_TOOLPAN );
- }
- else
- {
- if (mask & MASK_SHIFT)
- {
- // If shift is held, change the cursor to hint that the map can be dragged
- gViewerWindow->setCursor( UI_CURSOR_TOOLPAN );
- }
- else
- {
- gViewerWindow->setCursor( UI_CURSOR_CROSS );
- }
}
+ if (mask & MASK_SHIFT)
+ {
+ // If shift is held, change the cursor to hint that the map can be
+ // dragged. However, holding shift is not required to drag the map.
+ gViewerWindow->setCursor( UI_CURSOR_TOOLPAN );
+ }
+ else
+ {
+ gViewerWindow->setCursor( UI_CURSOR_CROSS );
+ }
+
return TRUE;
}
-void LLNetMap::handleZoom(const LLSD& userdata)
+bool LLNetMap::isZoomChecked(const LLSD &userdata)
{
- std::string level = userdata.asString();
-
- F32 scale = 0.0f;
- if (level == std::string("default"))
- {
- LLControlVariable *pvar = gSavedSettings.getControl("MiniMapScale");
- if(pvar)
- {
- pvar->resetToDefault();
- scale = gSavedSettings.getF32("MiniMapScale");
- }
- }
- else if (level == std::string("close"))
- scale = LLNetMap::MAP_SCALE_MAX;
- else if (level == std::string("medium"))
- scale = LLNetMap::MAP_SCALE_MID;
- else if (level == std::string("far"))
- scale = LLNetMap::MAP_SCALE_MIN;
- if (scale != 0.0f)
- {
- setScale(scale);
- }
+ std::string level = userdata.asString();
+ F32 scale = getScaleForName(level);
+ return scale == mScale;
+}
+
+void LLNetMap::setZoom(const LLSD &userdata)
+{
+ std::string level = userdata.asString();
+ F32 scale = getScaleForName(level);
+ if (scale != 0.0f)
+ {
+ setScale(scale);
+ }
}
void LLNetMap::handleStopTracking (const LLSD& userdata)
{
if (mPopupMenu)
{
- mPopupMenu->setItemEnabled ("Stop Tracking", false);
+ mPopupMenu->setItemEnabled ("Stop tracking", false);
LLTracker::stopTracking (LLTracker::isTracking(NULL));
}
}
+
+void LLNetMap::activateCenterMap(const LLSD &userdata) { mCentering = true; }
+
+bool LLNetMap::isMapOrientationChecked(const LLSD &userdata)
+{
+ const std::string command_name = userdata.asString();
+ const bool rotate_map = gSavedSettings.getBOOL("MiniMapRotate");
+ if (command_name == "north_at_top")
+ {
+ return !rotate_map;
+ }
+
+ if (command_name == "camera_at_top")
+ {
+ return rotate_map;
+ }
+
+ return false;
+}
+
+void LLNetMap::setMapOrientation(const LLSD &userdata)
+{
+ const std::string command_name = userdata.asString();
+ if (command_name == "north_at_top")
+ {
+ gSavedSettings.setBOOL("MiniMapRotate", false);
+ }
+ else if (command_name == "camera_at_top")
+ {
+ gSavedSettings.setBOOL("MiniMapRotate", true);
+ }
+}
+
+void LLNetMap::popupShowAboutLand(const LLSD &userdata)
+{
+ // Update parcel selection. It's important to deselect land first so the "About Land" floater doesn't refresh with the old selection.
+ LLViewerParcelMgr::getInstance()->deselectLand();
+ LLParcelSelectionHandle selection = LLViewerParcelMgr::getInstance()->selectParcelAt(mPopupWorldPos);
+ gMenuHolder->setParcelSelection(selection);
+
+ LLFloaterReg::showInstance("about_land", LLSD(), false);
+}
diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h
index 1f7e7d68c6..fe1aca65a9 100644
--- a/indra/newview/llnetmap.h
+++ b/indra/newview/llnetmap.h
@@ -62,9 +62,12 @@ protected:
public:
virtual ~LLNetMap();
- static const F32 MAP_SCALE_MIN;
- static const F32 MAP_SCALE_MID;
- static const F32 MAP_SCALE_MAX;
+ static const F32 MAP_SCALE_MIN;
+ static const F32 MAP_SCALE_FAR;
+ static const F32 MAP_SCALE_MEDIUM;
+ static const F32 MAP_SCALE_CLOSE;
+ static const F32 MAP_SCALE_VERY_CLOSE;
+ static const F32 MAP_SCALE_MAX;
/*virtual*/ void draw();
/*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
@@ -79,8 +82,17 @@ public:
/*virtual*/ BOOL handleClick(S32 x, S32 y, MASK mask);
/*virtual*/ BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
- void setScale( F32 scale );
- void setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; }
+ void setScale(F32 scale);
+
+ void setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; }
+ void setParcelNameMsg(const std::string& msg) { mParcelNameMsg = msg; }
+ void setParcelSalePriceMsg(const std::string& msg) { mParcelSalePriceMsg = msg; }
+ void setParcelSaleAreaMsg(const std::string& msg) { mParcelSaleAreaMsg = msg; }
+ void setParcelOwnerMsg(const std::string& msg) { mParcelOwnerMsg = msg; }
+ void setRegionNameMsg(const std::string& msg) { mRegionNameMsg = msg; }
+ void setToolTipHintMsg(const std::string& msg) { mToolTipHintMsg = msg; }
+ void setAltToolTipHintMsg(const std::string& msg) { mAltToolTipHintMsg = msg; }
+
void renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U &color, F32 radius );
private:
@@ -94,11 +106,14 @@ private:
void drawTracking( const LLVector3d& pos_global,
const LLColor4& color,
BOOL draw_arrow = TRUE);
+ bool isMouseOnPopupMenu();
+ void updateAboutLandPopupButton();
BOOL handleToolTipAgent(const LLUUID& avatar_id);
static void showAvatarInspector(const LLUUID& avatar_id);
void createObjectImage();
+ F32 getScaleForName(std::string scale_name);
static bool outsideSlop(S32 x, S32 y, S32 start_x, S32 start_y, S32 slop);
private:
@@ -112,11 +127,12 @@ private:
F32 mObjectMapPixels; // Width of object map in pixels
F32 mDotRadius; // Size of avatar markers
- bool mPanning; // map is being dragged
- LLVector2 mTargetPan;
- LLVector2 mCurPan;
- LLVector2 mStartPan; // pan offset at start of drag
- LLCoordGL mMouseDown; // pointer position at start of drag
+ bool mPanning; // map is being dragged
+ bool mCentering; // map is being re-centered around the agent
+ LLVector2 mCurPan;
+ LLVector2 mStartPan; // pan offset at start of drag
+ LLVector3d mPopupWorldPos; // world position picked under mouse when context menu is opened
+ LLCoordGL mMouseDown; // pointer position at start of drag
LLVector3d mObjectImageCenterGlobal;
LLPointer<LLImageRaw> mObjectRawImagep;
@@ -125,14 +141,26 @@ private:
LLUUID mClosestAgentToCursor;
LLUUID mClosestAgentAtLastRightClick;
- std::string mToolTipMsg;
+ std::string mToolTipMsg;
+ std::string mParcelNameMsg;
+ std::string mParcelSalePriceMsg;
+ std::string mParcelSaleAreaMsg;
+ std::string mParcelOwnerMsg;
+ std::string mRegionNameMsg;
+ std::string mToolTipHintMsg;
+ std::string mAltToolTipHintMsg;
public:
void setSelected(uuid_vec_t uuids) { gmSelected=uuids; };
private:
- void handleZoom(const LLSD& userdata);
- void handleStopTracking (const LLSD& userdata);
+ bool isZoomChecked(const LLSD& userdata);
+ void setZoom(const LLSD& userdata);
+ void handleStopTracking(const LLSD& userdata);
+ void activateCenterMap(const LLSD& userdata);
+ bool isMapOrientationChecked(const LLSD& userdata);
+ void setMapOrientation(const LLSD& userdata);
+ void popupShowAboutLand(const LLSD& userdata);
LLMenuGL* mPopupMenu;
uuid_vec_t gmSelected;
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 56370df751..a6f15489f4 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -1591,6 +1591,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
else if (sequence_id == 0 || sequence_id > parcel_mgr.mAgentParcelSequenceID)
{
// new agent parcel
+ // *TODO: Does it really make sense to set the agent parcel to this
+ // parcel if the client doesn't know what kind of parcel data this is?
parcel_mgr.mAgentParcelSequenceID = sequence_id;
parcel = parcel_mgr.mAgentParcel;
}
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp
index 7c3dd00e1a..c170a240a8 100644..100755
--- a/indra/newview/llviewerparceloverlay.cpp
+++ b/indra/newview/llviewerparceloverlay.cpp
@@ -907,8 +907,8 @@ S32 LLViewerParcelOverlay::renderPropertyLines ()
// Always fudge a little vertically.
pull_toward_camera.mV[VZ] += 0.01f;
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
// Move to appropriate region coords
LLVector3 origin = mRegion->getOriginAgent();
@@ -1013,7 +1013,65 @@ S32 LLViewerParcelOverlay::renderPropertyLines ()
}
- gGL.popMatrix();
+ gGL.popMatrix();
return drawn;
}
+
+// Draw half of a single cell (no fill) in a grid drawn from left to right and from bottom to top
+void grid_2d_part_lines(const F32 left, const F32 top, const F32 right, const F32 bottom, bool has_left, bool has_bottom)
+{
+ gGL.begin(LLRender::LINES);
+
+ if (has_left)
+ {
+ gGL.vertex2f(left, bottom);
+ gGL.vertex2f(left, top);
+ }
+ if (has_bottom)
+ {
+ gGL.vertex2f(left, bottom);
+ gGL.vertex2f(right, bottom);
+ }
+
+ gGL.end();
+}
+
+void LLViewerParcelOverlay::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color)
+{
+ if (!mOwnership)
+ {
+ return;
+ }
+ if (!gSavedSettings.getBOOL("MiniMapShowPropertyLines"))
+ {
+ return;
+ }
+
+ LLVector3 origin_agent = mRegion->getOriginAgent();
+ LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent();
+ F32 region_left = rel_region_pos.mV[0] * scale_pixels_per_meter;
+ F32 region_bottom = rel_region_pos.mV[1] * scale_pixels_per_meter;
+ F32 map_parcel_width = PARCEL_GRID_STEP_METERS * scale_pixels_per_meter;
+ const S32 GRIDS_PER_EDGE = mParcelGridsPerEdge;
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ glLineWidth(1.0f);
+ gGL.color4fv(parcel_outline_color);
+ for (S32 i = 0; i < GRIDS_PER_EDGE + 1; i++)
+ {
+ F32 bottom = region_bottom + (i * map_parcel_width);
+ F32 top = bottom + map_parcel_width;
+ for (S32 j = 0; j < GRIDS_PER_EDGE + 1; j++)
+ {
+ F32 left = region_left + (j * map_parcel_width);
+ F32 right = left + map_parcel_width;
+ U8 overlay = mOwnership[(i * GRIDS_PER_EDGE) + j];
+ // The property line vertices are three-dimensional, but here we only care about the x and y coordinates, as we are drawing on a
+ // 2D map
+ const bool has_left = i != GRIDS_PER_EDGE && (j == GRIDS_PER_EDGE || (overlay & PARCEL_WEST_LINE));
+ const bool has_bottom = j != GRIDS_PER_EDGE && (i == GRIDS_PER_EDGE || (overlay & PARCEL_SOUTH_LINE));
+ grid_2d_part_lines(left, top, right, bottom, has_left, has_bottom);
+ }
+ }
+}
diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h
index e30dbf17b3..053f69ba4c 100644
--- a/indra/newview/llviewerparceloverlay.h
+++ b/indra/newview/llviewerparceloverlay.h
@@ -69,6 +69,7 @@ public:
// Returns the number of vertices drawn
S32 renderPropertyLines();
+ void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color);
U8 ownership( const LLVector3& pos) const;
U8 parcelLineFlags( const LLVector3& pos) const;
@@ -82,7 +83,7 @@ public:
void idleUpdate(bool update_now = false);
void updateGL();
-
+
private:
// This is in parcel rows and columns, not grid rows and columns
// Stored in bottom three bits.
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 2fb760ed17..2b65b2eea6 100644..100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1035,6 +1035,15 @@ S32 LLViewerRegion::renderPropertyLines()
}
}
+void LLViewerRegion::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color)
+{
+ if (mParcelOverlay)
+ {
+ mParcelOverlay->renderPropertyLinesOnMinimap(scale_pixels_per_meter, parcel_outline_color);
+ }
+}
+
+
// This gets called when the height field changes.
void LLViewerRegion::dirtyHeights()
{
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index fcbf56c81f..b6c8f5c583 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -154,6 +154,8 @@ public:
// Draw lines in the dirt showing ownership. Return number of
// vertices drawn.
S32 renderPropertyLines();
+ void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color);
+
// Call this whenever you change the height data in the region.
// (Automatically called by LLSurfacePatch's update routine)
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index a6df079223..57292f98a0 100644..100755
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -58,9 +58,15 @@
#include "llglheaders.h"
+// # Constants
+static const F32 MAP_DEFAULT_SCALE = 128.f;
+static const F32 MAP_ITERP_TIME_CONSTANT = 0.75f;
+static const F32 MAP_ZOOM_ACCELERATION_TIME = 0.3f;
+static const F32 MAP_ZOOM_MAX_INTERP = 0.5f;
+static const F32 MAP_SCALE_SNAP_THRESHOLD = 0.005f;
+
// Basically a C++ implementation of the OCEAN_COLOR defined in mapstitcher.py
// Please ensure consistency between those 2 files (TODO: would be better to get that color from an asset source...)
-// # Constants
// OCEAN_COLOR = "#1D475F"
const F32 OCEAN_RED = (F32)(0x1D)/255.f;
const F32 OCEAN_GREEN = (F32)(0x47)/255.f;
@@ -92,14 +98,12 @@ LLUIImagePtr LLWorldMapView::sClassifiedsImage = NULL;
LLUIImagePtr LLWorldMapView::sForSaleImage = NULL;
LLUIImagePtr LLWorldMapView::sForSaleAdultImage = NULL;
-F32 LLWorldMapView::sPanX = 0.f;
-F32 LLWorldMapView::sPanY = 0.f;
-F32 LLWorldMapView::sTargetPanX = 0.f;
-F32 LLWorldMapView::sTargetPanY = 0.f;
S32 LLWorldMapView::sTrackingArrowX = 0;
S32 LLWorldMapView::sTrackingArrowY = 0;
bool LLWorldMapView::sVisibleTilesLoaded = false;
-F32 LLWorldMapView::sMapScale = 128.f;
+F32 LLWorldMapView::sMapScaleSetting = MAP_DEFAULT_SCALE;
+LLVector2 LLWorldMapView::sZoomPivot = LLVector2(0.0f, 0.0f);
+LLFrameTimer LLWorldMapView::sZoomTimer = LLFrameTimer();
std::map<std::string,std::string> LLWorldMapView::sStringsMap;
@@ -166,20 +170,26 @@ void LLWorldMapView::cleanupClass()
sForSaleAdultImage = NULL;
}
-LLWorldMapView::LLWorldMapView()
-: LLPanel(),
- mBackgroundColor( LLColor4( OCEAN_RED, OCEAN_GREEN, OCEAN_BLUE, 1.f ) ),
- mItemPicked(FALSE),
- mPanning( FALSE ),
- mMouseDownPanX( 0 ),
- mMouseDownPanY( 0 ),
- mMouseDownX( 0 ),
- mMouseDownY( 0 ),
- mSelectIDStart(0)
+LLWorldMapView::LLWorldMapView() :
+ LLPanel(),
+ mBackgroundColor(LLColor4(OCEAN_RED, OCEAN_GREEN, OCEAN_BLUE, 1.f)),
+ mItemPicked(FALSE),
+ mPanX(0.f),
+ mPanY(0.f),
+ mTargetPanX(0.f),
+ mTargetPanY(0.f),
+ mPanning(FALSE),
+ mMouseDownPanX(0),
+ mMouseDownPanY(0),
+ mMouseDownX(0),
+ mMouseDownY(0),
+ mSelectIDStart(0),
+ mMapScale(0.f),
+ mTargetMapScale(0.f)
{
- //LL_INFOS("WorldMap") << "Creating the Map -> LLWorldMapView::LLWorldMapView()" << LL_ENDL;
+ // LL_INFOS("WorldMap") << "Creating the Map -> LLWorldMapView::LLWorldMapView()" << LL_ENDL;
- clearLastClick();
+ clearLastClick();
}
BOOL LLWorldMapView::postBuild()
@@ -210,6 +220,9 @@ BOOL LLWorldMapView::postBuild()
mTextBoxNorthEast ->reshapeToFitText();
mTextBoxSouthWest->reshapeToFitText();
mTextBoxNorthWest ->reshapeToFitText();
+
+ sZoomTimer.stop();
+ setScale(sMapScaleSetting, true);
return true;
}
@@ -227,59 +240,103 @@ void LLWorldMapView::cleanupTextures()
{
}
+void LLWorldMapView::zoom(F32 zoom)
+{
+ mTargetMapScale = scaleFromZoom(zoom);
+ if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale)
+ {
+ sZoomPivot = LLVector2(0, 0);
+ sZoomTimer.start();
+ }
+}
-// static
-void LLWorldMapView::setScale( F32 scale )
+void LLWorldMapView::zoomWithPivot(F32 zoom, S32 x, S32 y)
{
- if (scale != sMapScale)
- {
- F32 old_scale = sMapScale;
+ mTargetMapScale = scaleFromZoom(zoom);
+ sZoomPivot = LLVector2(x, y);
+ if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale)
+ {
+ sZoomTimer.start();
+ }
+}
- sMapScale = scale;
- if (sMapScale <= 0.f)
- {
- sMapScale = 0.1f;
- }
+F32 LLWorldMapView::getZoom() { return LLWorldMapView::zoomFromScale(mMapScale); }
- F32 ratio = (scale / old_scale);
- sPanX *= ratio;
- sPanY *= ratio;
- sTargetPanX = sPanX;
- sTargetPanY = sPanY;
- sVisibleTilesLoaded = false;
- }
-}
+F32 LLWorldMapView::getScale() { return mMapScale; }
+// static
+void LLWorldMapView::setScaleSetting(F32 scaleSetting) { sMapScaleSetting = scaleSetting; }
// static
-void LLWorldMapView::translatePan( S32 delta_x, S32 delta_y )
+F32 LLWorldMapView::getScaleSetting() { return sMapScaleSetting; }
+
+void LLWorldMapView::setScale(F32 scale, bool snap)
{
- sPanX += delta_x;
- sPanY += delta_y;
- sTargetPanX = sPanX;
- sTargetPanY = sPanY;
- sVisibleTilesLoaded = false;
+ if (scale != mMapScale)
+ {
+ F32 old_scale = mMapScale;
+
+ mMapScale = scale;
+ // Set the scale used when saving the setting
+ sMapScaleSetting = scale;
+ if (mMapScale <= 0.f)
+ {
+ mMapScale = 0.1f;
+ }
+
+ F32 ratio = (scale / old_scale);
+ mPanX *= ratio;
+ mPanY *= ratio;
+ mTargetPanX = mPanX;
+ mTargetPanY = mPanY;
+ sVisibleTilesLoaded = false;
+
+ // If we are zooming relative to somewhere else rather than the center of the map, compensate for the difference in panning here
+ if (!sZoomPivot.isExactlyZero())
+ {
+ LLVector2 relative_pivot;
+ relative_pivot.mV[VX] = sZoomPivot.mV[VX] - (getRect().getWidth() / 2.0);
+ relative_pivot.mV[VY] = sZoomPivot.mV[VY] - (getRect().getHeight() / 2.0);
+ LLVector2 zoom_pan_offset = relative_pivot - (relative_pivot * scale / old_scale);
+ mPanX += zoom_pan_offset.mV[VX];
+ mPanY += zoom_pan_offset.mV[VY];
+ mTargetPanX += zoom_pan_offset.mV[VX];
+ mTargetPanY += zoom_pan_offset.mV[VY];
+ }
+ }
+
+ if (snap)
+ {
+ mTargetMapScale = scale;
+ }
}
-
// static
-void LLWorldMapView::setPan( S32 x, S32 y, BOOL snap )
+void LLWorldMapView::translatePan(S32 delta_x, S32 delta_y)
{
- sTargetPanX = (F32)x;
- sTargetPanY = (F32)y;
- if (snap)
- {
- sPanX = sTargetPanX;
- sPanY = sTargetPanY;
- }
- sVisibleTilesLoaded = false;
+ mPanX += delta_x;
+ mPanY += delta_y;
+ mTargetPanX = mPanX;
+ mTargetPanY = mPanY;
+ sVisibleTilesLoaded = false;
}
-bool LLWorldMapView::showRegionInfo()
+
+// static
+void LLWorldMapView::setPan(S32 x, S32 y, BOOL snap)
{
- return (LLWorldMipmap::scaleToLevel(sMapScale) <= DRAW_SIMINFO_THRESHOLD ? true : false);
+ mTargetPanX = (F32) x;
+ mTargetPanY = (F32) y;
+ if (snap)
+ {
+ mPanX = mTargetPanX;
+ mPanY = mTargetPanY;
+ }
+ sVisibleTilesLoaded = false;
}
+bool LLWorldMapView::showRegionInfo() { return (LLWorldMipmap::scaleToLevel(mMapScale) <= DRAW_SIMINFO_THRESHOLD ? true : false); }
+
///////////////////////////////////////////////////////////////////////////////////
// HELPERS
@@ -301,8 +358,27 @@ void LLWorldMapView::draw()
mVisibleRegions.clear();
// animate pan if necessary
- sPanX = lerp(sPanX, sTargetPanX, LLSmoothInterpolation::getInterpolant(0.1f));
- sPanY = lerp(sPanY, sTargetPanY, LLSmoothInterpolation::getInterpolant(0.1f));
+ mPanX = lerp(mPanX, mTargetPanX, LLSmoothInterpolation::getInterpolant(MAP_ITERP_TIME_CONSTANT));
+ mPanY = lerp(mPanY, mTargetPanY, LLSmoothInterpolation::getInterpolant(MAP_ITERP_TIME_CONSTANT));
+
+ //RN: snaps to zoom value because interpolation caused jitter in the text rendering
+ if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale)
+ {
+ sZoomTimer.start();
+ }
+ bool snap_scale = false;
+ F32 interp = llmin(MAP_ZOOM_MAX_INTERP, sZoomTimer.getElapsedTimeF32() / MAP_ZOOM_ACCELERATION_TIME);
+ F32 current_zoom_val = zoomFromScale(mMapScale);
+ F32 target_zoom_val = zoomFromScale(mTargetMapScale);
+ F32 new_zoom_val = lerp(current_zoom_val, target_zoom_val, interp);
+ if (abs(new_zoom_val - current_zoom_val) < MAP_SCALE_SNAP_THRESHOLD)
+ {
+ sZoomTimer.stop();
+ snap_scale = true;
+ new_zoom_val = target_zoom_val;
+ }
+ F32 map_scale = scaleFromZoom(new_zoom_val);
+ setScale(map_scale, snap_scale);
const S32 width = getRect().getWidth();
const S32 height = getRect().getHeight();
@@ -310,7 +386,7 @@ void LLWorldMapView::draw()
const F32 half_height = F32(height) / 2.0f;
LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal();
- S32 level = LLWorldMipmap::scaleToLevel(sMapScale);
+ S32 level = LLWorldMipmap::scaleToLevel(mMapScale);
LLLocalClipRect clip(getLocalRect());
{
@@ -350,15 +426,15 @@ void LLWorldMapView::draw()
// Find x and y position relative to camera's center.
LLVector3d rel_region_pos = origin_global - camera_global;
- F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * sMapScale;
- F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * sMapScale;
+ F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * mMapScale;
+ F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * mMapScale;
// Coordinates of the sim in pixels in the UI panel
// When the view isn't panned, 0,0 = center of rectangle
- F32 bottom = sPanY + half_height + relative_y;
- F32 left = sPanX + half_width + relative_x;
- F32 top = bottom + sMapScale ;
- F32 right = left + sMapScale ;
+ F32 bottom = mPanY + half_height + relative_y;
+ F32 left = mPanX + half_width + relative_x;
+ F32 top = bottom + mMapScale ;
+ F32 right = left + mMapScale ;
// Discard if region is outside the screen rectangle (not visible on screen)
if ((top < 0.f) || (bottom > height) ||
@@ -419,7 +495,7 @@ void LLWorldMapView::draw()
if (overlayimage)
{
// Inform the fetch mechanism of the size we need
- S32 draw_size = ll_round(sMapScale);
+ S32 draw_size = ll_round(mMapScale);
overlayimage->setKnownDrawSize(ll_round(draw_size * LLUI::getScaleFactor().mV[VX]), ll_round(draw_size * LLUI::getScaleFactor().mV[VY]));
// Draw something whenever we have enough info
if (overlayimage->hasGLTexture())
@@ -447,7 +523,7 @@ void LLWorldMapView::draw()
}
// Draw the region name in the lower left corner
- if (sMapScale >= DRAW_TEXT_THRESHOLD)
+ if (mMapScale >= DRAW_TEXT_THRESHOLD)
{
LLFontGL* font = LLFontGL::getFont(LLFontDescriptor("SansSerif", "Small", LLFontGL::BOLD));
std::string mesg;
@@ -467,7 +543,7 @@ void LLWorldMapView::draw()
LLColor4::white,
LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW,
S32_MAX, //max_chars
- sMapScale, //max_pixels
+ mMapScale, //max_pixels
NULL,
TRUE); //use ellipses
}
@@ -594,7 +670,7 @@ void LLWorldMapView::setVisible(BOOL visible)
void LLWorldMapView::drawMipmap(S32 width, S32 height)
{
// Compute the level of the mipmap to use for the current scale level
- S32 level = LLWorldMipmap::scaleToLevel(sMapScale);
+ S32 level = LLWorldMipmap::scaleToLevel(mMapScale);
// Set the tile boost level so that unused tiles get to 0
LLWorldMap::getInstance()->equalizeBoostLevels();
@@ -877,7 +953,7 @@ void LLWorldMapView::drawAgents()
void LLWorldMapView::drawFrustum()
{
// Draw frustum
- F32 meters_to_pixels = sMapScale/ REGION_WIDTH_METERS;
+ F32 meters_to_pixels = mMapScale/ REGION_WIDTH_METERS;
F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect();
F32 far_clip_meters = LLViewerCamera::getInstance()->getFar();
@@ -887,8 +963,8 @@ void LLWorldMapView::drawFrustum()
F32 half_width_pixels = half_width_meters * meters_to_pixels;
// Compute the frustum coordinates. Take the UI scale into account.
- F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + sPanX) * LLUI::getScaleFactor().mV[VX]);
- F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + sPanY) * LLUI::getScaleFactor().mV[VY]);
+ F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + mPanX) * LLUI::getScaleFactor().mV[VX]);
+ F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + mPanY) * LLUI::getScaleFactor().mV[VY]);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -945,13 +1021,13 @@ LLVector3 LLWorldMapView::globalPosToView( const LLVector3d& global_pos )
LLVector3 pos_local;
pos_local.setVec(relative_pos_global); // convert to floats from doubles
- pos_local.mV[VX] *= sMapScale / REGION_WIDTH_METERS;
- pos_local.mV[VY] *= sMapScale / REGION_WIDTH_METERS;
+ pos_local.mV[VX] *= mMapScale / REGION_WIDTH_METERS;
+ pos_local.mV[VY] *= mMapScale / REGION_WIDTH_METERS;
// leave Z component in meters
- pos_local.mV[VX] += getRect().getWidth() / 2 + sPanX;
- pos_local.mV[VY] += getRect().getHeight() / 2 + sPanY;
+ pos_local.mV[VX] += getRect().getWidth() / 2 + mPanX;
+ pos_local.mV[VY] += getRect().getHeight() / 2 + mPanY;
return pos_local;
}
@@ -1022,12 +1098,12 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4&
// If you change this, then you need to change LLTracker::getTrackedPositionGlobal() as well
LLVector3d LLWorldMapView::viewPosToGlobal( S32 x, S32 y )
{
- x -= llfloor((getRect().getWidth() / 2 + sPanX));
- y -= llfloor((getRect().getHeight() / 2 + sPanY));
+ x -= llfloor((getRect().getWidth() / 2 + mPanX));
+ y -= llfloor((getRect().getHeight() / 2 + mPanY));
LLVector3 pos_local( (F32)x, (F32)y, 0.f );
- pos_local *= ( REGION_WIDTH_METERS / sMapScale );
+ pos_local *= ( REGION_WIDTH_METERS / mMapScale );
LLVector3d pos_global;
pos_global.setVec( pos_local );
@@ -1484,7 +1560,7 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask,
LLWorldMap::getInstance()->cancelTracking();
- S32 level = LLWorldMipmap::scaleToLevel(sMapScale);
+ S32 level = LLWorldMipmap::scaleToLevel(mMapScale);
// If the zoom level is not too far out already, test hits
if (level <= DRAW_SIMINFO_THRESHOLD)
{
@@ -1601,8 +1677,8 @@ BOOL LLWorldMapView::handleMouseDown( S32 x, S32 y, MASK mask )
{
gFocusMgr.setMouseCapture( this );
- mMouseDownPanX = ll_round(sPanX);
- mMouseDownPanY = ll_round(sPanY);
+ mMouseDownPanX = ll_round(mPanX);
+ mMouseDownPanY = ll_round(mPanY);
mMouseDownX = x;
mMouseDownY = y;
sHandledLastClick = TRUE;
@@ -1617,8 +1693,8 @@ BOOL LLWorldMapView::handleMouseUp( S32 x, S32 y, MASK mask )
{
// restore mouse cursor
S32 local_x, local_y;
- local_x = mMouseDownX + llfloor(sPanX - mMouseDownPanX);
- local_y = mMouseDownY + llfloor(sPanY - mMouseDownPanY);
+ local_x = mMouseDownX + llfloor(mPanX - mMouseDownPanX);
+ local_y = mMouseDownY + llfloor(mPanY - mMouseDownPanY);
LLRect clip_rect = getRect();
clip_rect.stretch(-8);
clip_rect.clipPointToRect(mMouseDownX, mMouseDownY, local_x, local_y);
@@ -1646,7 +1722,7 @@ BOOL LLWorldMapView::handleMouseUp( S32 x, S32 y, MASK mask )
void LLWorldMapView::updateVisibleBlocks()
{
- if (LLWorldMipmap::scaleToLevel(sMapScale) > DRAW_SIMINFO_THRESHOLD)
+ if (LLWorldMipmap::scaleToLevel(mMapScale) > DRAW_SIMINFO_THRESHOLD)
{
// If we're zoomed out too much, we just don't load all those sim info: too much!
return;
@@ -1662,16 +1738,16 @@ void LLWorldMapView::updateVisibleBlocks()
const F32 half_height = F32(height) / 2.0f;
// Compute center into sim grid coordinates
- S32 world_center_x = S32((-sPanX / sMapScale) + (camera_global.mdV[0] / REGION_WIDTH_METERS));
- S32 world_center_y = S32((-sPanY / sMapScale) + (camera_global.mdV[1] / REGION_WIDTH_METERS));
+ S32 world_center_x = S32((-mPanX / mMapScale) + (camera_global.mdV[0] / REGION_WIDTH_METERS));
+ S32 world_center_y = S32((-mPanY / mMapScale) + (camera_global.mdV[1] / REGION_WIDTH_METERS));
// Compute the boundaries into sim grid coordinates
- S32 world_left = world_center_x - S32(half_width / sMapScale) - 1;
- S32 world_right = world_center_x + S32(half_width / sMapScale) + 1;
- S32 world_bottom = world_center_y - S32(half_height / sMapScale) - 1;
- S32 world_top = world_center_y + S32(half_height / sMapScale) + 1;
+ S32 world_left = world_center_x - S32(half_width / mMapScale) - 1;
+ S32 world_right = world_center_x + S32(half_width / mMapScale) + 1;
+ S32 world_bottom = world_center_y - S32(half_height / mMapScale) - 1;
+ S32 world_top = world_center_y + S32(half_height / mMapScale) + 1;
- //LL_INFOS("WorldMap") << "LLWorldMapView::updateVisibleBlocks() : sMapScale = " << sMapScale << ", left = " << world_left << ", right = " << world_right << ", bottom = " << world_bottom << ", top = " << world_top << LL_ENDL;
+ //LL_INFOS("WorldMap") << "LLWorldMapView::updateVisibleBlocks() : mMapScale = " << mMapScale << ", left = " << world_left << ", right = " << world_right << ", bottom = " << world_bottom << ", top = " << world_top << LL_ENDL;
LLWorldMap::getInstance()->updateRegions(world_left, world_bottom, world_right, world_top);
}
@@ -1692,10 +1768,10 @@ BOOL LLWorldMapView::handleHover( S32 x, S32 y, MASK mask )
F32 delta_y = (F32)(gViewerWindow->getCurrentMouseDY());
// Set pan to value at start of drag + offset
- sPanX += delta_x;
- sPanY += delta_y;
- sTargetPanX = sPanX;
- sTargetPanY = sPanY;
+ mPanX += delta_x;
+ mPanY += delta_y;
+ mTargetPanX = mPanX;
+ mTargetPanY = mPanY;
gViewerWindow->moveCursorToCenter();
}
@@ -1792,4 +1868,8 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask )
return FALSE;
}
+// static
+F32 LLWorldMapView::scaleFromZoom(F32 zoom) { return exp2(zoom) * 256.0f; }
+// static
+F32 LLWorldMapView::zoomFromScale(F32 scale) { return log2(scale / 256.f); }
diff --git a/indra/newview/llworldmapview.h b/indra/newview/llworldmapview.h
index a2a6dc53fb..edbdded120 100644
--- a/indra/newview/llworldmapview.h
+++ b/indra/newview/llworldmapview.h
@@ -67,12 +67,21 @@ public:
bool checkItemHit(S32 x, S32 y, LLItemInfo& item, LLUUID* id, bool track);
void handleClick(S32 x, S32 y, MASK mask, S32* hit_type, LLUUID* id);
- // Scale and pan are shared across all instances! (i.e. Terrain and Objects maps are always registered)
- static void setScale( F32 scale );
- static void translatePan( S32 delta_x, S32 delta_y );
- static void setPan( S32 x, S32 y, BOOL snap = TRUE );
+ // Scale, aka zoom, is shared across all instances! (i.e. Terrain and Objects maps are always registered)
+ // Zoom is used for UI and will interpolate the map scale over multiple frames.
+ void zoom(F32 zoom);
+ void zoomWithPivot(F32 zoom, S32 x, S32 y);
+ F32 getZoom();
+ // Scale is a linear scaling factor of in-world coordinates
+ F32 getScale();
+ // setScaleSetting/getScaleSetting are for the default map setting on login
+ static void setScaleSetting(F32 scaleSetting);
+ static F32 getScaleSetting();
+ // Pan is in pixels relative to the center of the map.
+ void translatePan( S32 delta_x, S32 delta_y );
+ void setPan( S32 x, S32 y, BOOL snap = TRUE );
// Return true if the current scale level is above the threshold for accessing region info
- static bool showRegionInfo();
+ bool showRegionInfo();
LLVector3 globalPosToView(const LLVector3d& global_pos);
LLVector3d viewPosToGlobal(S32 x,S32 y);
@@ -153,14 +162,12 @@ public:
static LLUIImagePtr sForSaleImage;
static LLUIImagePtr sForSaleAdultImage;
- static F32 sMapScale; // scale = size of a region in pixels
-
BOOL mItemPicked;
- static F32 sPanX; // in pixels
- static F32 sPanY; // in pixels
- static F32 sTargetPanX; // in pixels
- static F32 sTargetPanY; // in pixels
+ F32 mPanX; // in pixels
+ F32 mPanY; // in pixels
+ F32 mTargetPanX; // in pixels
+ F32 mTargetPanY; // in pixels
static S32 sTrackingArrowX;
static S32 sTrackingArrowY;
static bool sVisibleTilesLoaded;
@@ -194,6 +201,17 @@ public:
private:
void drawTileOutline(S32 level, F32 top, F32 left, F32 bottom, F32 right);
+
+ void setScale(F32 scale, bool snap = true);
+
+ static F32 scaleFromZoom(F32 zoom);
+ static F32 zoomFromScale(F32 scale);
+
+ F32 mMapScale;
+ F32 mTargetMapScale;
+ static F32 sMapScaleSetting;
+ static LLVector2 sZoomPivot;
+ static LLFrameTimer sZoomTimer;
};
#endif
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index 7beb013fba..ad2bc075c6 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -514,8 +514,8 @@
name="MapFrustumColor"
reference="White_10" />
<color
- name="MapFrustumRotatingColor"
- value="1 1 1 0.2" />
+ name="MapParcelOutlineColor"
+ value="1 1 0 0.5" />
<color
name="MapTrackColor"
reference="Red" />
diff --git a/indra/newview/skins/default/xui/en/floater_map.xml b/indra/newview/skins/default/xui/en/floater_map.xml
index b8893e11d9..9639e70544 100644
--- a/indra/newview/skins/default/xui/en/floater_map.xml
+++ b/indra/newview/skins/default/xui/en/floater_map.xml
@@ -16,11 +16,35 @@
width="200">
<floater.string
name="ToolTipMsg">
- [REGION](Double-click to open Map, shift-drag to pan)
+ [PARCEL_NAME_MSG][PARCEL_SALE_PRICE_MSG][PARCEL_SALE_AREA_MSG][PARCEL_OWNER_MSG][REGION_NAME_MSG][TOOL_TIP_HINT_MSG]
+ </floater.string>
+ <floater.string
+ name="ParcelNameMsg">
+ [PARCEL_NAME]
+ </floater.string>
+ <floater.string
+ name="ParcelSalePriceMsg">
+ Price: L$[PRICE] (L$[PRICE_PER_SQM]/m²)
+ </floater.string>
+ <floater.string
+ name="ParcelSaleAreaMsg">
+ Area: [AREA]m²
+ </floater.string>
+ <floater.string
+ name="ParcelOwnerMsg">
+ Owner: [PARCEL_OWNER]
+ </floater.string>
+ <floater.string
+ name="RegionNameMsg">
+ Region: [REGION_NAME]
</floater.string>
<floater.string
- name="AltToolTipMsg">
- [REGION](Double-click to teleport, shift-drag to pan)
+ name="ToolTipHintMsg">
+ Double-click to open map
+ </floater.string>
+ <floater.string
+ name="AltToolTipHintMsg">
+ Double-click to teleport
</floater.string>
<floater.string name="mini_map_caption">
Mini-map
@@ -37,105 +61,73 @@
<text
type="string"
length="1"
- bottom="218"
label="N"
layout="topleft"
- left="0"
name="floater_map_north"
- right="10"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
N
</text>
<text
type="string"
length="1"
- bottom="218"
label="E"
layout="topleft"
- left="0"
name="floater_map_east"
- right="10"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
E
</text>
<text
type="string"
length="1"
- bottom="205"
label="W"
layout="topleft"
- left="0"
name="floater_map_west"
- right="11"
- text_color="1 1 1 0.7"
- top="175">
+ text_color="1 1 1 0.7">
W
</text>
<text
type="string"
length="1"
- bottom="218"
label="S"
layout="topleft"
- left="0"
name="floater_map_south"
- right="10"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
S
</text>
<text
type="string"
length="1"
- bottom="218"
label="SE"
layout="topleft"
- left="0"
name="floater_map_southeast"
- right="20"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
SE
</text>
<text
type="string"
length="1"
- bottom="218"
label="NE"
layout="topleft"
- left="0"
name="floater_map_northeast"
- right="20"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
NE
</text>
<text
type="string"
length="1"
- bottom="218"
label="SW"
layout="topleft"
- left="0"
name="floater_map_southwest"
- right="20"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
SW
</text>
<text
type="string"
length="1"
- bottom="218"
label="NW"
layout="topleft"
- left="0"
name="floater_map_northwest"
- right="20"
- text_color="1 1 1 0.7"
- top="189">
+ text_color="1 1 1 0.7">
NW
</text>
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml
index f4cf2cb512..96cb7c8641 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -784,6 +784,7 @@
<combo_item name="physics_medium"> Medium </combo_item>
<combo_item name="physics_low"> Low </combo_item>
<combo_item name="physics_lowest"> Lowest </combo_item>
+ <combo_item name="physics_bounding_box"> Bounding Box </combo_item>
<combo_item name="load_from_file"> From file </combo_item>
</combo_box>
<line_editor
diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml
index 83407069d2..eb633e50e7 100644
--- a/indra/newview/skins/default/xui/en/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/en/floater_world_map.xml
@@ -677,6 +677,7 @@
name="zoom_icon"
top_pad="7"
width="16" ></icon>
+ <!-- NOTE: min_val for zoom slider is hardcoded for performance reasons -->
<slider
follows="left|bottom"
height="16"
@@ -684,7 +685,7 @@
initial_value="-2"
left_pad="0"
layout="topleft"
- max_val="0"
+ max_val="4"
min_val="-8"
name="zoom slider"
show_text="false"
diff --git a/indra/newview/skins/default/xui/en/menu_mini_map.xml b/indra/newview/skins/default/xui/en/menu_mini_map.xml
index ea263d05ce..2715c916d4 100644
--- a/indra/newview/skins/default/xui/en/menu_mini_map.xml
+++ b/indra/newview/skins/default/xui/en/menu_mini_map.xml
@@ -8,63 +8,109 @@
top="724"
visible="false"
width="128">
- <menu_item_call
- label="Zoom Close"
- name="Zoom Close">
- <menu_item_call.on_click
- function="Minimap.Zoom"
+ <menu_item_check
+ label="Zoom very close"
+ name="Zoom very close">
+ <menu_item_check.on_check
+ function="Minimap.Zoom.Check"
+ parameter="very close" />
+ <menu_item_check.on_click
+ function="Minimap.Zoom.Set"
+ parameter="very close" />
+ </menu_item_check>
+ <menu_item_check
+ label="Zoom close"
+ name="Zoom close">
+ <menu_item_check.on_check
+ function="Minimap.Zoom.Check"
parameter="close" />
- </menu_item_call>
- <menu_item_call
- label="Zoom Medium"
- name="Zoom Medium">
- <menu_item_call.on_click
- function="Minimap.Zoom"
+ <menu_item_check.on_click
+ function="Minimap.Zoom.Set"
+ parameter="close" />
+ </menu_item_check>
+ <menu_item_check
+ label="Zoom medium"
+ name="Zoom medium">
+ <menu_item_check.on_check
+ function="Minimap.Zoom.Check"
parameter="medium" />
- </menu_item_call>
- <menu_item_call
- label="Zoom Far"
- name="Zoom Far">
- <menu_item_call.on_click
- function="Minimap.Zoom"
+ <menu_item_check.on_click
+ function="Minimap.Zoom.Set"
+ parameter="medium" />
+ </menu_item_check>
+ <menu_item_check
+ label="Zoom far"
+ name="Zoom far">
+ <menu_item_check.on_check
+ function="Minimap.Zoom.Check"
parameter="far" />
- </menu_item_call>
- <menu_item_call
- label="Zoom Default"
- name="Zoom Default">
- <menu_item_call.on_click
- function="Minimap.Zoom"
- parameter="default" />
- </menu_item_call>
+ <menu_item_check.on_click
+ function="Minimap.Zoom.Set"
+ parameter="far" />
+ </menu_item_check>
<menu_item_separator />
<menu_item_check
- label="Rotate Map"
- name="Rotate Map">
+ label="North at top"
+ name="North at top">
<menu_item_check.on_check
- control="MiniMapRotate" />
+ function="Minimap.MapOrientation.Check"
+ parameter="north_at_top" />
<menu_item_check.on_click
- function="ToggleControl"
- parameter="MiniMapRotate" />
+ function="Minimap.MapOrientation.Set"
+ parameter="north_at_top" />
</menu_item_check>
<menu_item_check
- label="Auto Center"
- name="Auto Center">
+ label="Camera at top"
+ name="Camera at top">
<menu_item_check.on_check
- control="MiniMapAutoCenter" />
+ function="Minimap.MapOrientation.Check"
+ parameter="camera_at_top" />
<menu_item_check.on_click
- function="ToggleControl"
- parameter="MiniMapAutoCenter" />
+ function="Minimap.MapOrientation.Set"
+ parameter="camera_at_top" />
+ </menu_item_check>
+ <menu_item_separator />
+ <menu_item_check
+ label="Show parcel boundaries"
+ name="Show parcel boundaries">
+ <menu_item_check.on_check
+ control="MiniMapShowPropertyLines" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="MiniMapShowPropertyLines" />
</menu_item_check>
<menu_item_separator />
+ <menu_item_check
+ label="Auto-center map"
+ name="Auto-center map">
+ <menu_item_check.on_check
+ control="MiniMapAutoCenter" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="MiniMapAutoCenter" />
+ </menu_item_check>
+ <menu_item_separator />
+ <menu_item_call
+ label="Re-center map"
+ name="Re-center map">
+ <menu_item_call.on_click
+ function="Minimap.Center.Activate" />
+ </menu_item_call>
<menu_item_call
- label="Stop Tracking"
- name="Stop Tracking">
+ label="Stop tracking"
+ name="Stop tracking">
<menu_item_call.on_click
function="Minimap.Tracker"
parameter="task_properties" />
</menu_item_call>
<menu_item_separator />
<menu_item_call
+ label="About Land"
+ name="About Land">
+ <menu_item_call.on_click
+ function="Minimap.AboutLand" />
+ </menu_item_call>
+ <menu_item_call
label="World Map"
name="World Map">
<menu_item_call.on_click
diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
index aa1b929412..54f038c24f 100644
--- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
@@ -155,6 +155,7 @@
right="-3"
mouse_opaque="true"
name="speaking_indicator"
+ tool_tip="Voice volume"
visible="true"
width="20" />
</panel>
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index c9aa82f7d4..73634a52c9 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -575,6 +575,7 @@ class WindowsManifest(ViewerManifest):
self.path(src="licenses-win32.txt", dst="licenses.txt")
self.path("featuretable.txt")
+ self.path("cube.dae")
with self.prefix(src=pkgdir):
self.path("ca-bundle.crt")
@@ -960,6 +961,7 @@ class DarwinManifest(ViewerManifest):
self.path("licenses-mac.txt", dst="licenses.txt")
self.path("featuretable_mac.txt")
+ self.path("cube.dae")
self.path("SecondLife.nib")
with self.prefix(src=pkgdir,dst=""):
@@ -1434,6 +1436,7 @@ class LinuxManifest(ViewerManifest):
print("Skipping llcommon.so (assuming llcommon was linked statically)")
self.path("featuretable_linux.txt")
+ self.path("cube.dae")
with self.prefix(src=pkgdir):
self.path("ca-bundle.crt")